diff --git a/src/README b/src/README new file mode 100644 index 0000000..23929c6 --- /dev/null +++ b/src/README @@ -0,0 +1,18 @@ +-------- +LICENSES +-------- + +Tiramisu is under the terms of the GNU General Public License v3.0 as +published by the Free Software Foundation; either version 3 of the +License, or (at your option) any later version. + +See gpl-3.0.txt for more informations. + +Contributors: + +Gwenaël Rémond lead developer +Emmanuel Garette contributor + + + + diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/autolib.py b/src/autolib.py new file mode 100644 index 0000000..febc172 --- /dev/null +++ b/src/autolib.py @@ -0,0 +1,94 @@ +# Copyright (C) 2012 Team tiramisu (see README for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# The original `Config` design model is unproudly borrowed from +# the rough gus of pypy: pypy: http://codespeak.net/svn/pypy/dist/pypy/config/ +# the whole pypy projet is under MIT licence +# ____________________________________________________________ +"enables us to carry out a calculation and return an option's value" +from tiramisu.error import DisabledOptionError, SpecialOwnersError +# ____________________________________________________________ +# automatic Option object +special_owners = ['auto', 'fill'] + +def special_owner_factory(name, owner, value, + callback, callback_params=None, config=None): + # in case of an 'auto' and a 'fill' without a value, + # we have to carry out a calculation + return calc_factory(name, callback, callback_params, config) + +def calc_factory(name, callback, callback_params, config): + # FIXME we have to know the exact status of the config + # not to disrupt it + # config.freeze() + if callback_params is None: + callback_params = {} + tcparams = {} + one_is_multi = False + len_multi = 0 + for key, value in callback_params.items(): + if type(value) == tuple: + path, check_disabled = value + try: + opt_value = getattr(config, path) + opt = config.unwrap_from_path(path) + except DisabledOptionError, e: + if chek_disabled: + continue + raise DisabledOptionError(e) + is_multi = opt.is_multi() + if is_multi: + if opt_value != None: + len_value = len(opt_value) + if len_multi != 0 and len_multi != len_value: + raise SpecialOwnersError('unable to carry out a calculation, ' + 'option values with multi types must have same length for: ' + + name) + len_multi = len_value + one_is_multi = True + tcparams[key] = (opt_value, is_multi) + else: + tcparams[key] = (value, False) + + if one_is_multi: + ret = [] + for incr in range(len_multi): + tcp = {} + for key, couple in tcparams.items(): + value, ismulti = couple + if ismulti and value != None: + tcp[key] = value[incr] + else: + tcp[key] = value + ret.append(calculate(name, callback, tcp)) + return ret + else: + tcp = {} + for key, couple in tcparams.items(): + tcp[key] = couple[0] + return calculate(name, callback, tcp) + +def calculate(name, callback, tcparams): + try: + # XXX not only creole... + from creole import eosfunc + return getattr(eosfunc, callback)(**tcparams) + except AttributeError, err: + import traceback + traceback.print_exc() + raise SpecialOwnersError("callback: {0} return error {1} for " + "option: {2}".format(callback, str(err), name)) + diff --git a/src/basetype.py b/src/basetype.py new file mode 100644 index 0000000..c501ccb --- /dev/null +++ b/src/basetype.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +"base 'interface' types for option types" +# Copyright (C) 2012 Team tiramisu (see README for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# The original `Config` design model is unproudly borrowed from +# the rough gus of pypy: pypy: http://codespeak.net/svn/pypy/dist/pypy/config/ +# the whole pypy projet is under MIT licence +# ____________________________________________________________ +# Option and OptionDescription modes +modes = ['normal', 'expert'] + +class HiddenBaseType(object): + hidden = False + def hide(self): + self.hidden = True + def show(self): + self.hidden = False + def _is_hidden(self): + # dangerous method: how an Option can determine its status by itself ? + return self.hidden + +class DisabledBaseType(object): + disabled = False + def disable(self): + self.disabled = True + def enable(self): + self.disabled = False + def _is_disabled(self): + return self.disabled + +class ModeBaseType(object): + mode = 'normal' + def get_mode(self): + return self.mode + def set_mode(self, mode): + if mode not in modes: + raise TypeError("Unknown mode: {0}".format(mode)) + self.mode = mode + diff --git a/src/config.py b/src/config.py new file mode 100644 index 0000000..f4fabdd --- /dev/null +++ b/src/config.py @@ -0,0 +1,540 @@ +# -*- coding: utf-8 -*- +"pretty small and local configuration management tool" +# Copyright (C) 2012 Team tiramisu (see README for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# The original `Config` design model is unproudly borrowed from +# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/ +# the whole pypy projet is under MIT licence +# ____________________________________________________________ +from error import (HiddenOptionError, ConfigError, NotFoundError, + AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound, + SpecialOwnersError, MandatoryError, MethodCallError, + DisabledOptionError, ModeOptionError) +from option import (OptionDescription, Option, SymLinkOption, group_types, + Multi, apply_requires, modes) +from autolib import special_owners, special_owner_factory +# ______________________________________________________________________ +# generic owner. 'default' is the general config owner after init time +default_owner = 'user' +# ____________________________________________________________ +class Config(object): + _cfgimpl_hidden = True + _cfgimpl_disabled = True + _cfgimpl_mandatory = True + _cfgimpl_frozen = False + _cfgimpl_owner = default_owner + _cfgimpl_toplevel = None + _cfgimpl_mode = 'normal' + + def __init__(self, descr, parent=None, **overrides): + self._cfgimpl_descr = descr + self._cfgimpl_value_owners = {} + self._cfgimpl_parent = parent + # `Config()` indeed takes care of the `Option()`'s values + self._cfgimpl_values = {} + self._cfgimpl_previous_values = {} + # XXX warnings are a great idea, let's make up a better use of it + self._cfgimpl_warnings = [] + self._cfgimpl_toplevel = self._cfgimpl_get_toplevel() + # `freeze()` allows us to carry out this calculation again if necessary + self._cfgimpl_frozen = self._cfgimpl_toplevel._cfgimpl_frozen + self._cfgimpl_build(overrides) + + def _validate_duplicates(self, children): + duplicates = [] + for dup in children: + if dup._name not in duplicates: + duplicates.append(dup._name) + else: + raise ConflictConfigError('duplicate option name: ' + '{0}'.format(dup._name)) + + def _cfgimpl_build(self, overrides): + self._validate_duplicates(self._cfgimpl_descr._children) + for child in self._cfgimpl_descr._children: + if isinstance(child, Option): + if child.is_multi(): + childdef = Multi(child.getdefault(), config=self, + child=child) + self._cfgimpl_values[child._name] = childdef + self._cfgimpl_previous_values[child._name] = childdef + else: + childdef = child.getdefault() + self._cfgimpl_values[child._name] = childdef + self._cfgimpl_previous_values[child._name] = childdef + if child.getcallback() is not None: + if child._is_hidden(): + self._cfgimpl_value_owners[child._name] = 'auto' + else: + self._cfgimpl_value_owners[child._name] = 'fill' + else: + if child.is_multi(): + self._cfgimpl_value_owners[child._name] = ['default' \ + for i in range(len(child.getdefault() ))] + else: + self._cfgimpl_value_owners[child._name] = 'default' + elif isinstance(child, OptionDescription): + self._validate_duplicates(child._children) + self._cfgimpl_values[child._name] = Config(child, parent=self) + self.override(overrides) + + def cfgimpl_update(self): + "dynamically adds `Option()` or `OptionDescription()`" + # Nothing is static. Everything evolve. + # FIXME this is an update for new options in the schema only + # see the update_child() method of the descr object + for child in self._cfgimpl_descr._children: + if isinstance(child, Option): + if child._name not in self._cfgimpl_values: + self._cfgimpl_values[child._name] = child.getdefault() + # FIXME and ['default', ...] if is_multi() ? + self._cfgimpl_value_owners[child._name] = 'default' + elif isinstance(child, OptionDescription): + if child._name not in self._cfgimpl_values: + self._cfgimpl_values[child._name] = Config(child, parent=self) + + def override(self, overrides): + for name, value in overrides.iteritems(): + homeconfig, name = self._cfgimpl_get_home_by_path(name) + # if there are special_owners, impossible to override + if homeconfig._cfgimpl_value_owners[name] in special_owners: + raise SpecialOwnersError("cannot override option: {0} because " + "of its special owner".format(name)) + homeconfig.setoption(name, value, 'default') + + def cfgimpl_set_owner(self, owner): + self._cfgimpl_owner = owner + for child in self._cfgimpl_descr._children: + if isinstance(child, OptionDescription): + self._cfgimpl_values[child._name].cfgimpl_set_owner(owner) + # ____________________________________________________________ + def cfgimpl_hide(self): + if self._cfgimpl_parent != None: + raise MethodCallError("this method root_hide() shall not be" + "used with non-root Config() object") + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_hidden = True + + def cfgimpl_show(self): + if self._cfgimpl_parent != None: + raise MethodCallError("this method root_hide() shall not be" + "used with non-root Config() object") + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_hidden = False + # ____________________________________________________________ + def cfgimpl_disable(self): + if self._cfgimpl_parent != None: + raise MethodCallError("this method root_hide() shall not be" + "used with non-root Confit() object") + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_disabled = True + + def cfgimpl_enable(self): + if self._cfgimpl_parent != None: + raise MethodCallError("this method root_hide() shall not be" + "used with non-root Confit() object") + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_disabled = False + # ____________________________________________________________ + def __setattr__(self, name, value): + if '.' in name: + homeconfig, name = self._cfgimpl_get_home_by_path(name) + return setattr(homeconfig, name, value) + + if name.startswith('_cfgimpl_'): + self.__dict__[name] = value + return + if self._cfgimpl_frozen and getattr(self, name) != value: + raise TypeError("trying to change a value in a frozen config" + ": {0} {1}".format(name, value)) + if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption: + self._validate(name, getattr(self._cfgimpl_descr, name)) + self.setoption(name, value, self._cfgimpl_owner) + + def _validate(self, name, opt_or_descr): + apply_requires(opt_or_descr, self) + if not type(opt_or_descr) == OptionDescription: + # hidden options + if self._cfgimpl_toplevel._cfgimpl_hidden and \ + (opt_or_descr._is_hidden() or self._cfgimpl_descr._is_hidden()): + raise HiddenOptionError("trying to access to a hidden option:" + " {0}".format(name)) + # disabled options + if self._cfgimpl_toplevel._cfgimpl_disabled and \ + (opt_or_descr._is_disabled() or self._cfgimpl_descr._is_disabled()): + raise DisabledOptionError("this option is disabled:" + " {0}".format(name)) + # expert options + # XXX currently doesn't look at the group, is it really necessary ? + if self._cfgimpl_toplevel._cfgimpl_mode != 'normal': + if opt_or_descr.get_mode() != 'normal': + raise ModeOptionError("this option's mode is not normal:" + " {0}".format(name)) + + def __getattr__(self, name): + # attribute access by passing a path, + # for instance getattr(self, "creole.general.family.adresse_ip_eth0") + if '.' in name: + homeconfig, name = self._cfgimpl_get_home_by_path(name) + return getattr(homeconfig, name) + opt_or_descr = getattr(self._cfgimpl_descr, name) + # symlink options + if type(opt_or_descr) == SymLinkOption: + return getattr(self, opt_or_descr.path) + self._validate(name, opt_or_descr) + # special attributes + if name.startswith('_cfgimpl_'): + # if it were in __dict__ it would have been found already + return self.__dict__[name] + raise AttributeError("%s object has no attribute %s" % + (self.__class__, name)) + if name not in self._cfgimpl_values: + raise AttributeError("%s object has no attribute %s" % + (self.__class__, name)) + if name in self._cfgimpl_value_owners: + owner = self._cfgimpl_value_owners[name] + if owner in special_owners: + value = self._cfgimpl_values[name] + if value != None: + if opt_or_descr.is_multi(): + if owner == 'fill' and None not in value: + return value + else: + if owner == 'fill' and value != None: + return value + result = special_owner_factory(name, owner, + value=value, + callback=opt_or_descr.getcallback(), + callback_params=opt_or_descr.getcallback_params(), + config=self._cfgimpl_get_toplevel()) + # this result **shall not** be a list + # for example, [1, 2, 3, None] -> [1, 2, 3, result] + if type(result) == list: + raise ConfigError('invalid calculated value returned' + ' for option {0} : shall not be a list'.format(name)) + if result != None and not opt_or_descr._validate(result): + raise ConfigError('invalid calculated value returned' + ' for option {0}'.format(name)) + if opt_or_descr.is_multi(): + if value == []: + _result = [result] + else: + _result = [] + for val in value: + if val == None: + val = result + _result.append(val) + else: + _result = result + return _result + # mandatory options + if not isinstance(opt_or_descr, OptionDescription): + homeconfig = self._cfgimpl_get_toplevel() + mandatory = homeconfig._cfgimpl_mandatory + if opt_or_descr.is_mandatory() and mandatory: + if self._cfgimpl_values[name] == None\ + and opt_or_descr.getdefault() == None: + raise MandatoryError("option: {0} is mandatory " + "and shall have a value".format(name)) + # for multi types with None in the value (ex: ["egg", None, "spam"]) + # None is replaced by default_multi + if not isinstance(opt_or_descr, OptionDescription): + if opt_or_descr.is_multi() and None in self._cfgimpl_values[name]: + newvalue = [] + for val in self._cfgimpl_values[name]: + if val is None: + newvalue.append(opt_or_descr.default_multi) + else: + newvalue.append(val) + return newvalue + return self._cfgimpl_values[name] + + def __dir__(self): + #from_type = dir(type(self)) + from_dict = list(self.__dict__) + extras = list(self._cfgimpl_values) + return sorted(set(extras + from_dict)) + + def unwrap_from_name(self, name): + # didn't have to stoop so low: `self.get()` must be the proper method + # **and it is slow**: it recursively searches into the namespaces + paths = self.getpaths(allpaths=True) + opts = dict([(path, self.unwrap_from_path(path)) for path in paths]) + all_paths = [p.split(".") for p in self.getpaths()] + for pth in all_paths: + if name in pth: + return opts[".".join(pth)] + raise NotFoundError("name: {0} not found".format(name)) + + def unwrap_from_path(self, path): + # didn't have to stoop so low, `geattr(self, path)` is much better + # **fast**: finds the option directly in the appropriate namespace + if '.' in path: + homeconfig, path = self._cfgimpl_get_home_by_path(path) + return getattr(homeconfig._cfgimpl_descr, path) + return getattr(self._cfgimpl_descr, path) + + def __delattr__(self, name): + # if you use delattr you are responsible for all bad things happening + if name.startswith('_cfgimpl_'): + del self.__dict__[name] + return + self._cfgimpl_value_owners[name] = 'default' + opt = getattr(self._cfgimpl_descr, name) + if isinstance(opt, OptionDescription): + raise AttributeError("can't option subgroup") + self._cfgimpl_values[name] = getattr(opt, 'default', None) + + def setoption(self, name, value, who=None): + #who is **not necessarily** a owner, because it cannot be a list + child = getattr(self._cfgimpl_descr, name) + if who == None: + if child.is_multi(): + newowner = [self._cfgimpl_owner for i in range(len(value))] + else: + newowner = self._cfgimpl_owner + else: + if type(child) != SymLinkOption: + if child.is_multi(): + if type(value) != list: + raise ConfigError("invalid value for option:" + " {0} that is set to multi".format(name)) + newowner = [who for i in range(len(value))] + else: + newowner = who + if type(child) != SymLinkOption: + if name not in self._cfgimpl_values: + raise AttributeError('unknown option %s' % (name,)) + # special owners, a value with a owner *auto* cannot be changed + oldowner = self._cfgimpl_value_owners[child._name] + if oldowner == 'auto': + if who == 'auto': + raise ConflictConfigError('cannot override value to %s for ' + 'option %s' % (value, name)) + if oldowner == who: + oldvalue = getattr(self, name) + if oldvalue == value: #or who in ("default",): + return + child.setoption(self, value, who) + # if the value owner is 'auto', set the option to hidden + if who == 'auto': + if not child._is_hidden(): + child.hide() + if (value is None and who != 'default' and not child.is_multi()): + child.setowner(self, 'default') + self._cfgimpl_values[name] = child.getdefault() + elif (value == [] and who != 'default' and child.is_multi()): + child.setowner(self, ['default' for i in range(len(child.getdefault()))]) + self._cfgimpl_values[name] = child.getdefault() + else: + child.setowner(self, newowner) + else: + homeconfig = self._cfgimpl_get_toplevel() + child.setoption(homeconfig, value, who) + + def set(self, **kwargs): + all_paths = [p.split(".") for p in self.getpaths(allpaths=True)] + for key, value in kwargs.iteritems(): + key_p = key.split('.') + candidates = [p for p in all_paths if p[-len(key_p):] == key_p] + if len(candidates) == 1: + name = '.'.join(candidates[0]) + homeconfig, name = self._cfgimpl_get_home_by_path(name) + try: + getattr(homeconfig, name) + except MandatoryError: + pass + except Exception, e: + raise e # HiddenOptionError or DisabledOptionError + homeconfig.setoption(name, value, self._cfgimpl_owner) + elif len(candidates) > 1: + raise AmbigousOptionError( + 'more than one option that ends with %s' % (key, )) + else: + raise NoMatchingOptionFound( + 'there is no option that matches %s' + ' or the option is hidden or disabled'% (key, )) + + def get(self, name): + paths = self.getpaths(allpaths=True) + pathsvalues = [] + for path in paths: + pathname = path.split('.')[-1] + if pathname == name: + try: + value = getattr(self, path) + return value + except Exception, e: + raise e + raise NotFoundError("option {0} not found in config".format(name)) + + def _cfgimpl_get_home_by_path(self, path): + """returns tuple (config, name)""" + path = path.split('.') + + for step in path[:-1]: + self = getattr(self, step) + return self, path[-1] + + def _cfgimpl_get_toplevel(self): + while self._cfgimpl_parent is not None: + self = self._cfgimpl_parent + return self + + def cfgimpl_previous_value(self, path): + home, name = self._cfgimpl_get_home_by_path(path) + return home._cfgimpl_previous_values[name] + + def get_previous_value(self, name): + return self._cfgimpl_previous_values[name] + + def add_warning(self, warning): + self._cfgimpl_get_toplevel()._cfgimpl_warnings.append(warning) + + def get_warnings(self): + return self._cfgimpl_get_toplevel()._cfgimpl_warnings + # ____________________________________________________________ + # freeze and read-write statuses + def cfgimpl_freeze(self): + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_frozen = True + self._cfgimpl_frozen = True + + def cfgimpl_unfreeze(self): + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_frozen = False + self._cfgimpl_frozen = False + + def is_frozen(self): + # it should be the same value as self._cfgimpl_frozen... + rootconfig = self._cfgimpl_get_toplevel() + return rootconfig.__dict__['_cfgimpl_frozen'] + + def cfgimpl_read_only(self): + # hung up on freeze, hidden and disabled concepts + self.cfgimpl_freeze() + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_hidden = False + rootconfig._cfgimpl_disabled = True + rootconfig._cfgimpl_mandatory = True + + def cfgimpl_set_mode(self, mode): + # normal or expert mode + rootconfig = self._cfgimpl_get_toplevel() + if mode not in modes: + raise ConfigError("mode {0} not available".format(mode)) + rootconfig._cfgimpl_mode = mode + + def cfgimpl_read_write(self): + # hung up on freeze, hidden and disabled concepts + self.cfgimpl_unfreeze() + rootconfig = self._cfgimpl_get_toplevel() + rootconfig._cfgimpl_hidden = True + rootconfig._cfgimpl_disabled = False + rootconfig._cfgimpl_mandatory = False + # ____________________________________________________________ + def getkey(self): + return self._cfgimpl_descr.getkey(self) + + def __hash__(self): + return hash(self.getkey()) + + def __eq__(self, other): + return self.getkey() == other.getkey() + + def __ne__(self, other): + return not self == other + + def __iter__(self): + # iteration only on Options (not OptionDescriptions) + for child in self._cfgimpl_descr._children: + if isinstance(child, Option): + try: + yield child._name, getattr(self, child._name) + except: + pass # hidden, disabled option group + + def iter_groups(self, group_type=None): + "iteration on OptionDescriptions" + if group_type == None: + groups = group_types + else: + if group_type not in group_types: + raise TypeError("Unknown group_type: {0}".format(group_type)) + groups = [group_type] + for child in self._cfgimpl_descr._children: + if isinstance(child, OptionDescription): + try: + if child.get_group_type() in groups: + yield child._name, getattr(self, child._name) + except: + pass # hidden, disabled option + + def __str__(self, indent=""): + lines = [] + children = [(child._name, child) + for child in self._cfgimpl_descr._children] + children.sort() + for name, child in children: + if self._cfgimpl_value_owners.get(name, None) == 'default': + continue + value = getattr(self, name) + if isinstance(value, Config): + substr = value.__str__(indent + " ") + else: + substr = "%s %s = %s" % (indent, name, value) + if substr: + lines.append(substr) + if indent and not lines: + return '' # hide subgroups with all default values + lines.insert(0, "%s[%s]" % (indent, self._cfgimpl_descr._name,)) + return '\n'.join(lines) + + def getpaths(self, include_groups=False, allpaths=False): + """returns a list of all paths in self, recursively, taking care of + the context (hidden/disabled) + """ + paths = [] + for path in self._cfgimpl_descr.getpaths(include_groups=include_groups): + try: + value = getattr(self, path) + except Exception, e: + if not allpaths: + pass # hidden or disabled option + else: + paths.append(path) # hidden or disabled option added + else: + paths.append(path) + return paths + +def make_dict(config, flatten=False): + paths = config.getpaths() + pathsvalues = [] + for path in paths: + if flatten: + pathname = path.split('.')[-1] + else: + pathname = path + try: + value = getattr(config, path) + pathsvalues.append((pathname, value)) + except: + pass # this just a hidden or disabled option + options = dict(pathsvalues) + return options +# ____________________________________________________________ + diff --git a/src/doc/Makefile b/src/doc/Makefile new file mode 100644 index 0000000..f8c7cfe --- /dev/null +++ b/src/doc/Makefile @@ -0,0 +1,26 @@ +SRC=$(wildcard *.txt) +HTMLFRAGMENT=$(addsuffix .html, $(basename $(SRC))) + +.SUFFIXES: + +.PHONY: all clean + +all: html code epydoc +# make -C ./build/code all +# make -C ./build/test all +# make -C ./build all + +html: $(HTMLFRAGMENT) + +%.html: %.txt + ./rst2html.py --stylesheet ./build/style.css $< > ./build/$@ + +code: + ./code2html + +epydoc: + ./epydoc.sh + +clean: + make -C ./build clean + diff --git a/src/doc/build/Makefile b/src/doc/build/Makefile new file mode 100644 index 0000000..a825b9e --- /dev/null +++ b/src/doc/build/Makefile @@ -0,0 +1,7 @@ +.PHONY: clean +.SUFFIXES: + +clean: + rm -f *.html + rm -f api/*.html + make -C ./pydoc/ clean diff --git a/src/doc/build/api/Readme b/src/doc/build/api/Readme new file mode 100644 index 0000000..8623c0e --- /dev/null +++ b/src/doc/build/api/Readme @@ -0,0 +1 @@ +API's directory diff --git a/src/doc/build/architecture.dia b/src/doc/build/architecture.dia new file mode 100644 index 0000000..35adb7e Binary files /dev/null and b/src/doc/build/architecture.dia differ diff --git a/src/doc/build/architecture.png b/src/doc/build/architecture.png new file mode 100644 index 0000000..fecefa0 Binary files /dev/null and b/src/doc/build/architecture.png differ diff --git a/src/doc/build/default.css b/src/doc/build/default.css new file mode 100644 index 0000000..8625c0e --- /dev/null +++ b/src/doc/build/default.css @@ -0,0 +1,1080 @@ +body,body.editor,body.body { + font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif; + background: White; + color: Black; +} + +a, a.reference { + text-decoration: none; +} +a[href]:hover { text-decoration: underline; } + +img { + border: none; + vertical-align: middle; +} + +p, div.text { + text-align: left; + line-height: 1.5em; + margin: 0.5em 0em 0em 0em; +} + + + +p a:active { + color: Red; + background-color: transparent; +} + +p img { + border: 0; + margin: 0; +} + +img.inlinephoto { + padding: 0; + padding-right: 1em; + padding-top: 0.7em; + float: left; +} + +hr { + clear: both; + height: 1px; + color: #8CACBB; + background-color: transparent; +} + + +ul { + line-height: 1.5em; + /*list-style-image: url("bullet.gif"); */ + margin-left: 1.5em; + padding:0; +} + +ol { + line-height: 1.5em; + margin-left: 1.5em; + padding:0; +} + +ul a, ol a { + text-decoration: underline; +} + +dl { +} + +dt { + font-weight: bold; +} + +dd { + line-height: 1.5em; + margin-bottom: 1em; +} + +blockquote { + font-family: Times, "Times New Roman", serif; + font-style: italic; + font-size: 120%; +} + +code { + color: Black; + /*background-color: #dee7ec;*/ + background-color: #cccccc; +} + +pre { + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; + overflow: auto; +} + + +.netscape4 { + display: none; +} + +/* main page styles */ + +/*a[href]:hover { color: black; text-decoration: underline; } +a[href]:link { color: black; text-decoration: underline; } +a[href] { color: black; text-decoration: underline; } +*/ + +span.menu_selected { + color: black; + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; + background-color: #cccccc; +} + + +a.menu { + /*color: #3ba6ec; */ + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; +} + +a.menu[href]:visited, a.menu[href]:link{ + /*color: #3ba6ec; */ + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; +} + +a.menu[href]:hover { + /*color: black;*/ +} + +div.project_title{ + /*border-spacing: 20px;*/ + font: 160% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: middle; + padding-bottom: 0.3em; +} + +a.wikicurrent { + font: 100% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: middle; +} + + +table.body { + border: 0; + /*padding: 0; + border-spacing: 0px; + border-collapse: separate; + */ +} + +td.page-header-left { + padding: 5px; + /*border-bottom: 1px solid #444444;*/ +} + +td.page-header-top { + padding: 0; + + /*border-bottom: 1px solid #444444;*/ +} + +td.sidebar { + padding: 1 0 0 1; +} + +td.sidebar p.classblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeee; +} + +td.sidebar p.userblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeff; +} + +td.content { + padding: 1 5 1 5; + vertical-align: top; + width: 100%; +} + +p.ok-message { + background-color: #22bb22; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +p.error-message { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} + +p:first-child { + margin: 0 ; + padding: 0; +} + +/* style for forms */ +table.form { + padding: 2; + border-spacing: 0px; + border-collapse: separate; +} + +table.form th { + color: #333388; + text-align: right; + vertical-align: top; + font-weight: normal; +} +table.form th.header { + font-weight: bold; + background-color: #eeeeff; + text-align: left; +} + +table.form th.required { + font-weight: bold; +} + +table.form td { + color: #333333; + empty-cells: show; + vertical-align: top; +} + +table.form td.optional { + font-weight: bold; + font-style: italic; +} + +table.form td.html { + color: #777777; +} + +/* style for lists */ +table.list { + border-spacing: 0px; + border-collapse: separate; + vertical-align: top; + padding-top: 0; + width: 100%; +} + +table.list th { + padding: 0 4 0 4; + color: #404070; + background-color: #eeeeff; + border-right: 1px solid #404070; + border-top: 1px solid #404070; + border-bottom: 1px solid #404070; + vertical-align: top; + empty-cells: show; +} +table.list th a[href]:hover { color: #404070 } +table.list th a[href]:link { color: #404070 } +table.list th a[href] { color: #404070 } +table.list th.group { + background-color: #f4f4ff; + text-align: center; + font-size: 120%; +} + +table.list td { + padding: 0 4 0 4; + border: 0 2 0 2; + border-right: 1px solid #404070; + color: #404070; + background-color: white; + vertical-align: top; + empty-cells: show; +} + +table.list tr.normal td { + background-color: white; + white-space: nowrap; +} + +table.list tr.alt td { + background-color: #efefef; + white-space: nowrap; +} + +table.list td:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list th:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list tr.navigation th { + text-align: right; +} +table.list tr.navigation th:first-child { + border-right: none; + text-align: left; +} + + +/* style for message displays */ +table.messages { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.messages th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.messages th { + font-weight: bold; + color: black; + text-align: left; + border-bottom: 1px solid #afafaf; +} + +table.messages td { + font-family: monospace; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + color: black; + empty-cells: show; + border-right: 1px solid #afafaf; + vertical-align: top; + padding: 2 5 2 5; +} + +table.messages td:first-child { + border-left: 1px solid #afafaf; + border-right: 1px solid #afafaf; +} + +/* style for file displays */ +table.files { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.files th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.files th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +table.files td { + font-family: monospace; + empty-cells: show; +} + +/* style for history displays */ +table.history { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.history th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; + font-size: 100%; +} + +table.history th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; + font-size: 90%; +} + +table.history td { + font-size: 90%; + vertical-align: top; + empty-cells: show; +} + + +/* style for class list */ +table.classlist { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classlist th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.classlist th { + font-weight: bold; + text-align: left; +} + + +/* style for class help display */ +table.classhelp { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classhelp th { + font-weight: bold; + text-align: left; + color: #707040; +} + +table.classhelp td { + padding: 2 2 2 2; + border: 1px solid black; + text-align: left; + vertical-align: top; + empty-cells: show; +} + + +/* style for "other" displays */ +table.otherinfo { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.otherinfo th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.otherinfo th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +input { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + +select { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + + +a.nonexistent { + color: #FF2222; +} +a.nonexistent:visited { + color: #FF2222; +} +a.external { + color: #AA6600; +} + +/* +dl,ul,ol { + margin-top: 1pt; +} +tt,pre { + font-family: Lucida Console,Courier New,Courier,monotype; + font-size: 12pt; +} +pre.code { + margin-top: 8pt; + margin-bottom: 8pt; + background-color: #FFFFEE; + white-space:pre; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#111111; + padding:5px; + width:100%; +} +*/ +div.diffold { + background-color: #FFFF80; + border-style:none; + border-width:thin; + width:100%; +} +div.diffnew { + background-color: #80FF80; + border-style:none; + border-width:thin; + width:100%; +} +div.message { + margin-top: 6pt; + background-color: #E8FFE8; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#440000; + padding:5px; + width:100%; +} +strong.highlight { + background-color: #FFBBBB; +/* as usual, NetScape fucks up with innocent CSS + border-color: #FFAAAA; + border-style: solid; + border-width: 1pt; +*/ +} + +table.navibar { + background-color: #C8C8C8; + border-spacing: 3px; +} +td.navibar { + background-color: #E8E8E8; + vertical-align: top; + text-align: right; + padding: 0px; +} + +div.pagename { + font-size: 140%; + color: blue; + text-align: center; + font-weight: bold; + background-color: white; + padding: 0 ; +} + +a.wikiaction, input.wikiaction { + color: black; + text-decoration: None; + text-align: center; + color: black; + /*border: 1px solid #3ba6ec; */ + margin: 4px; + padding: 5; + padding-bottom: 0; + white-space: nowrap; +} + +a.wikiaction[href]:hover { + color: black; + text-decoration: none; + /*background-color: #dddddd; */ +} + +span.wikiuserpref { + padding-top: 1em; + font-size: 120%; +} + +div.wikitrail { + vertical-align: bottom; + /*font-size: -1;*/ + padding-top: 1em; + display: none; +} + +div.wikiaction { + vertical-align: middle; + /*border-bottom: 1px solid #8cacbb;*/ + padding-bottom:1em; + text-align: left; + width: 100%; +} + +div.wikieditmenu { + text-align: right; +} + +form.wikiedit { + border: 1px solid #8cacbb; + background-color: #f0f0f0; + background-color: #fabf00; + padding: 1em; + padding-right: 0em; +} + +div.legenditem { + padding-top: 0.5em; + padding-left: 0.3em; +} + +span.wikitoken { + background-color: #eeeeee; +} + + +div#contentspace h1:first-child, div.heading:first-child { + padding-top: 0; + margin-top: 0; +} +div#contentspace h2:first-child { + padding-top: 0; + margin-top: 0; +} + +/* heading and paragraph text */ + +div.heading, h1 { + font-family: Verdana, Helvetica, Arial, sans-serif; + background-color: #58b3ef; + background-color: #FFFFFF; + /*color: #4893cf;*/ + color: black; + padding-top: 1.0em; + padding-bottom:0.2em; + text-align: left; + margin-top: 0em; + /*margin-bottom:8pt;*/ + font-weight: bold; + font-size: 115%; + border-bottom: 1px solid #8CACBB; +} + + +h1, h2, h3, h4, h5, h6 { + color: orange; + clear: left; + font: 100% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 1em; + padding-bottom: 0.2em; + /*border-bottom: 1px solid #8CACBB;*/ +} +/* h1,h2 { padding-top: 0; }*/ + + +h1 { font-size: 145%; } +h2 { font-size: 135%; } +h3 { font-size: 125%; } +h4 { font-size: 120%; } +h5 { font-size: 110%; } +h6 { font-size: 80%; } + +h1 a { text-decoration: None;} + +div.exception { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +pre.exception { + font-size: 110%; + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; +} + +/* defines for navgiation bar (documentation) */ + + +div.direntry { + padding-top: 0.3em; + padding-bottom: 0.3em; + margin-right: 1em; + font-weight: bold; + background-color: #dee7ec; + font-size: 110%; +} + +div.fileentry { + font-family: Verdana, Helvetica, Arial, sans-serif; + padding-bottom: 0.3em; + white-space: nowrap; + line-height: 150%; +} + +a.fileentry { + white-space: nowrap; +} + + +span.left { + text-align: left; +} +span.right { + text-align: right; +} + +div.navbar { + /*margin: 0;*/ + font-size: 80% /*smaller*/; + font-weight: bold; + text-align: left; + /* position: fixed; */ + top: 100pt; + left: 0pt; /* auto; */ + width: 120pt; + /* right: auto; + right: 0pt; 2em; */ +} + + +div.history a { + /* font-size: 70%; */ +} + +div.wikiactiontitle { + font-weight: bold; +} + +/* REST defines */ + +div.document { + margin: 0; +} + +h1.title { + margin: 0; + margin-bottom: 0.5em; +} + +td.toplist { + vertical-align: top; +} + +img#pyimg { + position: absolute; + top: 4px; + left: 4px; +} + +div#navspace { + position: absolute; + top: 130px; + left: 11px; + font-size: 100%; + width: 150px; + overflow: hidden; /* scroll; */ +} + +div#metaspace { + position: absolute; + top: 40px; + left: 170px; +} + +div#errorline { + position: relative; + top: 5px; + float: right; +} + +div#contentspace { + position: absolute; + /* font: 120% "Times New Roman", serif;*/ + font: 110% Verdana, Helvetica, Arial, sans-serif; + top: 130px; + left: 170px; + margin-right: 5px; +} + +div#menubar { +/* width: 400px; */ + float: left; +} + +/* for the documentation page */ +div#docinfoline { + position: relative; + top: 5px; + left: 0px; + + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 1em; + color: black; + /*border-width: 1pt; + border-style: solid;*/ + +} + +div#docnavlist { + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 2em; + color: black; + border-width: 1pt; + /*border-style: solid;*/ +} + + +/* text markup */ + +div.listtitle { + color: Black; + clear: left; + font: 120% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 0em; + padding-bottom: 0.2em; + margin-right: 0.5em; + border-bottom: 1px solid #8CACBB; +} + +div.actionbox h3 { + padding-top: 0; + padding-right: 0.5em; + padding-left: 0.5em; + background-color: #fabf00; + text-align: center; + border: 1px solid black; /* 8cacbb; */ +} + +div.actionbox a { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; +} + +div.actionbox a.history { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; + font-size: 90%; +} + +div.actionbox { + margin-bottom: 2em; + padding-bottom: 1em; + overflow: hidden; /* scroll; */ +} + +/* taken from docutils (oh dear, a bit senseless) */ +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + + +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date: 2003/01/22 22:26:48 $ +:version: $Revision: 1.29 $ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. +*/ +/* +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.title { + text-align: center ; + color: orange} + +h2.subtitle { + color: orange; + text-align: center } + +hr { + width: 75% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } + +tt { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } +*/ + +div.section { + margin-top: 1.0em ; +} diff --git a/src/doc/build/docutils.css b/src/doc/build/docutils.css new file mode 100644 index 0000000..f03e03d --- /dev/null +++ b/src/doc/build/docutils.css @@ -0,0 +1,255 @@ +.first { + margin-top: 0 ! important } + +.last { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +a.toc-backref { + text-decoration: none ; + color: inherit } + +blockquote.epigraph { + margin: 2em 5em } + +dl.docutils dd { + margin-bottom: 0.5em } + +dl.docutils dt { + font-weight: bold } + +dl dt { line-height: 150% } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.document { + width: 600px ; + margin-left: 5em ; + margin-right: 5em } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1, h2, h3, h4, h5 { + font-family: sans-serif ; + line-height: 150% ; + color: orange} /* #666 } */ + +h1.title { + text-align: center + } +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + font-size: small ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table.citation { + border-left: solid thin gray } + +table.docinfo { + /* float: right ; */ + margin: 2em 4em ; + color: #666 } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid thin black } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: right ; + white-space: nowrap } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } + diff --git a/src/doc/build/pydoc/Makefile b/src/doc/build/pydoc/Makefile new file mode 100644 index 0000000..612cb8f --- /dev/null +++ b/src/doc/build/pydoc/Makefile @@ -0,0 +1,5 @@ +.PHONY: clean +.SUFFIXES: + +clean: + rm -f *.html diff --git a/src/doc/build/pydoc/api-objects.txt b/src/doc/build/pydoc/api-objects.txt new file mode 100644 index 0000000..c9ed6ab --- /dev/null +++ b/src/doc/build/pydoc/api-objects.txt @@ -0,0 +1,377 @@ +tiramisu tiramisu-module.html +tiramisu.__package__ tiramisu-module.html#__package__ +tiramisu.autolib tiramisu.autolib-module.html +tiramisu.autolib.calculate tiramisu.autolib-module.html#calculate +tiramisu.autolib.special_owners tiramisu.autolib-module.html#special_owners +tiramisu.autolib.__package__ tiramisu.autolib-module.html#__package__ +tiramisu.autolib.calc_factory tiramisu.autolib-module.html#calc_factory +tiramisu.autolib.special_owner_factory tiramisu.autolib-module.html#special_owner_factory +tiramisu.basetype tiramisu.basetype-module.html +tiramisu.basetype.modes tiramisu.basetype-module.html#modes +tiramisu.basetype.__package__ tiramisu.basetype-module.html#__package__ +tiramisu.config tiramisu.config-module.html +tiramisu.config.__package__ tiramisu.config-module.html#__package__ +tiramisu.config.special_owner_factory tiramisu.autolib-module.html#special_owner_factory +tiramisu.config.make_dict tiramisu.config-module.html#make_dict +tiramisu.config.apply_requires tiramisu.option-module.html#apply_requires +tiramisu.error tiramisu.error-module.html +tiramisu.error.__package__ tiramisu.error-module.html#__package__ +tiramisu.option tiramisu.option-module.html +tiramisu.option.__package__ tiramisu.option-module.html#__package__ +tiramisu.option.reverse_actions tiramisu.option-module.html#reverse_actions +tiramisu.option.group_types tiramisu.option-module.html#group_types +tiramisu.option.apply_requires tiramisu.option-module.html#apply_requires +tiramisu.option.available_actions tiramisu.option-module.html#available_actions +tiramisu.tool tiramisu.tool-module.html +tiramisu.tool.apply_requires tiramisu.option-module.html#apply_requires +tiramisu.tool.__package__ tiramisu.tool-module.html#__package__ +tiramisu.tool.reverse_from_paths tiramisu.tool-module.html#reverse_from_paths +tiramisu.basetype.DisabledBaseType tiramisu.basetype.DisabledBaseType-class.html +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.basetype.HiddenBaseType tiramisu.basetype.HiddenBaseType-class.html +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.ModeBaseType tiramisu.basetype.ModeBaseType-class.html +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.config.Config tiramisu.config.Config-class.html +tiramisu.config.Config.set tiramisu.config.Config-class.html#set +tiramisu.config.Config.unwrap_from_name tiramisu.config.Config-class.html#unwrap_from_name +tiramisu.config.Config.cfgimpl_unfreeze tiramisu.config.Config-class.html#cfgimpl_unfreeze +tiramisu.config.Config._validate tiramisu.config.Config-class.html#_validate +tiramisu.config.Config.__str__ tiramisu.config.Config-class.html#__str__ +tiramisu.config.Config.cfgimpl_set_owner tiramisu.config.Config-class.html#cfgimpl_set_owner +tiramisu.config.Config.getkey tiramisu.config.Config-class.html#getkey +tiramisu.config.Config._cfgimpl_mandatory tiramisu.config.Config-class.html#_cfgimpl_mandatory +tiramisu.config.Config.unwrap_from_path tiramisu.config.Config-class.html#unwrap_from_path +tiramisu.config.Config.__init__ tiramisu.config.Config-class.html#__init__ +tiramisu.config.Config._validate_duplicates tiramisu.config.Config-class.html#_validate_duplicates +tiramisu.config.Config._cfgimpl_owner tiramisu.config.Config-class.html#_cfgimpl_owner +tiramisu.config.Config.__getattr__ tiramisu.config.Config-class.html#__getattr__ +tiramisu.config.Config._cfgimpl_hidden tiramisu.config.Config-class.html#_cfgimpl_hidden +tiramisu.config.Config.iter_groups tiramisu.config.Config-class.html#iter_groups +tiramisu.config.Config.get_warnings tiramisu.config.Config-class.html#get_warnings +tiramisu.config.Config.cfgimpl_update tiramisu.config.Config-class.html#cfgimpl_update +tiramisu.config.Config.override tiramisu.config.Config-class.html#override +tiramisu.config.Config.setoption tiramisu.config.Config-class.html#setoption +tiramisu.config.Config.__ne__ tiramisu.config.Config-class.html#__ne__ +tiramisu.config.Config.cfgimpl_disable tiramisu.config.Config-class.html#cfgimpl_disable +tiramisu.config.Config.__hash__ tiramisu.config.Config-class.html#__hash__ +tiramisu.config.Config.get tiramisu.config.Config-class.html#get +tiramisu.config.Config._cfgimpl_get_toplevel tiramisu.config.Config-class.html#_cfgimpl_get_toplevel +tiramisu.config.Config._cfgimpl_build tiramisu.config.Config-class.html#_cfgimpl_build +tiramisu.config.Config.__setattr__ tiramisu.config.Config-class.html#__setattr__ +tiramisu.config.Config.is_frozen tiramisu.config.Config-class.html#is_frozen +tiramisu.config.Config.__iter__ tiramisu.config.Config-class.html#__iter__ +tiramisu.config.Config._cfgimpl_toplevel tiramisu.config.Config-class.html#_cfgimpl_toplevel +tiramisu.config.Config._cfgimpl_get_home_by_path tiramisu.config.Config-class.html#_cfgimpl_get_home_by_path +tiramisu.config.Config._cfgimpl_mode tiramisu.config.Config-class.html#_cfgimpl_mode +tiramisu.config.Config.cfgimpl_read_write tiramisu.config.Config-class.html#cfgimpl_read_write +tiramisu.config.Config.__eq__ tiramisu.config.Config-class.html#__eq__ +tiramisu.config.Config.__dir__ tiramisu.config.Config-class.html#__dir__ +tiramisu.config.Config.getpaths tiramisu.config.Config-class.html#getpaths +tiramisu.config.Config.cfgimpl_set_mode tiramisu.config.Config-class.html#cfgimpl_set_mode +tiramisu.config.Config.cfgimpl_hide tiramisu.config.Config-class.html#cfgimpl_hide +tiramisu.config.Config.cfgimpl_show tiramisu.config.Config-class.html#cfgimpl_show +tiramisu.config.Config._cfgimpl_frozen tiramisu.config.Config-class.html#_cfgimpl_frozen +tiramisu.config.Config._cfgimpl_disabled tiramisu.config.Config-class.html#_cfgimpl_disabled +tiramisu.config.Config.__delattr__ tiramisu.config.Config-class.html#__delattr__ +tiramisu.config.Config.add_warning tiramisu.config.Config-class.html#add_warning +tiramisu.config.Config.cfgimpl_enable tiramisu.config.Config-class.html#cfgimpl_enable +tiramisu.config.Config.cfgimpl_freeze tiramisu.config.Config-class.html#cfgimpl_freeze +tiramisu.config.Config.cfgimpl_read_only tiramisu.config.Config-class.html#cfgimpl_read_only +tiramisu.error.AmbigousOptionError tiramisu.error.AmbigousOptionError-class.html +tiramisu.error.ConfigError tiramisu.error.ConfigError-class.html +tiramisu.error.ConflictConfigError tiramisu.error.ConflictConfigError-class.html +tiramisu.error.DisabledOptionError tiramisu.error.DisabledOptionError-class.html +tiramisu.error.HiddenOptionError tiramisu.error.HiddenOptionError-class.html +tiramisu.error.MandatoryError tiramisu.error.MandatoryError-class.html +tiramisu.error.MethodCallError tiramisu.error.MethodCallError-class.html +tiramisu.error.ModeOptionError tiramisu.error.ModeOptionError-class.html +tiramisu.error.NoMatchingOptionFound tiramisu.error.NoMatchingOptionFound-class.html +tiramisu.error.NotFoundError tiramisu.error.NotFoundError-class.html +tiramisu.error.RequiresError tiramisu.error.RequiresError-class.html +tiramisu.error.SpecialOwnersError tiramisu.error.SpecialOwnersError-class.html +tiramisu.option.ArbitraryOption tiramisu.option.ArbitraryOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.ArbitraryOption._validate tiramisu.option.ArbitraryOption-class.html#_validate +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.ArbitraryOption.__init__ tiramisu.option.ArbitraryOption-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.Option.setoption tiramisu.option.Option-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.ArbitraryOption.getdefault tiramisu.option.ArbitraryOption-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.BoolOption tiramisu.option.BoolOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.BoolOption._validate tiramisu.option.BoolOption-class.html#_validate +tiramisu.option.BoolOption.opt_type tiramisu.option.BoolOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.Option.setoption tiramisu.option.Option-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.ChoiceOption tiramisu.option.ChoiceOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.ChoiceOption._validate tiramisu.option.ChoiceOption-class.html#_validate +tiramisu.option.ChoiceOption.opt_type tiramisu.option.ChoiceOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.ChoiceOption.__init__ tiramisu.option.ChoiceOption-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.ChoiceOption.setoption tiramisu.option.ChoiceOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.FloatOption tiramisu.option.FloatOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.FloatOption._validate tiramisu.option.FloatOption-class.html#_validate +tiramisu.option.FloatOption.opt_type tiramisu.option.FloatOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.FloatOption.setoption tiramisu.option.FloatOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.IPOption tiramisu.option.IPOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.IPOption._validate tiramisu.option.IPOption-class.html#_validate +tiramisu.option.IPOption.opt_type tiramisu.option.IPOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.IPOption.setoption tiramisu.option.IPOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.IntOption tiramisu.option.IntOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.IntOption._validate tiramisu.option.IntOption-class.html#_validate +tiramisu.option.IntOption.opt_type tiramisu.option.IntOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.IntOption.setoption tiramisu.option.IntOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.NetmaskOption tiramisu.option.NetmaskOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.NetmaskOption._validate tiramisu.option.NetmaskOption-class.html#_validate +tiramisu.option.NetmaskOption.opt_type tiramisu.option.NetmaskOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.NetmaskOption.setoption tiramisu.option.NetmaskOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.Option tiramisu.option.Option-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.Option.setoption tiramisu.option.Option-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.OptionDescription tiramisu.option.OptionDescription-class.html +tiramisu.option.OptionDescription.show tiramisu.option.OptionDescription-class.html#show +tiramisu.option.OptionDescription.add_child tiramisu.option.OptionDescription-class.html#add_child +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.OptionDescription.__init__ tiramisu.option.OptionDescription-class.html#__init__ +tiramisu.option.OptionDescription.hide tiramisu.option.OptionDescription-class.html#hide +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.option.OptionDescription.get_group_type tiramisu.option.OptionDescription-class.html#get_group_type +tiramisu.option.OptionDescription.update_child tiramisu.option.OptionDescription-class.html#update_child +tiramisu.option.OptionDescription.set_group_type tiramisu.option.OptionDescription-class.html#set_group_type +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.option.OptionDescription.group_type tiramisu.option.OptionDescription-class.html#group_type +tiramisu.option.OptionDescription.getpaths tiramisu.option.OptionDescription-class.html#getpaths +tiramisu.option.OptionDescription.enable tiramisu.option.OptionDescription-class.html#enable +tiramisu.option.OptionDescription.disable tiramisu.option.OptionDescription-class.html#disable +tiramisu.option.OptionDescription.getkey tiramisu.option.OptionDescription-class.html#getkey +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.OptionDescription._build tiramisu.option.OptionDescription-class.html#_build +tiramisu.option.OptionDescription.getdoc tiramisu.option.OptionDescription-class.html#getdoc +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.StrOption tiramisu.option.StrOption-class.html +tiramisu.basetype.HiddenBaseType.show tiramisu.basetype.HiddenBaseType-class.html#show +tiramisu.option.StrOption._validate tiramisu.option.StrOption-class.html#_validate +tiramisu.option.StrOption.opt_type tiramisu.option.StrOption-class.html#opt_type +tiramisu.option.Option.getkey tiramisu.option.Option-class.html#getkey +tiramisu.basetype.DisabledBaseType.disabled tiramisu.basetype.DisabledBaseType-class.html#disabled +tiramisu.option.Option.setowner tiramisu.option.Option-class.html#setowner +tiramisu.basetype.DisabledBaseType._is_disabled tiramisu.basetype.DisabledBaseType-class.html#_is_disabled +tiramisu.option.Option.__init__ tiramisu.option.Option-class.html#__init__ +tiramisu.option.Option.is_mandatory tiramisu.option.Option-class.html#is_mandatory +tiramisu.basetype.ModeBaseType.set_mode tiramisu.basetype.ModeBaseType-class.html#set_mode +tiramisu.basetype.HiddenBaseType._is_hidden tiramisu.basetype.HiddenBaseType-class.html#_is_hidden +tiramisu.basetype.HiddenBaseType.hidden tiramisu.basetype.HiddenBaseType-class.html#hidden +tiramisu.basetype.DisabledBaseType.enable tiramisu.basetype.DisabledBaseType-class.html#enable +tiramisu.option.StrOption.setoption tiramisu.option.StrOption-class.html#setoption +tiramisu.basetype.DisabledBaseType.disable tiramisu.basetype.DisabledBaseType-class.html#disable +tiramisu.option.Option.getcallback tiramisu.option.Option-class.html#getcallback +tiramisu.basetype.HiddenBaseType.hide tiramisu.basetype.HiddenBaseType-class.html#hide +tiramisu.option.Option.validate tiramisu.option.Option-class.html#validate +tiramisu.option.Option.freeze tiramisu.option.Option-class.html#freeze +tiramisu.basetype.ModeBaseType.get_mode tiramisu.basetype.ModeBaseType-class.html#get_mode +tiramisu.option.Option._frozen tiramisu.option.Option-class.html#_frozen +tiramisu.option.Option.getdoc tiramisu.option.Option-class.html#getdoc +tiramisu.option.Option.is_multi tiramisu.option.Option-class.html#is_multi +tiramisu.option.Option.getdefault tiramisu.option.Option-class.html#getdefault +tiramisu.option.Option.unfreeze tiramisu.option.Option-class.html#unfreeze +tiramisu.basetype.ModeBaseType.mode tiramisu.basetype.ModeBaseType-class.html#mode +tiramisu.option.Option.getcallback_params tiramisu.option.Option-class.html#getcallback_params +tiramisu.option.SymLinkOption tiramisu.option.SymLinkOption-class.html +tiramisu.option.SymLinkOption.setoption tiramisu.option.SymLinkOption-class.html#setoption +tiramisu.option.SymLinkOption.opt_type tiramisu.option.SymLinkOption-class.html#opt_type +tiramisu.option.SymLinkOption.__init__ tiramisu.option.SymLinkOption-class.html#__init__ +tiramisu.tool.extend tiramisu.tool.extend-class.html +tiramisu.tool.extend.extend tiramisu.tool.extend-class.html#extend diff --git a/src/doc/build/pydoc/crarr.png b/src/doc/build/pydoc/crarr.png new file mode 100644 index 0000000..26b43c5 Binary files /dev/null and b/src/doc/build/pydoc/crarr.png differ diff --git a/src/doc/build/pydoc/epydoc.css b/src/doc/build/pydoc/epydoc.css new file mode 100644 index 0000000..1c00695 --- /dev/null +++ b/src/doc/build/pydoc/epydoc.css @@ -0,0 +1,322 @@ + + +/* Epydoc CSS Stylesheet + * + * This stylesheet can be used to customize the appearance of epydoc's + * HTML output. + * + */ + +/* Default Colors & Styles + * - Set the default foreground & background color with 'body'; and + * link colors with 'a:link' and 'a:visited'. + * - Use bold for decision list terms. + * - The heading styles defined here are used for headings *within* + * docstring descriptions. All headings used by epydoc itself use + * either class='epydoc' or class='toc' (CSS styles for both + * defined below). + */ +body { background: #ffffff; color: #000000; } +p { margin-top: 0.5em; margin-bottom: 0.5em; } +a:link { color: #000000; } +a:visited { color: #404040; } +dt { font-weight: bold; } +h1 { font-size: +140%; font-style: italic; + font-weight: bold; } +h2 { font-size: +125%; font-style: italic; + font-weight: bold; } +h3 { font-size: +110%; font-style: italic; + font-weight: normal; } +code { font-size: 100%; } +/* N.B.: class, not pseudoclass */ +a.link { font-family: monospace; } + +/* Page Header & Footer + * - The standard page header consists of a navigation bar (with + * pointers to standard pages such as 'home' and 'trees'); a + * breadcrumbs list, which can be used to navigate to containing + * classes or modules; options links, to show/hide private + * variables and to show/hide frames; and a page title (using + *

). The page title may be followed by a link to the + * corresponding source code (using 'span.codelink'). + * - The footer consists of a navigation bar, a timestamp, and a + * pointer to epydoc's homepage. + */ +h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } +h2.epydoc { font-size: +130%; font-weight: bold; } +h3.epydoc { font-size: +115%; font-weight: bold; + margin-top: 0.2em; } +td h3.epydoc { font-size: +115%; font-weight: bold; + margin-bottom: 0; } +table.navbar { background: #c0c0c0; color: #000000; + border: 2px groove #d0d0d0; } +table.navbar table { color: #000000; } +th.navbar-select { background: #b0b0b0; + color: #000000; } +table.navbar a { text-decoration: none; } +table.navbar a:link { color: #000000; } +table.navbar a:visited { color: #404040; } +span.breadcrumbs { font-size: 85%; font-weight: bold; } +span.options { font-size: 70%; } +span.codelink { font-size: 85%; } +td.footer { font-size: 85%; } + +/* Table Headers + * - Each summary table and details section begins with a 'header' + * row. This row contains a section title (marked by + * 'span.table-header') as well as a show/hide private link + * (marked by 'span.options', defined above). + * - Summary tables that contain user-defined groups mark those + * groups using 'group header' rows. + */ +td.table-header { background: #b0b0b0; color: #000000; + border: 1px solid #808080; } +td.table-header table { color: #000000; } +td.table-header table a:link { color: #000000; } +td.table-header table a:visited { color: #404040; } +span.table-header { font-size: 120%; font-weight: bold; } +th.group-header { background: #e0e0e0; color: #000000; + text-align: left; font-style: italic; + font-size: 115%; + border: 1px solid #808080; } + +/* Summary Tables (functions, variables, etc) + * - Each object is described by a single row of the table with + * two cells. The left cell gives the object's type, and is + * marked with 'code.summary-type'. The right cell gives the + * object's name and a summary description. + * - CSS styles for the table's header and group headers are + * defined above, under 'Table Headers' + */ +table.summary { border-collapse: collapse; + background: #f0f0f0; color: #000000; + border: 1px solid #808080; + margin-bottom: 0.5em; } +td.summary { border: 1px solid #808080; } +code.summary-type { font-size: 85%; } +table.summary a:link { color: #000000; } +table.summary a:visited { color: #404040; } + + +/* Details Tables (functions, variables, etc) + * - Each object is described in its own div. + * - A single-row summary table w/ table-header is used as + * a header for each details section (CSS style for table-header + * is defined above, under 'Table Headers'). + */ +table.details { border-collapse: collapse; + background: #f0f0f0; color: #000000; + border: 1px solid #808080; + margin: .2em 0 0 0; } +table.details table { color: #000000; } +table.details a:link { color: #000000; } +table.details a:visited { color: #404040; } + +/* Fields */ +dl.fields { margin-left: 2em; margin-top: 1em; + margin-bottom: 1em; } +dl.fields dd ul { margin-left: 0em; padding-left: 0em; } +dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } +div.fields { margin-left: 2em; } +div.fields p { margin-bottom: 0.5em; } + +/* Index tables (identifier index, term index, etc) + * - link-index is used for indices containing lists of links + * (namely, the identifier index & term index). + * - index-where is used in link indices for the text indicating + * the container/source for each link. + * - metadata-index is used for indices containing metadata + * extracted from fields (namely, the bug index & todo index). + */ +table.link-index { border-collapse: collapse; + background: #f0f0f0; color: #000000; + border: 1px solid #808080; } +td.link-index { border-width: 0px; } +table.link-index a:link { color: #000000; } +table.link-index a:visited { color: #404040; } +span.index-where { font-size: 70%; } +table.metadata-index { border-collapse: collapse; + background: #f0f0f0; color: #000000; + border: 1px solid #808080; + margin: .2em 0 0 0; } +td.metadata-index { border-width: 1px; border-style: solid; } +table.metadata-index a:link { color: #000000; } +table.metadata-index a:visited { color: #404040; } + +/* Function signatures + * - sig* is used for the signature in the details section. + * - .summary-sig* is used for the signature in the summary + * table, and when listing property accessor functions. + * */ +.sig-name { color: #606060; } +.sig-arg { color: #808080; } +.sig-default { color: #202020; } +.summary-sig { font-family: monospace; } +.summary-sig-name { color: #606060; font-weight: bold; } +table.summary a.summary-sig-name:link + { color: #606060; font-weight: bold; } +table.summary a.summary-sig-name:visited + { color: #606060; font-weight: bold; } +.summary-sig-arg { color: #606060; } +.summary-sig-default { color: #181818; } + +/* Subclass list + */ +ul.subclass-list { display: inline; } +ul.subclass-list li { display: inline; } + +/* To render variables, classes etc. like functions */ +table.summary .summary-name { color: #606060; font-weight: bold; + font-family: monospace; } +table.summary + a.summary-name:link { color: #606060; font-weight: bold; + font-family: monospace; } +table.summary + a.summary-name:visited { color: #606060; font-weight: bold; + font-family: monospace; } + +/* Variable values + * - In the 'variable details' sections, each varaible's value is + * listed in a 'pre.variable' box. The width of this box is + * restricted to 80 chars; if the value's repr is longer than + * this it will be wrapped, using a backslash marked with + * class 'variable-linewrap'. If the value's repr is longer + * than 3 lines, the rest will be ellided; and an ellipsis + * marker ('...' marked with 'variable-ellipsis') will be used. + * - If the value is a string, its quote marks will be marked + * with 'variable-quote'. + * - If the variable is a regexp, it is syntax-highlighted using + * the re* CSS classes. + */ +pre.variable { padding: .5em; margin: 0; + background: #e4e4e4; color: #000000; + border: 1px solid #888888; } +.variable-linewrap { color: #404040; font-weight: bold; } +.variable-ellipsis { color: #404040; font-weight: bold; } +.variable-quote { color: #404040; font-weight: bold; } +.variable-group { color: #808080; font-weight: bold; } +.variable-op { color: #404040; font-weight: bold; } +.variable-string { color: #606060; } +.variable-unknown { color: #000000; font-weight: bold; } +.re { color: #000000; } +.re-char { color: #606060; } +.re-op { color: #000000; } +.re-group { color: #303030; } +.re-ref { color: #404040; } + +/* Base tree + * - Used by class pages to display the base class hierarchy. + */ +pre.base-tree { font-size: 80%; margin: 0; } + +/* Frames-based table of contents headers + * - Consists of two frames: one for selecting modules; and + * the other listing the contents of the selected module. + * - h1.toc is used for each frame's heading + * - h2.toc is used for subheadings within each frame. + */ +h1.toc { text-align: center; font-size: 105%; + margin: 0; font-weight: bold; + padding: 0; } +h2.toc { font-size: 100%; font-weight: bold; + margin: 0.5em 0 0 -0.3em; } + +/* Syntax Highlighting for Source Code + * - doctest examples are displayed in a 'pre.py-doctest' block. + * If the example is in a details table entry, then it will use + * the colors specified by the 'table pre.py-doctest' line. + * - Source code listings are displayed in a 'pre.py-src' block. + * Each line is marked with 'span.py-line' (used to draw a line + * down the left margin, separating the code from the line + * numbers). Line numbers are displayed with 'span.py-lineno'. + * The expand/collapse block toggle button is displayed with + * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not + * modify the font size of the text.) + * - If a source code page is opened with an anchor, then the + * corresponding code block will be highlighted. The code + * block's header is highlighted with 'py-highlight-hdr'; and + * the code block's body is highlighted with 'py-highlight'. + * - The remaining py-* classes are used to perform syntax + * highlighting (py-string for string literals, py-name for names, + * etc.) + */ +pre.py-doctest { padding: .5em; margin: 1em; + background: #f0f0f0; color: #000000; + border: 1px solid #888888; } +table pre.py-doctest { background: #e4e4e4; + color: #000000; } +pre.py-src { border: 2px solid #000000; + background: #f0f0f0; color: #000000; } +.py-line { border-left: 2px solid #000000; + margin-left: .2em; padding-left: .4em; } +.py-lineno { font-style: italic; font-size: 90%; + padding-left: .5em; } +a.py-toggle { text-decoration: none; } +div.py-highlight-hdr { border-top: 2px solid #000000; + border-bottom: 2px solid #000000; + background: #e8e8e8; } +div.py-highlight { border-bottom: 2px solid #000000; + background: #e0e0e0; } +.py-prompt { color: #505050; font-weight: bold;} +.py-more { color: #505050; font-weight: bold;} +.py-string { color: #606060; } +.py-comment { color: #303030; } +.py-keyword { color: #000000; } +.py-output { color: #404040; } +.py-name { color: #000000; } +.py-name:link { color: #000000 !important; } +.py-name:visited { color: #000000 !important; } +.py-number { color: #505050; } +.py-defname { color: #000000; font-weight: bold; } +.py-def-name { color: #000000; font-weight: bold; } +.py-base-class { color: #000000; } +.py-param { color: #000000; } +.py-docstring { color: #606060; } +.py-decorator { color: #404040; } +/* Use this if you don't want links to names underlined: */ +/*a.py-name { text-decoration: none; }*/ + +/* Graphs & Diagrams + * - These CSS styles are used for graphs & diagrams generated using + * Graphviz dot. 'img.graph-without-title' is used for bare + * diagrams (to remove the border created by making the image + * clickable). + */ +img.graph-without-title { border: none; } +img.graph-with-title { border: 1px solid #000000; } +span.graph-title { font-weight: bold; } +span.graph-caption { } + +/* General-purpose classes + * - 'p.indent-wrapped-lines' defines a paragraph whose first line + * is not indented, but whose subsequent lines are. + * - The 'nomargin-top' class is used to remove the top margin (e.g. + * from lists). The 'nomargin' class is used to remove both the + * top and bottom margin (but not the left or right margin -- + * for lists, that would cause the bullets to disappear.) + */ +p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; + margin: 0; } +.nomargin-top { margin-top: 0; } +.nomargin { margin-top: 0; margin-bottom: 0; } + +/* HTML Log */ +div.log-block { padding: 0; margin: .5em 0 .5em 0; + background: #f0f0f0; color: #000000; + border: 1px solid #000000; } +div.log-error { padding: .1em .3em .1em .3em; margin: 4px; + background: #b0b0b0; color: #000000; + border: 1px solid #000000; } +div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; + background: #ffffff; color: #000000; + border: 1px solid #000000; } +div.log-info { padding: .1em .3em .1em .3em; margin: 4px; + background: #ffffff; color: #000000; + border: 1px solid #000000; } +h2.log-hdr { background: #b0b0b0; color: #000000; + margin: 0; padding: 0em 0.5em 0em 0.5em; + border-bottom: 1px solid #000000; font-size: 110%; } +p.log { font-weight: bold; margin: .5em 0 .5em 0; } +tr.opt-changed { color: #000000; font-weight: bold; } +tr.opt-default { color: #606060; } +pre.log { margin: 0; padding: 0; padding-left: 1em; } diff --git a/src/doc/build/pydoc/epydoc.js b/src/doc/build/pydoc/epydoc.js new file mode 100644 index 0000000..e787dbc --- /dev/null +++ b/src/doc/build/pydoc/epydoc.js @@ -0,0 +1,293 @@ +function toggle_private() { + // Search for any private/public links on this page. Store + // their old text in "cmd," so we will know what action to + // take; and change their text to the opposite action. + var cmd = "?"; + var elts = document.getElementsByTagName("a"); + for(var i=0; i...
"; + elt.innerHTML = s; + } +} + +function toggle(id) { + elt = document.getElementById(id+"-toggle"); + if (elt.innerHTML == "-") + collapse(id); + else + expand(id); + return false; +} + +function highlight(id) { + var elt = document.getElementById(id+"-def"); + if (elt) elt.className = "py-highlight-hdr"; + var elt = document.getElementById(id+"-expanded"); + if (elt) elt.className = "py-highlight"; + var elt = document.getElementById(id+"-collapsed"); + if (elt) elt.className = "py-highlight"; +} + +function num_lines(s) { + var n = 1; + var pos = s.indexOf("\n"); + while ( pos > 0) { + n += 1; + pos = s.indexOf("\n", pos+1); + } + return n; +} + +// Collapse all blocks that mave more than `min_lines` lines. +function collapse_all(min_lines) { + var elts = document.getElementsByTagName("div"); + for (var i=0; i 0) + if (elt.id.substring(split, elt.id.length) == "-expanded") + if (num_lines(elt.innerHTML) > min_lines) + collapse(elt.id.substring(0, split)); + } +} + +function expandto(href) { + var start = href.indexOf("#")+1; + if (start != 0 && start != href.length) { + if (href.substring(start, href.length) != "-") { + collapse_all(4); + pos = href.indexOf(".", start); + while (pos != -1) { + var id = href.substring(start, pos); + expand(id); + pos = href.indexOf(".", pos+1); + } + var id = href.substring(start, href.length); + expand(id); + highlight(id); + } + } +} + +function kill_doclink(id) { + var parent = document.getElementById(id); + parent.removeChild(parent.childNodes.item(0)); +} +function auto_kill_doclink(ev) { + if (!ev) var ev = window.event; + if (!this.contains(ev.toElement)) { + var parent = document.getElementById(this.parentID); + parent.removeChild(parent.childNodes.item(0)); + } +} + +function doclink(id, name, targets_id) { + var elt = document.getElementById(id); + + // If we already opened the box, then destroy it. + // (This case should never occur, but leave it in just in case.) + if (elt.childNodes.length > 1) { + elt.removeChild(elt.childNodes.item(0)); + } + else { + // The outer box: relative + inline positioning. + var box1 = document.createElement("div"); + box1.style.position = "relative"; + box1.style.display = "inline"; + box1.style.top = 0; + box1.style.left = 0; + + // A shadow for fun + var shadow = document.createElement("div"); + shadow.style.position = "absolute"; + shadow.style.left = "-1.3em"; + shadow.style.top = "-1.3em"; + shadow.style.background = "#404040"; + + // The inner box: absolute positioning. + var box2 = document.createElement("div"); + box2.style.position = "relative"; + box2.style.border = "1px solid #a0a0a0"; + box2.style.left = "-.2em"; + box2.style.top = "-.2em"; + box2.style.background = "white"; + box2.style.padding = ".3em .4em .3em .4em"; + box2.style.fontStyle = "normal"; + box2.onmouseout=auto_kill_doclink; + box2.parentID = id; + + // Get the targets + var targets_elt = document.getElementById(targets_id); + var targets = targets_elt.getAttribute("targets"); + var links = ""; + target_list = targets.split(","); + for (var i=0; i" + + target[0] + ""; + } + + // Put it all together. + elt.insertBefore(box1, elt.childNodes.item(0)); + //box1.appendChild(box2); + box1.appendChild(shadow); + shadow.appendChild(box2); + box2.innerHTML = + "Which "+name+" do you want to see documentation for?" + + ""; + } + return false; +} + +function get_anchor() { + var href = location.href; + var start = href.indexOf("#")+1; + if ((start != 0) && (start != href.length)) + return href.substring(start, href.length); + } +function redirect_url(dottedName) { + // Scan through each element of the "pages" list, and check + // if "name" matches with any of them. + for (var i=0; i-m" or "-c"; + // extract the portion & compare it to dottedName. + var pagename = pages[i].substring(0, pages[i].length-2); + if (pagename == dottedName.substring(0,pagename.length)) { + + // We've found a page that matches `dottedName`; + // construct its URL, using leftover `dottedName` + // content to form an anchor. + var pagetype = pages[i].charAt(pages[i].length-1); + var url = pagename + ((pagetype=="m")?"-module.html": + "-class.html"); + if (dottedName.length > pagename.length) + url += "#" + dottedName.substring(pagename.length+1, + dottedName.length); + return url; + } + } + } diff --git a/src/doc/build/style.css b/src/doc/build/style.css new file mode 100644 index 0000000..28c256e --- /dev/null +++ b/src/doc/build/style.css @@ -0,0 +1,32 @@ +@import url(docutils.css); +@import url(default.css); +a:link { + color: orange; + font-weight: bold; + text-decoration: none; +} +a:visited { + text-decoration: none; + color: #999999; +} +a:hover { + text-decoration: none; + color: #999999; +} +a:active { + text-decoration: none; + color: #999999; +} + +.header { + color: orange; + background-color: white; + padding: 1em; +} +.footer { + color: #666; + background-color: inherit; + font-size: 75%; +} + + diff --git a/src/doc/build/tiramisu.jpeg b/src/doc/build/tiramisu.jpeg new file mode 100644 index 0000000..84b391d Binary files /dev/null and b/src/doc/build/tiramisu.jpeg differ diff --git a/src/doc/code2html b/src/doc/code2html new file mode 100755 index 0000000..5fbd402 --- /dev/null +++ b/src/doc/code2html @@ -0,0 +1,82 @@ +#!/usr/bin/env python +import types +from os.path import join +from inspect import getsource, getmembers, isclass, isfunction, ismethod, ismodule +from importlib import import_module + +root="./build/api" + +# autopath + +from os.path import dirname, abspath, join, normpath +import sys + +HERE = dirname(abspath(__file__)) +PATH = normpath(join(HERE, '..', '..')) +if PATH not in sys.path: + sys.path.insert(1, PATH) + +htmltmpl = """ + + + +{title} + + + + + + +
+{content}
+
+ + +""" + +def write_source(name, content): + fh = file(join(root, name)+'.html', 'w') + fh.write(format_html(name, content)) + fh.close() + +def format_html(title, content): + return htmltmpl.format(title=title, content=content) + +def parse_module(module): + module = import_module(module) + write_source(module.__name__, getsource(module)) +# classes = [(cls, value) for cls, value in getattr(module, '__dict__').items() if value == types.ClassType] + classes = getmembers(module, isclass) + for name, obj in classes: + write_source(module.__name__ + '.' + name, getsource(obj)) +# methods = [(meth, value) for meth, value in getattr(obj, '__dict__').items() if type(value) == types.MethodType] + methods = getmembers(obj, ismethod) + for meth, value in methods: + write_source(module.__name__ + '.' + name + '.' + meth, getsource(value)) + + #functions = [(func, value) for func, value in getattr(module, '__dict__').items() if type(value) == types.FunctionType] + functions = getmembers(module, isfunction) + for name, obj in functions: + write_source(module.__name__ + '.' + name, getsource(obj)) + +def process_modules(): + from glob import glob + from os.path import abspath, dirname, normpath, splitext, basename + here = abspath(__file__) + directory = dirname(here) + pyfiles = glob(normpath(join(directory, '..', '*.py'))) + for pyf in pyfiles: + pyf = splitext(basename(pyf))[0] + modname = 'tiramisu.' + pyf + if not '__init__' in modname: + parse_module(modname) + + pyfiles = glob(normpath(join(directory, '..', 'test', '*.py'))) + for pyf in pyfiles: + pyf = splitext(basename(pyf))[0] + modname = 'tiramisu.test.' + pyf + if not '__init__' in modname: + parse_module(modname) + +process_modules() + diff --git a/src/doc/config.txt b/src/doc/config.txt new file mode 100644 index 0000000..9b967d7 --- /dev/null +++ b/src/doc/config.txt @@ -0,0 +1,158 @@ +.. default-role:: literal + +======================= +Configuration Handling +======================= + +:module: :api:`config.py` +:tests: - :api:`test_config.py` + - :api:`test_option_setting.py` + +Main Assumption +=============== + +Configuration option objects :api:`config.Config()` are produced at the +entry points and handed down to where they are actually used. This keeps +configuration local but available everywhere and consistent. + +`Config` and `Option` objects +============================== + +Configuration option objects can be created in different ways. Let's perform +very basic `Config` object manipulations: + +:: + + >>> from tiramisu.config import Config + >>> from tiramisu.option import OptionDescription, BoolOption + >>> descr = OptionDescription("optgroup", "", [ + ... BoolOption("bool", "", default=False)]) + >>> + >>> config = Config(descr) + >>> config.bool + False + >>> config.bool = True + >>> config.bool + True + +Take a look at :api:`test_config.test_base_config()` or +:api:`test_config.test_base_config_and_groups()`. + + +Accessing the configuration `Option`'s +----------------------------------------- + +The `Config` object attribute access notation stands for the value of the +configuration's `Option`. That is, the `Config`'s object attribute is the name +of the `Option`, and the value is the value accessed by the `__getattr__` +attribute access mechanism. + +If the attribute of the `Config` called by `__getattr__` has not been set before +(by the classic `__setattr__` mechanism), the default value of the `Option` +object is returned, and if no `Option` has been declared in the +`OptionDescription` (that is the schema of the configuration), an +`AttributeError` is raised. + +:: + + >>> gcdummy = BoolOption('dummy', 'dummy', default=False) + >>> gcdummy._name + 'dummy' + >>> gcdummy.getdefault() + False + >>> descr = OptionDescription('tiramisu', '', [gcdummy]) + >>> cfg = Config(descr) + >>> cfg.dummy + False + >>> cfg.dummy = True + >>> cfg.dummy + True + >>> cfg.idontexist + AttributeError: 'OptionDescription' object has no attribute 'idontexist' + +The configuration `Option` objects (in this case the `BoolOption`), are +organized into a tree into nested `OptionDescription` objects. Every +option has a name, as does every option group. The parts of the full +name of the option are separated by dots: e.g. +``config.optgroup.optname``. + +**Can you repeat it, what is the protocol of accessing a config's attribute ?** + +1. If the option has not been declared, an `AttributeError` is raised, + +2. If an option is declared, but neither a value nor a default value has + been set, the returned value is `None`, + +3. If an option is declared and a default value has been set, but no value + has been set, the returned value is the default value of the option, + +4. If an option is declared, and a value has been set, the returned value is + the value of the option. + +If you do not want to use the pythonic way, that is the attribute access +way to obtain the value of the configuration option, you can also search +for it recursively in the whole config namespaces with the ``get()`` +method : + +:: + + >>> config.get('bool') + True + + +To find the right option, `get()` searches recursively into the whole +tree. For example, to find an option which is in the `gc` namespace +there are two possibilites. + +If you know the path: + +:: + + >>> config.gc.dummy + False + +If you don't remember the path: + +:: + + >>> config.get('dummy') + False + +Setting the values of the options +---------------------------------------- + +An important part of the setting of the configuration consists of setting the +values of the configuration options. There are different ways of setting values, +the first one is of course the `__setattr__` method + +:: + + cfg.name = value + +wich has the same effect that the "global" `set()` method : it expects that +the value owner is the default :ref:`glossary#valueowner` + +:: + + cfg.set(name=value) + +The global `setoption()` method of the config objects can set a value with a specific owner + +:: + + cfg.setoption('name', value, 'owner') + + +Finally, the local `setoption()` method directly in the `Option` object can be +used. While the `Option` object refers to his parent, the config knows that the +value has been changed and no bad side effect won't occur + +:: + + >>> booloption = BoolOption('bool', 'Test boolean option', default=True) + >>> descr = OptionDescription('descr', '', [booloption]) + >>> cfg = Config(descr) + >>> booloption.setoption(cfg, False, 'owner') + >>> cfg.bool + >>> False + diff --git a/src/doc/configapi.txt b/src/doc/configapi.txt new file mode 100644 index 0000000..d6fe570 --- /dev/null +++ b/src/doc/configapi.txt @@ -0,0 +1,103 @@ +.. default-role:: literal + +Config API Details +================== + +:module: :api:`config.py` +:test cases: - :api:`test_config_api.py` + - :api:`test_config_big_example.py` + + +The handling of options is split into two parts: the description of +which options are available, what their possible values and defaults are +and how they are organized into a tree. A specific choice of options is +bundled into a configuration object which has a reference to its option +description (and therefore makes sure that the configuration values +adhere to the option description). + +The configuration object +------------------------- + +:api:`config.Config()` object that lives in :api:`config.py` hold the +choosen values for the options (or the default value for the +:api:`option.Option()` object, if no choice was made). + +A `Config` object is informed by an :api:`option.OptionDescription` +instance. The attributes of the ``Config`` objects are the names of the +children of the ``OptionDescription``. + +Here are the (useful) methods on ``Config``: + + :api:`config.Config.__init__(self, descr, **overrides)`: + ``descr`` is an instance of :api:`option.OptionDescription` that + describes the configuration object. ``override`` can be used to + set different default values (see method ``override``). + + :api:`config.Config.override(self, overrides)`: + override default values. This marks the overridden values as defaults. + ``overrides`` is a dictionary of path strings to values. + + :api:`config.Config.set(self, **kwargs)`: + "do what I mean"-interface to option setting. Searches all paths + starting from that config for matches of the optional arguments + and sets the found option if the match is not ambiguous. + + :api:`config.Config.get(self, name)`: + the behavior is much like the attribute access way, except that + the search for the option is performed recursively in the whole + configuration tree. + + :api:`config.Config.cfgimpl_read_write()`: + configuration level `read_write` status, see :doc:`status` + + :api:`config.Config.cfgimpl_read_only()`: + configuration level `read_only` status, see :doc:`status` + +Here are some private attributes of a `Config()` object, for a +comprehension of the internal merchanism: + +- `_cfgimpl_descr =` :api:`option.OptionDescription()`, + e.g. the :ref:`optionapi#schema` + +- `_cfgimpl_values` contains the :api:`option.Option()`'s values. + Yes, the values of the options: remember that the values are stored **inside** + the :api:`config.Config()` and not in the `Option()` + +`_cfgimpl_values` contains something like that + +:: + + {'int': 0, 'wantframework': False, 'objspace': 'std', 'bool': False, + 'str': 'abc', 'gc': , 'wantref': False} + +We can see that values can also be config objects, it's the +sub-namespaces that are stored in the values as `Config()` objects. + +convenience utilities (iteration, exports...) +----------------------------------------------- + +With this :api:`config.Config()` configuration management entry point, +it is possible to + +- `iter` on config, notice that there is an iteration order wich is + the order of the :ref:`optionapi#schema` specification entries, +- compare two configs (equality), +- export the whole config into a `dict` with :api:`config.make_dict()`, +- `validate()` an option value into a config, see :doc:`consistency`. + +:api:`option.Option()` objects in a config are iterable in the pythonic +way, that is something like `[(name, value) for name, value in config]`. + +To iter on groups in the same manner, use the +:api:`config.Config.iter_groups()` method wich yields generators too. + +**iteration utilities** + + :api:`config.Config.__iter__()` + Pythonesque way of parsing group's ordered options. + + :api:`config.Config.iter_groups(group_type=None)`: + To iter on groups objects only. + All groups are returned if `group_type` is `None`, otherwise the groups + can be filtered by categories (families, or whatever). + diff --git a/src/doc/consistency.txt b/src/doc/consistency.txt new file mode 100644 index 0000000..4b00606 --- /dev/null +++ b/src/doc/consistency.txt @@ -0,0 +1,104 @@ +.. default-role:: literal + +The global configuration's consistency +======================================== + +:module: :api:`config.py` +:tests: :api:`test_option_consistency.py` + +Option's values type validation +-------------------------------- + +When a value is set to the option, the value is validated by the +option's :api:`option.Option()` validator's type. + +Notice that if the option is `multi`, that is the `multi` attribute is set to +`True`, then the validation of the option value accepts a list of values +of the same type. + +Requirements +------------ + +Configuration options can specify requirements as parameters at the init +time, the specification of some links between options or groups allows +to carry out a dependencies calculation. For example, an option can ben +hidden if another option has been set with some expected value. This is +just an example, because the possibilities are hudge. + +A requirement is specified using a list of triplets. The first element +of the triplet gives the path of the option that is required, the second +element is the value wich is expected to trigger the callback, and the +third one is the callback's action name (`hide`, `show`...):: + + stroption = StrOption('str', 'Test string option', default="abc", + requires=[('int', 1, 'hide')]) + +Take a look at an example here +:api:`test_option_consistency.test_hidden_if_in()` + +Config updates +--------------- + +New configuration options and groups can be dynamically added. + +The configuration has to be *updated* after that the description has been +passed to the Config objet, see: + +:: + + >>> config = Config(descr) + >>> newoption = BoolOption('newoption', 'dummy twoo', default=False) + >>> descr.add_child(newoption) + >>> config.update() + >>> config.newoption + False + +in + +- :api:`test_option_consistency.test_newoption_add_in_descr()` +- :api:`test_option_consistency.test_newoption_add_in_subdescr()` +- :api:`test_option_consistency.test_newoption_add_in_config()` + + +Validation upon a whole configuration object +---------------------------------------------- + +An option's integrity can be validated towards a whole configuration. + +This type of validation is very open. Let's take a use case : an option +has a certain value, and the value of this option can change the owner +of another option or option group... Everything is possible. + +For example, the configuration paths have to be unique in the +:ref:`glossary#schema`, the validation is carried out at the +:api:`config.Config._cfgimpl_build()` time in the +:api:`config.Config._validate_duplicates()` method. + +Other hook are availables to validate upon a whole configuration at any +time. + +.. FIXME : get the validates hooks from the original config pypy's code + +Identical option names +---------------------- + +If an :api:`option.Option()` happens to be defined twice in the +:ref:`glossary#schema` (e.g. the :api:`option.OptionDescription()`), +:that is the two options actually have the same name, an exception is raised. + +The calculation is currently carried out in the samespace, for example +if `config.gc.name` is defined, another option in `gc` with the name +`name` is **not** allowed, whereas `config.whateverelse.name` is still +allowed. + +.. the calculation was carried out by the requires, wich is not a goog idead + + Type constraints with the `multi` type + ---------------------------------------- + + By convention, if a multi option has somme requires, the constraints on + the multi type is in all the OptionGroup (a group has to be `multi`, and + a multi of the same length). + + See :api:`test_option_consistency.test_multi_constraints()` + diff --git a/src/doc/eole-report/eolreport/D01AccesVariables.txt b/src/doc/eole-report/eolreport/D01AccesVariables.txt new file mode 100644 index 0000000..af6f19f --- /dev/null +++ b/src/doc/eole-report/eolreport/D01AccesVariables.txt @@ -0,0 +1,82 @@ +.. default-role:: literal + +.. include:: inc/preambule.txt + +Accès aux variables +==================== + +Protocole d'accès aux valeurs +------------------------------- + +**Créole** + +- Si la variable n'a pas été déclarée, une erreur est levée +- Si la variable a été déclarée, mais qu'aucune valeur n'a été définie, (ni valeur affectée, ni valeur par défaut) la valeur retournée est `[]` ou `""` ou `[""]` ou `["",""]`, +- Si la variable a été déclarée et qu'une valeur par défaut a été définie, la valeur retournée et la valeur par défaut, +- Si la variable a été déclarée et qu'une valeur a été définie, la valeur retournée est la valeur de la variable. + +**tiramisu** + +- Si la variable n'a pas été déclarée, une erreur est levée +- Si la variable a été déclarée, mais qu'aucune valeur n'a été définie, (ni valeur affectée, ni valeur par défaut) la valeur retournée est `None`, +- Si la variable a été déclarée et qu'une valeur par défaut a été définie, la valeur retournée et la valeur par défaut, +- Si la variable a été déclarée et qu'une valeur a été définie, la valeur retournée est la valeur de la variable. + +la différence tient au fait de la valeur nulle (`None`) qui a été mal définie +dès le début dans `Créole`. + +Accès Créole par "dictionnaire" +-------------------------------- + +La définition est dans le `XML` + +:: + + + + + +Le dictionnaire est chargé dans un `EoleDict()` + +:: + + from creole.cfgparser import EoleDict + eoldict = EoleDict(...) + +Un export dans un dictionnaire est necessaire pour manipuler les données + +:: + + from creole.parsedico import parse_dico + + flatdict = parse_dico(eoldict) + + assert dico['ip'] == '10.10.1.11' + + +le resultat de l'accès aux données vient de `typeole.EoleVar('ip').get_value()` + + +Accès `tiramisu` par espace de nommage +---------------------------------------- + + +- espaces de nommages ; +- c'est la configuration qui est responsable de l'accès aux valeurs ; +- une configuration par accès direct (pas d'export) ; +- un point d'entrée unique aisément manipulable grâce aux espaces de nommage. + +:: + + from tiramisu.config import Config + from tiramisu.option import OptionDescription + subdescr = OptionDescription("creole", [IPOption('ip')]) + descr = OptionDescription("creole", [subdescr]) + config = Config(descr) + assert config.creole.general.ip == '10.10.1.11' + +Les valeurs sont dépendantes **de la configuration** et donc la responsabilité +des valeurs dépend de la configuration et pas de la variable elle-même. + + + diff --git a/src/doc/eole-report/eolreport/D02CoherenceVariables.txt b/src/doc/eole-report/eolreport/D02CoherenceVariables.txt new file mode 100644 index 0000000..fa37aaf --- /dev/null +++ b/src/doc/eole-report/eolreport/D02CoherenceVariables.txt @@ -0,0 +1,109 @@ +.. default-role:: literal + +.. include:: inc/preambule.txt + +Cohérence des valeurs des variables +==================================== + +type des variables +------------------- + +**Créole** + +pas d'unicité du type abstrait : `Multivar`, `CreoleVar` et `TypedVar` + +- `String` +- `Ip` +- `Netmask` +- `Number` +- `Boolean` +- `OuiNon` + +**tiramisu** + +unicité du type abstrait : `Option()` + +pas de nouveau type multivalué, mais un attribut des types existants:: + + >>> from option import BoolOption + >>> boolopt = BoolOption('bool', 'description de bool', multi=True) + +tous les types Créole, plus + +- `SymlinkOption` +- `CheckOption` qui permet de définir les "oui/non", "On/Off" + +Validations suivant l'organisation en familles +----------------------------------------------- + +**Créole** + +**Organisation par accumulation de références sur des dictionnaires (`EoleDict`)** + +On peut charger un EoleDict avec des variables qui pointent vers des families +qui n'existent pas, aucune validation n'est faite (confiance absolument faite au +moment du chargemzent du XML) + +exemple, dans l'espace de nommage racine:: + + + + + +:: + + from creole.parsedico import parse_dico + flatdict = parse_dico(eoldict) + dico['adresse_ip_eth0'] + KeyError: 'adresse_ip_eth0' + +**Tiramisu** + +**Organisation par arborescence.** + +Un espace de nommage doit systématiquement être défini, la variable n'est +accessible **que** par un path. + + +Variables présentes deux fois +------------------------------- + +- Créole : pas de validation possible +- tiramisu : comportement règlable (on autorise l'unicité ou pas) + +- dans Créole les valeurs sont **fausses** (c'est la dernière variable qui qui gagne) + +Il faut faire confiance au XML + +:: + + + + toto + + + + + tutu + + +dans `gen_config` la valeur retenue est:: + + general/adresse_ip_eth0 -> tutu + services/adresse_ip_eth0 -> tutu + +dans `parsedico`, la variable est écrasée:: + + >>> from creole.parsedico import parse_dico + >>> d = parse_dico() + >>> d['adresse_ip_eth0'] + tutu + +dans tiramisu:: + + >>> config.general.adresse_ip_eth0 + toto + >>> config.services.adresse_ip_eth0 + tutu + + diff --git a/src/doc/eole-report/eolreport/D03ReglesEtats.txt b/src/doc/eole-report/eolreport/D03ReglesEtats.txt new file mode 100644 index 0000000..70705f5 --- /dev/null +++ b/src/doc/eole-report/eolreport/D03ReglesEtats.txt @@ -0,0 +1,113 @@ +.. default-role:: literal + +.. include:: inc/preambule.txt + +Etats et statuts des options de configuration +================================================ + +état des variables et lisibilité de l'API +------------------------------------------- + +**Creole** + +`EoleVar()` + +- `get_value()` +- `get_final_value()` +- `get_final_value_at_index()` +- `check_value()` +- `get_prec_value()` +- `get_calculated_value()` -> automatique + +**tiramisu** + +`Option()` + +- **aucune API** d'accès à la valeur d'une option au niveau de l'option de configuration +- `option.getdefault()` +- `option.setoption(config, value, owner)` + +variables "automatiques" +------------------------------ + +si `owner` == 'auto', la variable est automatique et la configuration le sait, +elle lance alors les fonctions de calcul à chaque évaluation + +dans Créole, c'est validé aux niveau de la variable par un appel à `eval_func()` + +Accès suivant les états de la configuration +-------------------------------------------- + +- disabled +- hidden +- mode (normal/expert) +- obligatoire (mandatory) +- ... + +- `EoleVar.hidden` +- `EoleVar.disabled` + +pas d'objet `Family` dans Créole donc l'organisation des hiérarchie de +hidden est opaque + +- `EoleDict.families['hidden']` pour avoir accès à l'état d'une famille + +dans Tiramisu + +- `hidden` au niveau `Option`, `OptionDescription` et **aussi** au niveau de + la configuration ce qui permet d'avoir des états (inexistant dans `Créole`) + +.. maitres/esclaves avec Créole : `mavar.get_slaves()` + + +`hidden_if_in`, `hidden_if_not_in` +------------------------------------- + +La notion est généralisée dans tiramisu avec les `requires`. + +Dans Créole : très difficile de conserver une cohérence des `hidden_if_in` +quand il y en a plusieurs. + +Dans Tiramisu : validation et levée d'exception si les **requirements** sont +incohérents, action inverse si aucun requires n'est matché. + +exemple de requires + +:: + + + + + + non + + + oui + + + non + activer_clam + + + + non + activer_clam + + +:résultat: `activer_clam` est visible, c'est la dernière condition qui a raison + +avec tiramisu, `activer_clam` **dans les même conditions**, est cachée. + +:: + + >>> activer_clam = StrOption('activer_clam', 'activer clamav', + requires=[('activer_clam_exim', 'non', 'hide'), + ('activer_clam_samba', 'non', 'hide'),]) + >>> config.clamav.activer_clam_exim = 'non' + >>> config.clamav.activer_clam_samba = 'oui' + >>> config.clamav.activer_clam + >>> Traceback (most recent call last): + File "", line 1, in + HiddenOptionError("trying to access to a hidden option:activer_clam") + >>> + diff --git a/src/doc/eole-report/eolreport/Makefile b/src/doc/eole-report/eolreport/Makefile new file mode 100644 index 0000000..fbf5816 --- /dev/null +++ b/src/doc/eole-report/eolreport/Makefile @@ -0,0 +1,7 @@ + +%.odt: %.txt + rst2odt --create-links --custom-odt-footer="Page %p% de %P%" --endnotes-end-doc --no-generator --stylesheet=styles.odt $< $@ + +%.html: %.txt + rst2html --stylesheet ./build/style.css $< > ./build/$@ + diff --git a/src/doc/eole-report/eolreport/build/Makefile b/src/doc/eole-report/eolreport/build/Makefile new file mode 100644 index 0000000..cc5f93b --- /dev/null +++ b/src/doc/eole-report/eolreport/build/Makefile @@ -0,0 +1,6 @@ +.PHONY: clean +.SUFFIXES: + +clean: + rm -f *.html + rm -f api/*.html diff --git a/src/doc/eole-report/eolreport/build/default.css b/src/doc/eole-report/eolreport/build/default.css new file mode 100644 index 0000000..8625c0e --- /dev/null +++ b/src/doc/eole-report/eolreport/build/default.css @@ -0,0 +1,1080 @@ +body,body.editor,body.body { + font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif; + background: White; + color: Black; +} + +a, a.reference { + text-decoration: none; +} +a[href]:hover { text-decoration: underline; } + +img { + border: none; + vertical-align: middle; +} + +p, div.text { + text-align: left; + line-height: 1.5em; + margin: 0.5em 0em 0em 0em; +} + + + +p a:active { + color: Red; + background-color: transparent; +} + +p img { + border: 0; + margin: 0; +} + +img.inlinephoto { + padding: 0; + padding-right: 1em; + padding-top: 0.7em; + float: left; +} + +hr { + clear: both; + height: 1px; + color: #8CACBB; + background-color: transparent; +} + + +ul { + line-height: 1.5em; + /*list-style-image: url("bullet.gif"); */ + margin-left: 1.5em; + padding:0; +} + +ol { + line-height: 1.5em; + margin-left: 1.5em; + padding:0; +} + +ul a, ol a { + text-decoration: underline; +} + +dl { +} + +dt { + font-weight: bold; +} + +dd { + line-height: 1.5em; + margin-bottom: 1em; +} + +blockquote { + font-family: Times, "Times New Roman", serif; + font-style: italic; + font-size: 120%; +} + +code { + color: Black; + /*background-color: #dee7ec;*/ + background-color: #cccccc; +} + +pre { + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; + overflow: auto; +} + + +.netscape4 { + display: none; +} + +/* main page styles */ + +/*a[href]:hover { color: black; text-decoration: underline; } +a[href]:link { color: black; text-decoration: underline; } +a[href] { color: black; text-decoration: underline; } +*/ + +span.menu_selected { + color: black; + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; + background-color: #cccccc; +} + + +a.menu { + /*color: #3ba6ec; */ + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; +} + +a.menu[href]:visited, a.menu[href]:link{ + /*color: #3ba6ec; */ + font: 140% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; +} + +a.menu[href]:hover { + /*color: black;*/ +} + +div.project_title{ + /*border-spacing: 20px;*/ + font: 160% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: middle; + padding-bottom: 0.3em; +} + +a.wikicurrent { + font: 100% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: middle; +} + + +table.body { + border: 0; + /*padding: 0; + border-spacing: 0px; + border-collapse: separate; + */ +} + +td.page-header-left { + padding: 5px; + /*border-bottom: 1px solid #444444;*/ +} + +td.page-header-top { + padding: 0; + + /*border-bottom: 1px solid #444444;*/ +} + +td.sidebar { + padding: 1 0 0 1; +} + +td.sidebar p.classblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeee; +} + +td.sidebar p.userblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeff; +} + +td.content { + padding: 1 5 1 5; + vertical-align: top; + width: 100%; +} + +p.ok-message { + background-color: #22bb22; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +p.error-message { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} + +p:first-child { + margin: 0 ; + padding: 0; +} + +/* style for forms */ +table.form { + padding: 2; + border-spacing: 0px; + border-collapse: separate; +} + +table.form th { + color: #333388; + text-align: right; + vertical-align: top; + font-weight: normal; +} +table.form th.header { + font-weight: bold; + background-color: #eeeeff; + text-align: left; +} + +table.form th.required { + font-weight: bold; +} + +table.form td { + color: #333333; + empty-cells: show; + vertical-align: top; +} + +table.form td.optional { + font-weight: bold; + font-style: italic; +} + +table.form td.html { + color: #777777; +} + +/* style for lists */ +table.list { + border-spacing: 0px; + border-collapse: separate; + vertical-align: top; + padding-top: 0; + width: 100%; +} + +table.list th { + padding: 0 4 0 4; + color: #404070; + background-color: #eeeeff; + border-right: 1px solid #404070; + border-top: 1px solid #404070; + border-bottom: 1px solid #404070; + vertical-align: top; + empty-cells: show; +} +table.list th a[href]:hover { color: #404070 } +table.list th a[href]:link { color: #404070 } +table.list th a[href] { color: #404070 } +table.list th.group { + background-color: #f4f4ff; + text-align: center; + font-size: 120%; +} + +table.list td { + padding: 0 4 0 4; + border: 0 2 0 2; + border-right: 1px solid #404070; + color: #404070; + background-color: white; + vertical-align: top; + empty-cells: show; +} + +table.list tr.normal td { + background-color: white; + white-space: nowrap; +} + +table.list tr.alt td { + background-color: #efefef; + white-space: nowrap; +} + +table.list td:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list th:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list tr.navigation th { + text-align: right; +} +table.list tr.navigation th:first-child { + border-right: none; + text-align: left; +} + + +/* style for message displays */ +table.messages { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.messages th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.messages th { + font-weight: bold; + color: black; + text-align: left; + border-bottom: 1px solid #afafaf; +} + +table.messages td { + font-family: monospace; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + color: black; + empty-cells: show; + border-right: 1px solid #afafaf; + vertical-align: top; + padding: 2 5 2 5; +} + +table.messages td:first-child { + border-left: 1px solid #afafaf; + border-right: 1px solid #afafaf; +} + +/* style for file displays */ +table.files { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.files th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.files th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +table.files td { + font-family: monospace; + empty-cells: show; +} + +/* style for history displays */ +table.history { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.history th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; + font-size: 100%; +} + +table.history th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; + font-size: 90%; +} + +table.history td { + font-size: 90%; + vertical-align: top; + empty-cells: show; +} + + +/* style for class list */ +table.classlist { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classlist th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.classlist th { + font-weight: bold; + text-align: left; +} + + +/* style for class help display */ +table.classhelp { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classhelp th { + font-weight: bold; + text-align: left; + color: #707040; +} + +table.classhelp td { + padding: 2 2 2 2; + border: 1px solid black; + text-align: left; + vertical-align: top; + empty-cells: show; +} + + +/* style for "other" displays */ +table.otherinfo { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.otherinfo th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.otherinfo th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +input { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + +select { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + + +a.nonexistent { + color: #FF2222; +} +a.nonexistent:visited { + color: #FF2222; +} +a.external { + color: #AA6600; +} + +/* +dl,ul,ol { + margin-top: 1pt; +} +tt,pre { + font-family: Lucida Console,Courier New,Courier,monotype; + font-size: 12pt; +} +pre.code { + margin-top: 8pt; + margin-bottom: 8pt; + background-color: #FFFFEE; + white-space:pre; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#111111; + padding:5px; + width:100%; +} +*/ +div.diffold { + background-color: #FFFF80; + border-style:none; + border-width:thin; + width:100%; +} +div.diffnew { + background-color: #80FF80; + border-style:none; + border-width:thin; + width:100%; +} +div.message { + margin-top: 6pt; + background-color: #E8FFE8; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#440000; + padding:5px; + width:100%; +} +strong.highlight { + background-color: #FFBBBB; +/* as usual, NetScape fucks up with innocent CSS + border-color: #FFAAAA; + border-style: solid; + border-width: 1pt; +*/ +} + +table.navibar { + background-color: #C8C8C8; + border-spacing: 3px; +} +td.navibar { + background-color: #E8E8E8; + vertical-align: top; + text-align: right; + padding: 0px; +} + +div.pagename { + font-size: 140%; + color: blue; + text-align: center; + font-weight: bold; + background-color: white; + padding: 0 ; +} + +a.wikiaction, input.wikiaction { + color: black; + text-decoration: None; + text-align: center; + color: black; + /*border: 1px solid #3ba6ec; */ + margin: 4px; + padding: 5; + padding-bottom: 0; + white-space: nowrap; +} + +a.wikiaction[href]:hover { + color: black; + text-decoration: none; + /*background-color: #dddddd; */ +} + +span.wikiuserpref { + padding-top: 1em; + font-size: 120%; +} + +div.wikitrail { + vertical-align: bottom; + /*font-size: -1;*/ + padding-top: 1em; + display: none; +} + +div.wikiaction { + vertical-align: middle; + /*border-bottom: 1px solid #8cacbb;*/ + padding-bottom:1em; + text-align: left; + width: 100%; +} + +div.wikieditmenu { + text-align: right; +} + +form.wikiedit { + border: 1px solid #8cacbb; + background-color: #f0f0f0; + background-color: #fabf00; + padding: 1em; + padding-right: 0em; +} + +div.legenditem { + padding-top: 0.5em; + padding-left: 0.3em; +} + +span.wikitoken { + background-color: #eeeeee; +} + + +div#contentspace h1:first-child, div.heading:first-child { + padding-top: 0; + margin-top: 0; +} +div#contentspace h2:first-child { + padding-top: 0; + margin-top: 0; +} + +/* heading and paragraph text */ + +div.heading, h1 { + font-family: Verdana, Helvetica, Arial, sans-serif; + background-color: #58b3ef; + background-color: #FFFFFF; + /*color: #4893cf;*/ + color: black; + padding-top: 1.0em; + padding-bottom:0.2em; + text-align: left; + margin-top: 0em; + /*margin-bottom:8pt;*/ + font-weight: bold; + font-size: 115%; + border-bottom: 1px solid #8CACBB; +} + + +h1, h2, h3, h4, h5, h6 { + color: orange; + clear: left; + font: 100% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 1em; + padding-bottom: 0.2em; + /*border-bottom: 1px solid #8CACBB;*/ +} +/* h1,h2 { padding-top: 0; }*/ + + +h1 { font-size: 145%; } +h2 { font-size: 135%; } +h3 { font-size: 125%; } +h4 { font-size: 120%; } +h5 { font-size: 110%; } +h6 { font-size: 80%; } + +h1 a { text-decoration: None;} + +div.exception { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +pre.exception { + font-size: 110%; + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; +} + +/* defines for navgiation bar (documentation) */ + + +div.direntry { + padding-top: 0.3em; + padding-bottom: 0.3em; + margin-right: 1em; + font-weight: bold; + background-color: #dee7ec; + font-size: 110%; +} + +div.fileentry { + font-family: Verdana, Helvetica, Arial, sans-serif; + padding-bottom: 0.3em; + white-space: nowrap; + line-height: 150%; +} + +a.fileentry { + white-space: nowrap; +} + + +span.left { + text-align: left; +} +span.right { + text-align: right; +} + +div.navbar { + /*margin: 0;*/ + font-size: 80% /*smaller*/; + font-weight: bold; + text-align: left; + /* position: fixed; */ + top: 100pt; + left: 0pt; /* auto; */ + width: 120pt; + /* right: auto; + right: 0pt; 2em; */ +} + + +div.history a { + /* font-size: 70%; */ +} + +div.wikiactiontitle { + font-weight: bold; +} + +/* REST defines */ + +div.document { + margin: 0; +} + +h1.title { + margin: 0; + margin-bottom: 0.5em; +} + +td.toplist { + vertical-align: top; +} + +img#pyimg { + position: absolute; + top: 4px; + left: 4px; +} + +div#navspace { + position: absolute; + top: 130px; + left: 11px; + font-size: 100%; + width: 150px; + overflow: hidden; /* scroll; */ +} + +div#metaspace { + position: absolute; + top: 40px; + left: 170px; +} + +div#errorline { + position: relative; + top: 5px; + float: right; +} + +div#contentspace { + position: absolute; + /* font: 120% "Times New Roman", serif;*/ + font: 110% Verdana, Helvetica, Arial, sans-serif; + top: 130px; + left: 170px; + margin-right: 5px; +} + +div#menubar { +/* width: 400px; */ + float: left; +} + +/* for the documentation page */ +div#docinfoline { + position: relative; + top: 5px; + left: 0px; + + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 1em; + color: black; + /*border-width: 1pt; + border-style: solid;*/ + +} + +div#docnavlist { + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 2em; + color: black; + border-width: 1pt; + /*border-style: solid;*/ +} + + +/* text markup */ + +div.listtitle { + color: Black; + clear: left; + font: 120% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 0em; + padding-bottom: 0.2em; + margin-right: 0.5em; + border-bottom: 1px solid #8CACBB; +} + +div.actionbox h3 { + padding-top: 0; + padding-right: 0.5em; + padding-left: 0.5em; + background-color: #fabf00; + text-align: center; + border: 1px solid black; /* 8cacbb; */ +} + +div.actionbox a { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; +} + +div.actionbox a.history { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; + font-size: 90%; +} + +div.actionbox { + margin-bottom: 2em; + padding-bottom: 1em; + overflow: hidden; /* scroll; */ +} + +/* taken from docutils (oh dear, a bit senseless) */ +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + + +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date: 2003/01/22 22:26:48 $ +:version: $Revision: 1.29 $ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. +*/ +/* +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.title { + text-align: center ; + color: orange} + +h2.subtitle { + color: orange; + text-align: center } + +hr { + width: 75% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } + +tt { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } +*/ + +div.section { + margin-top: 1.0em ; +} diff --git a/src/doc/eole-report/eolreport/build/docutils.css b/src/doc/eole-report/eolreport/build/docutils.css new file mode 100644 index 0000000..f03e03d --- /dev/null +++ b/src/doc/eole-report/eolreport/build/docutils.css @@ -0,0 +1,255 @@ +.first { + margin-top: 0 ! important } + +.last { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +a.toc-backref { + text-decoration: none ; + color: inherit } + +blockquote.epigraph { + margin: 2em 5em } + +dl.docutils dd { + margin-bottom: 0.5em } + +dl.docutils dt { + font-weight: bold } + +dl dt { line-height: 150% } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.document { + width: 600px ; + margin-left: 5em ; + margin-right: 5em } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1, h2, h3, h4, h5 { + font-family: sans-serif ; + line-height: 150% ; + color: orange} /* #666 } */ + +h1.title { + text-align: center + } +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + font-size: small ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table.citation { + border-left: solid thin gray } + +table.docinfo { + /* float: right ; */ + margin: 2em 4em ; + color: #666 } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid thin black } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: right ; + white-space: nowrap } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +tt.docutils { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } + diff --git a/src/doc/eole-report/eolreport/build/imgs/eol.png b/src/doc/eole-report/eolreport/build/imgs/eol.png new file mode 100644 index 0000000..5b23138 Binary files /dev/null and b/src/doc/eole-report/eolreport/build/imgs/eol.png differ diff --git a/src/doc/eole-report/eolreport/build/imgs/logo.png b/src/doc/eole-report/eolreport/build/imgs/logo.png new file mode 100644 index 0000000..9c554f4 Binary files /dev/null and b/src/doc/eole-report/eolreport/build/imgs/logo.png differ diff --git a/src/doc/eole-report/eolreport/build/index-report.html b/src/doc/eole-report/eolreport/build/index-report.html new file mode 100644 index 0000000..a0597f8 --- /dev/null +++ b/src/doc/eole-report/eolreport/build/index-report.html @@ -0,0 +1,76 @@ + + + + + + +rapports eole + + + +
+ + +imgs/eol.png + +++ + + + + + +
date:mai 2012
description:rapports Créole, compatibilités Creole et tiramisu
+
+

Vue d'ensemble des rapports

+

Les rapports ci-dessous résument et permettent de donner des points d'appui à +des discussions de recherche et développement concernant l'évolution du +projet Creole (comprenant Creole_Serv). Il y a aussi le support de +documentation développeur tiramisu (en anglais) qui constitue une bonne +base pour connaître et comprendre plus en détails les motivations de +la nouvelle implementation.

+ +
+
+ + diff --git a/src/doc/eole-report/eolreport/build/pdfreport/D01AccesVariables.pdf b/src/doc/eole-report/eolreport/build/pdfreport/D01AccesVariables.pdf new file mode 100644 index 0000000..471a375 Binary files /dev/null and b/src/doc/eole-report/eolreport/build/pdfreport/D01AccesVariables.pdf differ diff --git a/src/doc/eole-report/eolreport/build/pdfreport/D02CoherenceVariables.pdf b/src/doc/eole-report/eolreport/build/pdfreport/D02CoherenceVariables.pdf new file mode 100644 index 0000000..d8c37fe Binary files /dev/null and b/src/doc/eole-report/eolreport/build/pdfreport/D02CoherenceVariables.pdf differ diff --git a/src/doc/eole-report/eolreport/build/pdfreport/D03ReglesEtats.pdf b/src/doc/eole-report/eolreport/build/pdfreport/D03ReglesEtats.pdf new file mode 100644 index 0000000..7ec977c Binary files /dev/null and b/src/doc/eole-report/eolreport/build/pdfreport/D03ReglesEtats.pdf differ diff --git a/src/doc/eole-report/eolreport/build/pdfreport/make_index b/src/doc/eole-report/eolreport/build/pdfreport/make_index new file mode 100755 index 0000000..ca207c8 --- /dev/null +++ b/src/doc/eole-report/eolreport/build/pdfreport/make_index @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import sys +from glob import glob +from os.path import isfile, dirname, abspath, join, basename, splitext +from rst import Rest, Paragraph, Strong, ListItem, Link + + +here = abspath(dirname(__file__)) +html = glob(join(here, '*.pdf')) + +basehtml = [basename(htm) for htm in html] +basehtml.sort() + +content = Rest() + +for htm in basehtml: + link = Link( htm , "pdfreport/" +htm) + content.add(ListItem(link)) + +sys.stdout.write(content.text()) + + diff --git a/src/doc/eole-report/eolreport/build/pdfreport/rst.py b/src/doc/eole-report/eolreport/build/pdfreport/rst.py new file mode 100644 index 0000000..7548cdd --- /dev/null +++ b/src/doc/eole-report/eolreport/build/pdfreport/rst.py @@ -0,0 +1,410 @@ +# unproudly borrowed from pypy : +# http://codespeak.net/svn/pypy/trunk/pypy/tool/rest/rst.py +""" reStructuredText generation tools + + provides an api to build a tree from nodes, which can be converted to + ReStructuredText on demand + + note that not all of ReST is supported, a usable subset is offered, but + certain features aren't supported, and also certain details (like how links + are generated, or how escaping is done) can not be controlled +""" + +import re + +def escape(txt): + """escape ReST markup""" + if not isinstance(txt, str) and not isinstance(txt, unicode): + txt = str(txt) + # XXX this takes a very naive approach to escaping, but it seems to be + # sufficient... + for c in '\\*`|:_': + txt = txt.replace(c, '\\%s' % (c,)) + return txt + +class RestError(Exception): + """ raised on containment errors (wrong parent) """ + +class AbstractMetaclass(type): + def __new__(cls, *args): + obj = super(AbstractMetaclass, cls).__new__(cls, *args) + parent_cls = obj.parentclass + if parent_cls is None: + return obj + if not isinstance(parent_cls, list): + class_list = [parent_cls] + else: + class_list = parent_cls + if obj.allow_nesting: + class_list.append(obj) + + for _class in class_list: + if not _class.allowed_child: + _class.allowed_child = {obj:True} + else: + _class.allowed_child[obj] = True + return obj + +class AbstractNode(object): + """ Base class implementing rest generation + """ + sep = '' + __metaclass__ = AbstractMetaclass + parentclass = None # this exists to allow parent to know what + # children can exist + allow_nesting = False + allowed_child = {} + defaults = {} + + _reg_whitespace = re.compile('\s+') + + def __init__(self, *args, **kwargs): + self.parent = None + self.children = [] + for child in args: + self._add(child) + for arg in kwargs: + setattr(self, arg, kwargs[arg]) + + def join(self, *children): + """ add child nodes + + returns a reference to self + """ + for child in children: + self._add(child) + return self + + def add(self, child): + """ adds a child node + + returns a reference to the child + """ + self._add(child) + return child + + def _add(self, child): + if child.__class__ not in self.allowed_child: + raise RestError("%r cannot be child of %r" % \ + (child.__class__, self.__class__)) + self.children.append(child) + child.parent = self + + def __getitem__(self, item): + return self.children[item] + + def __setitem__(self, item, value): + self.children[item] = value + + def text(self): + """ return a ReST string representation of the node """ + return self.sep.join([child.text() for child in self.children]) + + def wordlist(self): + """ return a list of ReST strings for this node and its children """ + return [self.text()] + +class Rest(AbstractNode): + """ Root node of a document """ + + sep = "\n\n" + def __init__(self, *args, **kwargs): + AbstractNode.__init__(self, *args, **kwargs) + self.links = {} + + def render_links(self, check=False): + """render the link attachments of the document""" + assert not check, "Link checking not implemented" + if not self.links: + return "" + link_texts = [] + # XXX this could check for duplicates and remove them... + for link, target in self.links.iteritems(): + link_texts.append(".. _`%s`: %s" % (escape(link), target)) + return "\n" + "\n".join(link_texts) + "\n\n" + + def text(self): + outcome = [] + if (isinstance(self.children[0], Transition) or + isinstance(self.children[-1], Transition)): + raise ValueError, ('document must not begin or end with a ' + 'transition') + for child in self.children: + outcome.append(child.text()) + + # always a trailing newline + text = self.sep.join([i for i in outcome if i]) + "\n" + return text + self.render_links() + +class Transition(AbstractNode): + """ a horizontal line """ + parentclass = Rest + + def __init__(self, char='-', width=80, *args, **kwargs): + self.char = char + self.width = width + super(Transition, self).__init__(*args, **kwargs) + + def text(self): + return (self.width - 1) * self.char + +class Paragraph(AbstractNode): + """ simple paragraph """ + + parentclass = Rest + sep = " " + indent = "" + # FIXME + width = 880 + + def __init__(self, *args, **kwargs): + # make shortcut + args = list(args) + for num, arg in enumerate(args): + if isinstance(arg, str): + args[num] = Text(arg) + super(Paragraph, self).__init__(*args, **kwargs) + + def text(self): + texts = [] + for child in self.children: + texts += child.wordlist() + + buf = [] + outcome = [] + lgt = len(self.indent) + + def grab(buf): + outcome.append(self.indent + self.sep.join(buf)) + + texts.reverse() + while texts: + next = texts[-1] + if not next: + texts.pop() + continue + if lgt + len(self.sep) + len(next) <= self.width or not buf: + buf.append(next) + lgt += len(next) + len(self.sep) + texts.pop() + else: + grab(buf) + lgt = len(self.indent) + buf = [] + grab(buf) + return "\n".join(outcome) + +class SubParagraph(Paragraph): + """ indented sub paragraph """ + + indent = " " + +class Title(Paragraph): + """ title element """ + + parentclass = Rest + belowchar = "=" + abovechar = "" + + def text(self): + txt = self._get_text() + lines = [] + if self.abovechar: + lines.append(self.abovechar * len(txt)) + lines.append(txt) + if self.belowchar: + lines.append(self.belowchar * len(txt)) + return "\n".join(lines) + + def _get_text(self): + txt = [] + for node in self.children: + txt += node.wordlist() + return ' '.join(txt) + +class AbstractText(AbstractNode): + parentclass = [Paragraph, Title] + start = "" + end = "" + def __init__(self, _text): + self._text = _text + + def text(self): + text = self.escape(self._text) + return self.start + text + self.end + + def escape(self, text): + if not isinstance(text, str) and not isinstance(text, unicode): + text = str(text) + if self.start: + text = text.replace(self.start, '\\%s' % (self.start,)) + if self.end and self.end != self.start: + text = text.replace(self.end, '\\%s' % (self.end,)) + return text + +class Text(AbstractText): + def wordlist(self): + text = escape(self._text) + return self._reg_whitespace.split(text) + +class LiteralBlock(AbstractText): + parentclass = Rest + start = '::\n\n' + + def text(self): + if not self._text.strip(): + return '' + text = self.escape(self._text).split('\n') + for i, line in enumerate(text): + if line.strip(): + text[i] = ' %s' % (line,) + return self.start + '\n'.join(text) + +class Em(AbstractText): + start = "*" + end = "*" + +class Strong(AbstractText): + start = "**" + end = "**" + +class Quote(AbstractText): + start = '``' + end = '``' + +class Anchor(AbstractText): + start = '_`' + end = '`' + +class Footnote(AbstractText): + def __init__(self, note, symbol=False): + raise NotImplemented('XXX') + +class Citation(AbstractText): + def __init__(self, text, cite): + raise NotImplemented('XXX') + +class ListItem(Paragraph): + allow_nesting = True + item_chars = '*+-' + + def text(self): + idepth = self.get_indent_depth() + indent = self.indent + (idepth + 1) * ' ' + txt = '\n\n'.join(self.render_children(indent)) + ret = [] + item_char = self.item_chars[idepth] + ret += [indent[len(item_char)+1:], item_char, ' ', txt[len(indent):]] + return ''.join(ret) + + def render_children(self, indent): + txt = [] + buffer = [] + def render_buffer(fro, to): + if not fro: + return + p = Paragraph(indent=indent, *fro) + p.parent = self.parent + to.append(p.text()) + for child in self.children: + if isinstance(child, AbstractText): + buffer.append(child) + else: + if buffer: + render_buffer(buffer, txt) + buffer = [] + txt.append(child.text()) + + render_buffer(buffer, txt) + return txt + + def get_indent_depth(self): + depth = 0 + current = self + while (current.parent is not None and + isinstance(current.parent, ListItem)): + depth += 1 + current = current.parent + return depth + +class OrderedListItem(ListItem): + item_chars = ["#."] * 5 + +class DListItem(ListItem): + item_chars = None + def __init__(self, term, definition, *args, **kwargs): + self.term = term + super(DListItem, self).__init__(definition, *args, **kwargs) + + def text(self): + idepth = self.get_indent_depth() + indent = self.indent + (idepth + 1) * ' ' + txt = '\n\n'.join(self.render_children(indent)) + ret = [] + ret += [indent[2:], self.term, '\n', txt] + return ''.join(ret) + +class Link(AbstractText): + start = '`' + end = '`_' + + def __init__(self, _text, target): + self._text = _text + self.target = target + self.rest = None + + def text(self): + if self.rest is None: + self.rest = self.find_rest() + if self.rest.links.get(self._text, self.target) != self.target: + raise ValueError('link name %r already in use for a different ' + 'target' % (self.target,)) + self.rest.links[self._text] = self.target + return AbstractText.text(self) + + def find_rest(self): + # XXX little overkill, but who cares... + next = self + while next.parent is not None: + next = next.parent + return next + +class InternalLink(AbstractText): + start = '`' + end = '`_' + +class LinkTarget(Paragraph): + def __init__(self, name, target): + self.name = name + self.target = target + + def text(self): + return ".. _`%s`:%s\n" % (self.name, self.target) + +class Substitution(AbstractText): + def __init__(self, text, **kwargs): + raise NotImplemented('XXX') + +class Directive(Paragraph): + indent = ' ' + def __init__(self, name, *args, **options): + self.name = name + self.content = args + super(Directive, self).__init__() + self.options = options + + def text(self): + # XXX not very pretty... + txt = '.. %s::' % (self.name,) + options = '\n'.join([' :%s: %s' % (k, v) for (k, v) in + self.options.iteritems()]) + if options: + txt += '\n%s' % (options,) + + if self.content: + txt += '\n' + for item in self.content: + txt += '\n ' + item + + return txt + diff --git a/src/doc/eole-report/eolreport/build/style.css b/src/doc/eole-report/eolreport/build/style.css new file mode 100644 index 0000000..28c256e --- /dev/null +++ b/src/doc/eole-report/eolreport/build/style.css @@ -0,0 +1,32 @@ +@import url(docutils.css); +@import url(default.css); +a:link { + color: orange; + font-weight: bold; + text-decoration: none; +} +a:visited { + text-decoration: none; + color: #999999; +} +a:hover { + text-decoration: none; + color: #999999; +} +a:active { + text-decoration: none; + color: #999999; +} + +.header { + color: orange; + background-color: white; + padding: 1em; +} +.footer { + color: #666; + background-color: inherit; + font-size: 75%; +} + + diff --git a/src/doc/eole-report/eolreport/inc/00-Redacteur.txt b/src/doc/eole-report/eolreport/inc/00-Redacteur.txt new file mode 100644 index 0000000..554e81b --- /dev/null +++ b/src/doc/eole-report/eolreport/inc/00-Redacteur.txt @@ -0,0 +1,12 @@ +.. container:: rubric + + **Rédacteurs** + + | Gwenaël Rémond (gremond@cadoles.com) + | Emmanuel Garette (egarette@cadoles.com) + +**Référence** + + | ``tiramisu/doc/eole-reports`` + | ``git clone ssh://gitosis@git.cadol.es:2222/tiramisu.git`` + diff --git a/src/doc/eole-report/eolreport/inc/eol.png b/src/doc/eole-report/eolreport/inc/eol.png new file mode 100644 index 0000000..5b23138 Binary files /dev/null and b/src/doc/eole-report/eolreport/inc/eol.png differ diff --git a/src/doc/eole-report/eolreport/inc/logo.png b/src/doc/eole-report/eolreport/inc/logo.png new file mode 100644 index 0000000..9c554f4 Binary files /dev/null and b/src/doc/eole-report/eolreport/inc/logo.png differ diff --git a/src/doc/eole-report/eolreport/inc/menjva.gif b/src/doc/eole-report/eolreport/inc/menjva.gif new file mode 100644 index 0000000..49d17a6 Binary files /dev/null and b/src/doc/eole-report/eolreport/inc/menjva.gif differ diff --git a/src/doc/eole-report/eolreport/inc/preambule.txt b/src/doc/eole-report/eolreport/inc/preambule.txt new file mode 100644 index 0000000..c25bb90 --- /dev/null +++ b/src/doc/eole-report/eolreport/inc/preambule.txt @@ -0,0 +1,18 @@ +.. csv-table:: + + .. image:: inc/logo.png, .. image:: inc/eol.png + +.. container:: title + + Rapports de discussions de recherche et développements + +------------ + +.. container:: subtitle + + Comparaison ``tiramisu`` et ``Créole`` + +.. include:: 00-Redacteur.txt + + + diff --git a/src/doc/eole-report/eolreport/index-report.txt b/src/doc/eole-report/eolreport/index-report.txt new file mode 100644 index 0000000..4670b94 --- /dev/null +++ b/src/doc/eole-report/eolreport/index-report.txt @@ -0,0 +1,33 @@ +.. default-role:: literal + +.. title:: rapports eole + + +.. image:: imgs/eol.png + :align: right + +:date: mai 2012 +:description: rapports `Créole`, compatibilités `Creole` et `tiramisu` + + +Vue d'ensemble des rapports +=================================== + +Les rapports ci-dessous résument et permettent de donner des points d'appui à +des discussions de recherche et développement concernant l'évolution du +projet `Creole` (comprenant `Creole_Serv`). Il y a aussi le support de +documentation développeur `tiramisu` (en anglais) qui constitue une bonne +base pour connaître et comprendre plus en détails les motivations de +la nouvelle implementation. + + +* `D01AccesVariables.pdf`_ + +* `D02CoherenceVariables.pdf`_ + +* `D03ReglesEtats.pdf`_ + +.. _`D03ReglesEtats.pdf`: pdfreport/D03ReglesEtats.pdf +.. _`D02CoherenceVariables.pdf`: pdfreport/D02CoherenceVariables.pdf +.. _`D01AccesVariables.pdf`: pdfreport/D01AccesVariables.pdf + diff --git a/src/doc/eole-report/eolreport/styles.odt b/src/doc/eole-report/eolreport/styles.odt new file mode 100644 index 0000000..2121251 Binary files /dev/null and b/src/doc/eole-report/eolreport/styles.odt differ diff --git a/src/doc/eole-report/presentation/Makefile b/src/doc/eole-report/presentation/Makefile new file mode 100644 index 0000000..7b32a56 --- /dev/null +++ b/src/doc/eole-report/presentation/Makefile @@ -0,0 +1,12 @@ +SRC=$(wildcard *.tex) +OBJ=$(subst .tex,.pdf,$(SRC)) + +pdf: $(OBJ) + +%.pdf: %.tex + pdflatex $< + +clean: + rm -f $(OBJ) + rm -f *.aux *.log *.toc *.snm *.out *.nav + diff --git a/src/doc/eole-report/presentation/definition.tex b/src/doc/eole-report/presentation/definition.tex new file mode 100644 index 0000000..4bbea9f --- /dev/null +++ b/src/doc/eole-report/presentation/definition.tex @@ -0,0 +1,69 @@ +\begin{frame} + \frametitle{Comparaison entre le noyau de Créole et Tiramisu} + \begin{itemize} + \item \emph{Tiramisu} a pour objectif de + \begin{itemize} + \item remplacer le noyau \emph{Creole} (\texttt{EoleDict}) de manière transparente ; + \item résoudre les problèmes inhérents à \texttt{CreoleServ} ; + \end{itemize} + \item au niveau du code, il y a enfin une vraie séparation du c\oe ur et du fonctionnel ; + \item valide le type \emph{et la structure}, l'ajout de types est aisé. + \item \emph{Creole} : \texttt{EoleDict, EoleVars} $ \Leftrightarrow $ \texttt{Config, Option}\\ + cf \texttt{tiramisu/doc/build/pydoc/index.html} + \item intégré à \texttt{gen\_config}, \texttt{cheetah}, \texttt{DTD Creole}, syntaxe \texttt{Creole} \dots + \item \texttt{eole-report/D02CoherenceVariables.pdf} + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Gestionnaire de configuration existants} + \begin{itemize} + \item Le gestionnaire de conf de Victor Stinner $\Rightarrow$ \emph{NuFw}; + \item puppet, cfgengine... $\Rightarrow$ intéressant, de nombreux comportements peuvent être repris, mais tel quel difficilement compatible avec \emph{Creole}; + \item \emph{Creole} $\Leftrightarrow$ \texttt{tiramisu/doc/build/glossary.html} +\end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Un "vrai" serveur de config} + \begin{itemize} + \item un serveur de données de configuration ; + \item $1^{ere}$ méthode : exportation (snapshot) d'un état de la config $ \Rightarrow $ Créole ; + \item $2^{eme}$ méthode : JIT (just in time) calculation, une modification +de l'état de la configuration est possible \emph{pendant} la manipulation et l'utilisation de la conf $ \Rightarrow $ Tiramisu. + \item \texttt{doc/getting-started.html} + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Qu'est-ce qu'un gestionnaire de conf moderne ?} + \begin{itemize} + \item c'est une organisation arborescente des données (les données sont imbriquées) ; + \item c'est un accès facile aux données (typiquement une interface de type \emph{dictionnaire}) ; + \item clefs-valeurs, mais quelles valeurs exactement ? $ \Rightarrow $ calcul JIT (just in time) ; + \item \texttt{eole-report/D01AccesVariables.pdf} +\end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Définition d'un gestionnaire de configuration} + \begin{itemize} + \item les families, groups, master \dots~ ce sont des \emph{schémas} de données (\texttt{OptionDescription}) ; + \item c'est la configuration (\texttt{Config}) qui est responsable de l'accès aux valeurs ; + \item la configuration est aisément manipulable, et a un point d'entrée unique ; + \item l'accès aux valeurs des \texttt{Options} de configuration ne peut se faire \emph{que} depuis la conf racine. + \item \texttt{eole-report/D01AccesVariables.pdf} + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{Organisation en espace de nommage} + \begin{itemize} + \item dans \emph{tiramisu} l'accent est mis sur l'organisation arborescente des données ; + \item la validation des options de configuration se fait par l'appartenance aux groupes (families, master/slaves \dots) ; + \item l'organisation en groupes est unifiée par l'espace de nommage ; + \item \texttt{eole-report/D03ReglesEtats.pdf} + \item lisibilité d'une config : \texttt{tiramisu/report/build/index.html} rapport html d'une config + \end{itemize} +\end{frame} + diff --git a/src/doc/eole-report/presentation/statut.tex b/src/doc/eole-report/presentation/statut.tex new file mode 100644 index 0000000..1bee414 --- /dev/null +++ b/src/doc/eole-report/presentation/statut.tex @@ -0,0 +1,61 @@ + +\begin{frame} + \frametitle{Etats ("status") de la configuration} + \begin{itemize} + \item système d'états de la configuration par \emph{droits d'accès} ; + \item \texttt{read write}, \texttt{read only} ; + \item correspond à \texttt{freeze}, \texttt{hidden}, \texttt{disabled} \dots ; + \item \texttt{doc/status.html} ; + \item \texttt{eole-report/D03ReglesEtats.pdf} ; + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{hidden if in, hidden if not in} + \begin{itemize} + \item les hidden if in, disabled if, \dots sont généralisés + \item dans tiramisu, ce sont des pré-requis sur une (des) variables + \item \texttt{eole-report/D03ReglesEtats.pdf} + \item \texttt{doc/consistency.html} + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{un peu de mathématiques : prévenir les deadlocks} + \begin{itemize} +\item sûreté : prévention des deadlocks ; +\item dans tiramisu, le modèle est suffisamment abstrait pour que son exploitation mathématique soit +réalisable par les techniques de \emph{Model Checking} ; +\item soit on a besoin de ne connaître que l'ensemble des états, pas leurs liens $\Rightarrow$ espace d'états ; +\item soit on a besoin de connaître toutes les relations $\Rightarrow$ graphe d'accessibilité ; +\item la configuration est modélisable en une structure de \emph{Kripe} ; +\item déjà le parsing de la conf est facile, la preuve : \texttt{tiramisu/report/build/index.html} + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{un peu de mathématiques (suite) CreoleLint} + \begin{itemize} +\item exemple : $ P = 3 \wedge Q = 1 \triangleleft \langle P = 1 \hookleftarrow Q = 0 \rangle$ +\item la propriété \og dans aucun état on a $P = 3$ et $Q = 1$ \fg~ est-elle vraie ? +Pour vérifier cette propriété, on a besoin de connaître l'espace d'états ; +\item la propriété \og chaque chemin débutant dans un état accessible $P=1$ passe par un état où $Q=3$ et $P=2$ \fg~ +est-elle vraie ? Cela demande de connaître le graphe d'accessibilité ; +\item les structures de \emph{Kripe} sont des machines à états étiquetées par les valuations de toutes les variables propositionnelles ; +\item une compliation statique devient possible dans \emph{CreoleLint} \dots + \end{itemize} +\end{frame} + +\begin{frame} + \frametitle{compatibilité Créole : ce qui reste à faire} + \begin{itemize} +\item les options spéciales sont implémentées (auto, fill, obligatoire, \dots) reste la librairie des fonctions pour les variables automatiques \texttt{eosfunc} ; +\item tous les états sont implémentés (hidden, disabled, mode (normal/expert), \dots), il faut fixer les comportement \texttt{read write} ; +\item les "valprec" (valeur précédentes) et une mémoire de \emph{tous} les états antérieurs ; +\item fixer les comportement des hides (sous-groupes récursifs, \dots) ; +\item validations master/slaves, validations globales au regard de la configuration entière puisque c'est possible maintenant. +\end{itemize} + +\end{frame} + + diff --git a/src/doc/eole-report/presentation/tiramisu.tex b/src/doc/eole-report/presentation/tiramisu.tex new file mode 100644 index 0000000..a6067c9 --- /dev/null +++ b/src/doc/eole-report/presentation/tiramisu.tex @@ -0,0 +1,36 @@ +%%presentation +\documentclass{beamer} +\usepackage{beamerthemetree} +%%impression +%\documentclass[a4paper,9pt]{extarticle} +%\usepackage{beamerarticle} +%% + +% class FR +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[frenchb]{babel} + +% image +%% \usepackage{graphicx} +\usepackage{alltt} +\usecolortheme{crane} +\beamertemplatetransparentcovered +%\logo{\includegraphics[height=1cm]{ban.png}} + +\title{Tiramisu} +\subtitle{gestionnaire de configuration} +\author{Gwen} +\institute{\texttt{git clone git://git.labs.libre-entreprise.org/tiramisu.git} \\ +\texttt{firefox tiramisu/doc/build/index.html}} + +\date{\today} + +\begin{document} +\frame{\titlepage} + +\include{definition} +\include{statut} + +\end{document} + diff --git a/src/doc/epydoc.sh b/src/doc/epydoc.sh new file mode 100755 index 0000000..f83252f --- /dev/null +++ b/src/doc/epydoc.sh @@ -0,0 +1,3 @@ +epydoc --css grayscale -o ./build/pydoc ../*.py #config.py ../option.py +#apirst2html.py --stylesheet=docutils.css --external-api=epydoc --external-api-root=epydoc:./api/ --external-api-file=epydoc:./api/api-objects.txt doc.txt > doc.htm + diff --git a/src/doc/gaspacho.txt b/src/doc/gaspacho.txt new file mode 100644 index 0000000..457e3e9 --- /dev/null +++ b/src/doc/gaspacho.txt @@ -0,0 +1,70 @@ +- abstract values from `gaspacho` + + Les types possibles : + + - sans valeur : `boolean` + - avec valeur : `unicode` (un texte libre), `integer` (un chiffre), `enum` (une liste de choix prédéfinies) et `list` (une liste de choix libres). + + Les types sans valeurs sont les plus simples. Par exemple cette règle n’attend + aucune valeur particulière Vérifier que Firefox est le navigateur par défaut. + + Alors que celle-ci attend une adresse IP Configuration du serveur proxy manuelle. + + Il existe un autre type (multi) qui permet de mêler plusieurs types. + + Il s’agit bien de définir ici le type de la règle (et uniquement de la règle). + +- configuration levels in `creole` + + *thu, 28 april 2011* + + Exemple de niveau de configuration (dans l'ordre) : + + 1. - Coeur + + 2. + - Coeur + - gen_config + + 3. + - Coeur + - gen_config + - EAD + + 4. + - Coeur + - EAD + + 5. + - Coeur + - baculaconfig.py + + (`fill` : calcule une valeur jusqu'à ce que l'utilisateur change la + valeur) + + Gestion des ACL en écriture : + + Le coeur charge les variables + + - si auto : seul le coeur peut la modifier (cas 1) ; + + - si fill : le coeur calcule une valeur tant que pas configuré par + l'utilisateur. L'utilisateur peut modifier (cas 2 ou 3) ; + + - des variables modifiables que par gen_config (cas 2) ; + + - des variables modifiables par gen_config ou l'EAD (cas 3) ; + + - des variables d'autres applications (cas 4 et 5). + + Gestion des ACLs en lecture : + + - seule une application peut lire certaines variables (exemple un mot de + passe). + + + + + + + diff --git a/src/doc/getting-started.txt b/src/doc/getting-started.txt new file mode 100644 index 0000000..5e8a228 --- /dev/null +++ b/src/doc/getting-started.txt @@ -0,0 +1,67 @@ +================================== +`Tiramisu` - Getting Started +================================== + +What is Configuration handling ? +================================= + +Due to more and more available configuration options required to set up +an operating system, it became quite annoying to hand the necessary +options to where they are actually used and even more annoying to add +new options. To circumvent these problems the configuration management +was introduced. + +What is Tiramisu ? +=================== + +Tiramisu is yet another configuration handler, wich aims at producing +flexible and fast configuration options access. The main advantages are +its access :ref:`glossary#rules` and the fact that the configuration 's +consistency is preserved at any time, see :ref:`glossary#consistency`. + +There are type and structures's validations for configuration options, +and validations towards the whole configuration. + +Last but not least, configuration options can be reached and changed +according to the access rules from nearly everywhere in the OS boxes, +e.g. the containers via the `http/json` server. + +Just the facts +============== + +.. _gettingtiramisu: + +Download +--------- + +To obtain a copy of the sources, check it out from the repository using +`git`. We suggest using `git` if one wants to access the current development. + +:: + + git clone git://git.labs.libre-entreprise.org/tiramisu.git + +This will get you a fresh checkout of the code repository in a local +directory named ``tiramisu``. + +Understanding Tiramisu's architecture +-------------------------------------- + +The :ref:`glossary#schema` is loaded from an XML file, and the values of +the configuration options are recovered from a `.ini` like file. + +By now, all the in-depth informations about the configuration are stored +in a **single** object, the :api:`config.Config()` object, wich is +responsible of nearly everything. All the necessary options are stored +into a configuration object, which is available nearly everywhere, so +that adding new options becomes trivial. + +This `Config()` is available from everywhere with the help of an http server +that serves configuration datas as `json` strings. + +.. figure:: architecture.png + + The basics of Tiramisu's architecture. + Once loaded, http server serves the :api:`config.Config()` object, that is, + the configuration options and the configuration groups. + diff --git a/src/doc/glossary.txt b/src/doc/glossary.txt new file mode 100644 index 0000000..e041090 --- /dev/null +++ b/src/doc/glossary.txt @@ -0,0 +1,97 @@ +.. default-role:: literal + +glossary +========== + +.. _configuration: + +**configuration** + + Global configuration object, wich contains the whole configuration + options *and* their descriptions (option types and group) + +.. _`option description`: +.. _`schema`: + +**schema**: +**option description** + + see :api:`option.OptionDescription`, see :ref:`optionapi#schema` + + The schema of a configuration : + + - the option types + + - how they are organised in groups or even subgroups, that's why we + call them **groups** too. + +.. _`configoption`: + +**configuration option** + + An option object wich has a name and a value and can be accessed + from the configuration object + +.. _`defaultvalue`: + +**default value** + + Default value of a configuration option. The default value can be + set at instanciation time, or even at any moment. Remember that if + you reset the default value, the owner reset to `default` + +.. _`rules`: + +**acces rules** + + Access rules are : :api:`config.Config.cfgimpl_read_write()` or + :api:`config.Config.cfgimpl_read_only()`, see :doc:`status` + +**freeze** + + A whole configuration can be frozen (used in read only access). See + :doc:`status` for details. + +.. _`valueowner`: + +**value owner** + + When an option is modified, including at the instanciation, we + always know who has modified it. It's the owner of the option, see + :doc:`status` for more details. + +**hidden option** + + a hidden option has a different behaviour on regards to the access + of the value in the configuration, see :doc:`status` for more details. + +**disabled option** + + a disabled option has a different behaviour on regards to the access + of the value in the configuration, see :doc:`status` for more details. + +**fill option** + + a fill option is like an automatic option except that it is + calculated only if a value hasn't been set. + +**auto option** + + an automatic option is an option thas is carried out by an external + calculation + +.. _mandatory: + +**mandatory option** + + A mandatory option is a configuration option wich value has to be + set, that is the default value cannot be `None`, see + :ref:`optionapi#optioninit` + + +.. _consistency: + +**consistency** + + Preserve the consistency in a whole configuration is a tricky thing, + tiramisu takes care of it for you, see :doc:`consistency` for details. diff --git a/src/doc/index.txt b/src/doc/index.txt new file mode 100644 index 0000000..dab64cb --- /dev/null +++ b/src/doc/index.txt @@ -0,0 +1,40 @@ +.. default-role:: literal + +.. meta:: + + :description: configuration management + :keywords: config, configuration + +.. title:: tiramisu + +.. |version| replace:: 0.1 + +The tasting of `Tiramisu` +========================= + +.. image:: tiramisu.jpeg + :height: 150px + +`Tiramisu` + + is a cool, refreshing Italian dessert, + + it is also a configuration management tool. + + +It's a pretty small, local (that is, straight on the operating system) +configuration handler. + +- :doc:`getting-started`: where to go from here, +- :doc:`config` explains the good praticies of configuration handling, +- :doc:`configapi` and :doc:`optionapi` describe the API's details, +- :doc:`status` for a summary of the `Option`'s and `Config`'s statuses, +- :doc:`consistency` for the local and global integrity constraints, + + +- :doc:`glossary` describes the specific terms used in Tiramisu. +- :doc:`pydoc/index` for the developer's API + + + + diff --git a/src/doc/optionapi.txt b/src/doc/optionapi.txt new file mode 100644 index 0000000..c3c534a --- /dev/null +++ b/src/doc/optionapi.txt @@ -0,0 +1,127 @@ +.. default-role:: literal + +Options API Details +===================== + +:module: :api:`option.py` + +.. _schema: + +Description of Options +---------------------- + +All the constructors take a ``name`` and a ``doc`` argument as first +arguments to give the option or option group a name and to document it. +Most constructors take a ``default`` argument that specifies the default +value of the option. If this argument is not supplied the default value +is assumed to be ``None``. + +Appart from that, the `Option` object is not supposed to contain any +other value than the `tainted` attribute, which is explained later. The +container of the value is in the `Config` object. + +``OptionDescription`` ++++++++++++++++++++++ + +This class is used to group suboptions. + + ``__init__(self, name, doc, children)`` + ``children`` is a list of option descriptions (including + ``OptionDescription`` instances for nested namespaces). + + ``set_group_type(self, group_name)`` + Three available group_types : `default`, `family`, `group` and + `master` (for master~slave group type). Notice that for a + master~slave group, the name of the group and the name of the + master option are identical. + +`Options description` objects lives in the `_cfgimpl_descr` config attribute. + +If you need to access an option object, you can do it with the OptionDescription +object. Not only the value of the option by attribute access, but the option +object itself that lives behind the scene. It can always be accessed internally +with the `_cfgimpl_descr` attribute of the `config` objects. For example, with a +option named `name` in a `gc` group the `name` object can be accessed like +this:: + + conf._cfgimpl_descr.name + +of sub configs with :: + + conf.gc._cfgimpl_descr.name + +This is a binding. The option objects are in the `_children` config's attribute. + +Why accessing an option object ? It is possible for example freeze the +configuration option + +:: + + conf.gc._cfgimpl_descr.dummy.freeze() + +or to hide it, or disable it, or... anything. + +.. _optioninit: + +generic option ``__init__`` method: + + ``__init__(name, doc, default=None, requires=None, multi=False, mandatory=False)`` + + :``default``: specifies the default value of the option. + :``requires``: is a list of names of options located anywhere in the configuration. + :``multi``: means the value can be a list. + :``mandatory``: see :ref:`glossary#mandatory`. + +.. _optiontype: + +``BoolOption`` +++++++++++++++ + +Represents a choice between ``True`` and ``False``. + +``IntOption`` ++++++++++++++ + +Represents a choice of an integer. + +``FloatOption`` ++++++++++++++++ + +Represents a choice of a floating point number. + +``StrOption`` ++++++++++++++ + +Represents the choice of a string. + +``SymLinkOption`` +++++++++++++++++++ + +Redirects to another configuration option in the configuration, that is : + +- retrieves the value of the tagert, +- can set the value of the target too. + + ``__init__(self, name, path)`` + + `path` is the path to the target, the option + +``IPOption`` ++++++++++++++ + +Represents the choice of an ip. + +``NetmaskOption`` ++++++++++++++++++++ + +Represents the choice of a netmask. + +``ChoiceOption`` +++++++++++++++++ + +Represents a choice out of several objects. The option can also have the value +``None``. + + ``__init__(self, name, doc, values, default=None, requires=None)`` + ``values`` is a list of values the option can possibly take. + diff --git a/src/doc/rst2html.py b/src/doc/rst2html.py new file mode 100755 index 0000000..3e356f3 --- /dev/null +++ b/src/doc/rst2html.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# unproudly borrowed from David Goodger's rst2html.py + +""" +A minimal front end to the Docutils Publisher, producing HTML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description +# ____________________________________________________________ +from docutils import nodes, utils +from docutils.parsers.rst import roles + +""" +description of the new roles: + +`:api:` : link to the code + +- code.py becomes api/code.html +- code.Code.code_test becomes api/code.Code.code_test.html +- code.Code() becomes api/code.Code.html + +`:doc:`a link to an internal file +example become example.html + +ref: link with anchor as in an external file + +:ref:`toto#titi` becomes toto.html#titi +""" +from os.path import splitext + +def api_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + basename = text + if "(" in text: + basename = text.split("(")[0] + if ".py" in text: + basename = splitext(text)[0] + if "test_" in text: + refuri = "api/" + "tiramisu.test." + basename + '.html' + else: + refuri = "api/" + "tiramisu." + basename + '.html' + roles.set_classes(options) + node = nodes.reference(rawtext, utils.unescape(text), refuri=refuri, + **options) + return [node], [] + +roles.register_local_role('api', api_reference_role) + +def doc_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + refuri = text + '.html' + roles.set_classes(options) + node = nodes.reference(rawtext, utils.unescape(text), refuri=refuri, + **options) + return [node], [] + +roles.register_local_role('doc', doc_reference_role) + +def ref_reference_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + fname, anchor = text.split('#') + refuri = fname + '.html#' + anchor + roles.set_classes(options) + node = nodes.reference(rawtext, utils.unescape(anchor), refuri=refuri, + **options) + return [node], [] + +roles.register_local_role('ref', ref_reference_role) + +# ____________________________________________________________ + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html', description=description) + diff --git a/src/doc/status.txt b/src/doc/status.txt new file mode 100644 index 0000000..23de627 --- /dev/null +++ b/src/doc/status.txt @@ -0,0 +1,181 @@ +.. default-role:: literal + +Configuration status +====================== + +:module: :api:`config.py` +:tests: - :api:`test_option_owner.py` + - :api:`test_option_type.py` + - :api:`test_option_default.py` + +Available configuration statuses +---------------------------------- + +These configuration statuses corresponds to specific global attributes : + +**read write status** + + The configuration can be accessed by `__get__` and `__set__` + properties, except for the `hidden` configuration options but, yes, it is + possible to modify a disabled option. + + To enable read-write status, call + :api:`config.Config.cfgimpl_read_write()` + +**read only status** + + The whole configuration is `frozen`, that is modifiying a value is + forbidden. We can access to a configuration option only with the + `__getattr__` property. + + The configuration has not an access to the hidden options + but can read the disabled options. + + To enable read only status, call :api:`config.Config.cfgimpl_read_only()` + +.. csv-table:: **Configuration's statuses summary** + :header: " ", "Hidden", "Disabled", "Mandatory" + + "read only status", `False`, `True`, `True` + "read-write status", `True`, `False`, `False` + +Freezing a configuration +--------------------------- + +It is possible to *freeze* a single `Option` object with +:api:`option.Option.freeze()`. If you try to modify a frozen option, it +raises a `TypeError: trying to change a frozen option object`. + +At the configuration level, :api:`config.Config.cfgimpl_freeze()` freeze +the whole configuration options. + +- :api:`test_option_type.test_freeze_one_option()` +- :api:`test_option_type.test_frozen_value()` +- :api:`test_option_type.test_freeze()` + + +Restricted access to an `Option()` +----------------------------------- + +Configuration options access statuses are defined at configuration level +that corresponds to theses :api:`option.Option()`'s attribute: + +**hidden** + + This means that an option raises an `HiddenOptionError` if we try to access + the value of the option. + + See `hide()` or `show()` in `Option()` that comes from + :api:`option.HiddenBaseType` + +corresponding convenience API provided: + + `hide()`: + set the `hidden` attribute to `True` + + `show()`: + set the `hidden` attribute to `False` + +**disabled** + + This means that an option *doesn't exists* (doesn't say anything + much more thant an `AttibuteAccess` error) + + See in :api:`option.DisabledBaseType` the origins of + `Option.enable()` or `Option.disable()` + +corresponding convenience API provided: + + `disable()`: + set the `disabled` attribute to `True` + + `enable()`: + set the `disabled` attribute to `False` + +mode + + a mode is `normal` or `expert`, just a category of `Option()` or + group wich determines if an option is easy to choose or not, + available methods are: + + `get_mode()`: + returns the current mode + + `set_mode(mode)`: + sets a new mode + + see it in :api:`option.ModeBaseType` + +Value owners +------------- + +Every configuration option has a **owner**. When the option is +instanciated, the owner is `default` because a default value has been +set (including `None`, take a look at the tests). + +The `value_owner` is the man who did it. Yes, the man who changed the value of the +configuration option. + +- At the instance of the `Config` object, the value owner is `default` because + the default values are set at the instance of the configuration option object, + +:: + + # let's expect there is an option named 'name' + config = Config(descr, bool=False) + # the override method has been called + config._cfgimpl_value_owners['name'] == 'default' + +- at the modification of an option, the owner is `default_owner`, (which is `user`) + +:: + + # modification of the value by attribute access + config.gc.dummy = True + assert config.gc._cfgimpl_value_owners['dummy'] == 'user' + assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'user' + +- the default owner can be set with the `set_owner()` method + +:: + + config.set_owner('spam') + config.set(dummy=True) + assert config.gc._cfgimpl_value_owners['dummy'] == 'spam' + assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'spam' + +Special owners +--------------- + +If the owner of a configuration option is `auto` or `fill` the behavior of the +access of the value changes. In fact, there is nothing in the value. +The value comes from somewhere else (typically, it is calculated by the +operation system). + +**auto** + + This means that it is a calculated value and therefore automatically + protected it cannot be modified by attribute access once the owner + is `auto`. + + The configuration option is hidden and a fonction in a specific + library is called for the computation of the value. + +**fill** + + if the configuration option has a default value, the default is + returned, otherwise the value is calculated + +The default values behavior +---------------------------- + +Configuration options have default values that are stored in the +`Option()` object itself. Default values, the `default`, can be set in +various ways. + +.. FIXME : ADD DETAILS HERE + +If a default value is modified by overriding it, not only the value of +the option resets to the default that is proposed, but the owner is +modified too, it is reseted to `default`. + diff --git a/src/doc/todo.txt b/src/doc/todo.txt new file mode 100644 index 0000000..7f89337 --- /dev/null +++ b/src/doc/todo.txt @@ -0,0 +1,126 @@ +:date: 20 janvier 2012 + +créer une variable implicite cachée + +:: + +