From acca6d5a270c1fbb12120820df75e29eda6dc4bc Mon Sep 17 00:00:00 2001 From: gwen Date: Wed, 21 Aug 2013 17:21:09 +0200 Subject: [PATCH] documentation update and docstrings --- doc/config.txt | 11 +++++++++++ doc/consistency.txt | 25 +++++++++++++++++++++++++ tiramisu/setting.py | 22 ++++++++++++++++------ tiramisu/storage/dictionary/storage.py | 6 ++++++ tiramisu/value.py | 4 ++-- 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/doc/config.txt b/doc/config.txt index a4a3a7c..2547923 100644 --- a/doc/config.txt +++ b/doc/config.txt @@ -61,6 +61,11 @@ Let's make the protocol of accessing a config's attribute explicit 4. If an option is declared, and a value has been set, the returned value is the value of the option. +But there are special exceptions. We will see later on that an option can be a +:term:`mandatory option`. A mandatory option is an option that must have a defined value. +If no value have been set yet, the value is `None`. +When the option is called to retrieve a value, an exception is raised. + What if a value has been set and `None` is to be returned again ? Don't worry, an option value can be "reseted" with the help of the `option.Option.reset()` method. @@ -130,3 +135,9 @@ Here are the (useful) methods on ``Config`` (or `SubConfig`). .. rubric:: Methods +A :class:`~config.CommonConfig` is a abstract base class. A +:class:`~config.SubConfig` is an just in time created objects that wraps an +::class:`~option.OptionDescription`. A SubConfig differs from a Config in the +::fact that a config is a root object and has an environnement, a context wich +::defines the different properties, access rules, vs... There is generally only +::one Config, and many SubConfigs. diff --git a/doc/consistency.txt b/doc/consistency.txt index 16d9eab..c5014b5 100644 --- a/doc/consistency.txt +++ b/doc/consistency.txt @@ -30,6 +30,19 @@ of the same type. For example, an :class:`option.IntOption` validator waits for an `int` object of course, an :class:`option.StrOption` validator waits for an `str`, vs... + +Where are located the values +------------------------------- + +The entry point of the acces to the values is the :class:`setting.Setting()` of +the root configuration object, but the values are actually located in the +:class:`value.Values()` object, in order to be delegated in some kind of a +`tiramisu.storage`, which can be a in-memory storage, or a persistent (for the +time being, a sqlite3) storage. + +:class:`value.Values()` is also responsible of the owners and the calculation +of the options that have callbacks. + Requirements ------------ @@ -76,3 +89,15 @@ modified at the first calculation. .. automodule:: tiramisu.autolib :members: +This is the typically protocol for accessing a option's for a calculated value, +but some twisted ways are also possible, take a look at the `force_store_value` +attribute. + +.. glossary:: + + force store value + + A calculated value (that is, an option that has a callback) with the + attribute `force_store_value` enabled is considered to be modified at + the first calculation + diff --git a/tiramisu/setting.py b/tiramisu/setting.py index b4cdc7a..b0f3dcd 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -184,6 +184,15 @@ class Settings(object): __slots__ = ('context', '_owner', '_p_') def __init__(self, context, storage): + """ + initializer + + :param context: the root config + :param storage: the storage type + + - dictionnary -> in memory + - sqlite3 -> persistent + """ # generic owner self._owner = owners.user self.context = context @@ -203,6 +212,7 @@ class Settings(object): #____________________________________________________________ # properties methods def __contains__(self, propname): + "enables the pythonic 'in' syntaxic sugar" return propname in self._getproperties() def __repr__(self): @@ -280,11 +290,11 @@ class Settings(object): the behavior can be different (typically with the `frozen` property) """ - #opt properties + # opt properties properties = copy(self._getproperties(opt_or_descr)) - #remove opt permissive + # remove opt permissive properties -= self._p_.getpermissive(self._getkey(opt_or_descr)) - #remove global permissive if need + # remove global permissive if need self_properties = copy(self._getproperties()) if force_permissive is True or 'permissive' in self_properties: properties -= self._p_.getpermissive() @@ -322,7 +332,7 @@ class Settings(object): "").format(opt_or_descr._name, str(props)), props) - #FIXME should be setpermissive + # XXX should rename it to setpermissive, but kept for retro compatibility def set_permissive(self, permissive, opt=None): if not isinstance(permissive, tuple): raise TypeError(_('permissive must be a tuple')) @@ -392,7 +402,7 @@ class Settings(object): "{1} {2}").format(opt._name, path, properties)) - #transitive action, force expected + # transitive action, force expected value = expected[0] inverse = False except AttributeError: @@ -403,7 +413,7 @@ class Settings(object): inverse and value not in expected): matches = True setting.append(action) - ## the calculation cannot be carried out + # the calculation cannot be carried out break # no requirement has been triggered, then just reverse the action if not matches: diff --git a/tiramisu/storage/dictionary/storage.py b/tiramisu/storage/dictionary/storage.py index 2180adf..09caf05 100644 --- a/tiramisu/storage/dictionary/storage.py +++ b/tiramisu/storage/dictionary/storage.py @@ -46,6 +46,11 @@ class Cache(object): return False, None def hascache(self, cache_type, opt): + """ option is in the cache + + :param cache_type: value | property + :param opt: the key (typically, the option object) + """ return opt in self._cache def reset_expired_cache(self, cache_type, exp): @@ -56,6 +61,7 @@ class Cache(object): del(self._cache[key]) def reset_all_cache(self, cache_type): + "empty the cache" self._cache.clear() def get_cached(self, cache_type, context): diff --git a/tiramisu/value.py b/tiramisu/value.py index ee0bb76..99d6d7f 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -79,12 +79,12 @@ class Values(object): """ key = self._getkey(opt) if not self._p_.hasvalue(key): - # if no value + # if there is no value value = self._getdefault(opt) if opt.impl_is_multi(): value = Multi(value, self.context, opt, validate) else: - #if value + # if there is a value value = self._p_.getvalue(key) if opt.impl_is_multi() and not isinstance(value, Multi): # load value so don't need to validate if is not a Multi