documentation update and docstrings

This commit is contained in:
gwen 2013-08-21 17:21:09 +02:00
parent 7d2449380c
commit acca6d5a27
5 changed files with 60 additions and 8 deletions

View File

@ -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 4. If an option is declared, and a value has been set, the returned value is
the value of the option. 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 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()` worry, an option value can be "reseted" with the help of the `option.Option.reset()`
method. method.
@ -130,3 +135,9 @@ Here are the (useful) methods on ``Config`` (or `SubConfig`).
.. rubric:: Methods .. 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.

View File

@ -30,6 +30,19 @@ of the same type.
For example, an :class:`option.IntOption` validator waits for an `int` object of For example, an :class:`option.IntOption` validator waits for an `int` object of
course, an :class:`option.StrOption` validator waits for an `str`, vs... 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 Requirements
------------ ------------
@ -76,3 +89,15 @@ modified at the first calculation.
.. automodule:: tiramisu.autolib .. automodule:: tiramisu.autolib
:members: :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

View File

@ -184,6 +184,15 @@ class Settings(object):
__slots__ = ('context', '_owner', '_p_') __slots__ = ('context', '_owner', '_p_')
def __init__(self, context, storage): def __init__(self, context, storage):
"""
initializer
:param context: the root config
:param storage: the storage type
- dictionnary -> in memory
- sqlite3 -> persistent
"""
# generic owner # generic owner
self._owner = owners.user self._owner = owners.user
self.context = context self.context = context
@ -203,6 +212,7 @@ class Settings(object):
#____________________________________________________________ #____________________________________________________________
# properties methods # properties methods
def __contains__(self, propname): def __contains__(self, propname):
"enables the pythonic 'in' syntaxic sugar"
return propname in self._getproperties() return propname in self._getproperties()
def __repr__(self): def __repr__(self):
@ -280,11 +290,11 @@ class Settings(object):
the behavior can be different (typically with the `frozen` the behavior can be different (typically with the `frozen`
property) property)
""" """
#opt properties # opt properties
properties = copy(self._getproperties(opt_or_descr)) properties = copy(self._getproperties(opt_or_descr))
#remove opt permissive # remove opt permissive
properties -= self._p_.getpermissive(self._getkey(opt_or_descr)) properties -= self._p_.getpermissive(self._getkey(opt_or_descr))
#remove global permissive if need # remove global permissive if need
self_properties = copy(self._getproperties()) self_properties = copy(self._getproperties())
if force_permissive is True or 'permissive' in self_properties: if force_permissive is True or 'permissive' in self_properties:
properties -= self._p_.getpermissive() properties -= self._p_.getpermissive()
@ -322,7 +332,7 @@ class Settings(object):
"").format(opt_or_descr._name, "").format(opt_or_descr._name,
str(props)), props) 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): def set_permissive(self, permissive, opt=None):
if not isinstance(permissive, tuple): if not isinstance(permissive, tuple):
raise TypeError(_('permissive must be a tuple')) raise TypeError(_('permissive must be a tuple'))
@ -392,7 +402,7 @@ class Settings(object):
"{1} {2}").format(opt._name, "{1} {2}").format(opt._name,
path, path,
properties)) properties))
#transitive action, force expected # transitive action, force expected
value = expected[0] value = expected[0]
inverse = False inverse = False
except AttributeError: except AttributeError:
@ -403,7 +413,7 @@ class Settings(object):
inverse and value not in expected): inverse and value not in expected):
matches = True matches = True
setting.append(action) setting.append(action)
## the calculation cannot be carried out # the calculation cannot be carried out
break break
# no requirement has been triggered, then just reverse the action # no requirement has been triggered, then just reverse the action
if not matches: if not matches:

View File

@ -46,6 +46,11 @@ class Cache(object):
return False, None return False, None
def hascache(self, cache_type, opt): 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 return opt in self._cache
def reset_expired_cache(self, cache_type, exp): def reset_expired_cache(self, cache_type, exp):
@ -56,6 +61,7 @@ class Cache(object):
del(self._cache[key]) del(self._cache[key])
def reset_all_cache(self, cache_type): def reset_all_cache(self, cache_type):
"empty the cache"
self._cache.clear() self._cache.clear()
def get_cached(self, cache_type, context): def get_cached(self, cache_type, context):

View File

@ -79,12 +79,12 @@ class Values(object):
""" """
key = self._getkey(opt) key = self._getkey(opt)
if not self._p_.hasvalue(key): if not self._p_.hasvalue(key):
# if no value # if there is no value
value = self._getdefault(opt) value = self._getdefault(opt)
if opt.impl_is_multi(): if opt.impl_is_multi():
value = Multi(value, self.context, opt, validate) value = Multi(value, self.context, opt, validate)
else: else:
#if value # if there is a value
value = self._p_.getvalue(key) value = self._p_.getvalue(key)
if opt.impl_is_multi() and not isinstance(value, Multi): if opt.impl_is_multi() and not isinstance(value, Multi):
# load value so don't need to validate if is not a Multi # load value so don't need to validate if is not a Multi