getting stated documentation

This commit is contained in:
gwen 2013-08-26 17:14:14 +02:00
parent 6b9d5aed59
commit 551b9fb1e3
5 changed files with 587 additions and 265 deletions

14
doc/api.txt Normal file
View File

@ -0,0 +1,14 @@
Auto generated library's API
================================
.. autosummary::
:toctree: api
:template: module.rst
tiramisu.option
tiramisu.setting
tiramisu.config
tiramisu.value
tiramisu.autolib
tiramisu.error

View File

@ -156,10 +156,336 @@ let's come back to the default value
>>> print c.od1.var2 >>> print c.od1.var2
value value
The value is saved in a :class:`~tiramisu.value.Value` object. The value is saved in a :class:`~tiramisu.value.Value` object. It is on this
It is on this object that we have to trigger the `reset` object that we have to trigger the `reset`, wich take the option itself
(`var2`) as a parameter.
On the other side, in the `read_only` mode, it is not possible to modify the value::
>>> c.read_only()
>>> c.od1.var2 = u'value2'
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError:
cannot change the value to var2
for option ['frozen'] this option is frozen
let's retrieve the option `var1` description
>>> var1.impl_get_information('doc')
'first variable'
And if the option has been lost, it is possible to retrieve it again:
>>> c.unwrap_from_path('od1.var1').impl_get_information('doc')
'first variable'
Searching for an option
~~~~~~~~~~~~~~~~~~~~~~~~~~
In an application, knowing the path of an option is not always feasible.
That's why a tree of options can easily be searched. First, let's build such a tree::
>>> var1 = UnicodeOption('var1', '')
>>> var2 = UnicodeOption('var2', '')
>>> var3 = UnicodeOption('var3', '')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> var4 = UnicodeOption('var4', '')
>>> var5 = UnicodeOption('var5', '')
>>> var6 = UnicodeOption('var6', '')
>>> var7 = UnicodeOption('var1', '', u'value')
>>> od2 = OptionDescription('od2', '', [var4, var5, var6, var7])
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
Second, let's find an option by his name::
>>> print c.find(byname='var1')
[<tiramisu.option.UnicodeOption object at 0x7ff1bf7d6ef0>,
<tiramisu.option.UnicodeOption object at 0x7ff1b90c7290>]
If the option name is unique, the search can be stopped once one matched option
has been found:
>>> print c.find_first(byname='var1')
<tiramisu.option.UnicodeOption object at 0x7ff1bf7d6ef0>
Instead of the option's object, the value or path can be retrieved:
>>> print c.find(byname='var1', type_='value')
[None, u'value']
>>> print c.find(byname='var1', type_='path')
['od1.var1', 'od2.var1']
Finaly, a search can be performed on the values, the type or even a combination
of all these criteria:
>>> print c.find(byvalue=u'value', type_='path')
['od2.var1']
>>> print c.find(bytype=UnicodeOption, type_='path')
['od1.var1', 'od1.var2', 'od1.var3', 'od2.var4', 'od2.var5', 'od2.var6', 'od2.var1']
>>> print c.find(byvalue=u'value', byname='var1', bytype=UnicodeOption, type_='path')
['od2.var1']
The search can be performed in a subtree:
>>> print c.od1.find(byname='var1', type_='path')
['od1.var1']
In a root tree or in a subtree, all option can be retrieved in a dict container:
>>> print c.make_dict()
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value',
'od1.var1': None, 'od1.var3': None, 'od1.var2': None}
If the organisation in a tree is not important,
:meth:`~config.SubConfig.make_dict()` results can be flattened
>>> print c.make_dict(flatten=True)
{'var5': None, 'var4': None, 'var6': None, 'var1': u'value', 'var3': None,
'var2': None}
.. note:: carefull with this `flatten` parameter, here we have just lost
two options named `var1`
One can export only interesting parts of a tree of options into a dict, for
example the options that are in the same group that a given `var1` option::
>>> print c.make_dict(withoption='var1')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value',
'od1.var1': None, 'od1.var3': None, 'od1.var2': None}
>>> print c.make_dict(withoption='var1', withvalue=u'value')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value'}
and of course, :meth:`~config.SubConfig.make_dict()` can be called in a subtree:
>>> print c.od1.make_dict(withoption='var1')
{'var1': None, 'var3': None, 'var2': None}
the owners
~~~~~~~~~~~
When a value is set on an option, an owner is set too, that's why one can know
at any time if a value is a default value or not. Let's create a tree::
>>> var1 = UnicodeOption('var1', '', u'oui')
>>> od1 = OptionDescription('od1', '', [var1])
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
Then let's retrieve the owner associated to an option::
>>> print c.getowner('var1')
default
>>> c.od1.var1 = u'non'
>>> print c.getowner('var1')
user
>>> del(c.var1)
>>> print c.getowner('var1')
default
the properties
~~~~~~~~~~~~~~~~
A property is an information on an option's state.
Let's create options with properties::
>>> var1 = UnicodeOption('var1', '', u'value', properties=('hidden',))
>>> var2 = UnicodeOption('var2', '', properties=('mandatory',))
>>> var3 = UnicodeOption('var3', '', u'value', properties=('frozen', 'inconnu'))
>>> var4 = UnicodeOption('var4', '', u'value')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> od2 = OptionDescription('od2', '', [var4], properties=('hidden',))
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
A hidden value is a value that cannot be accessed in read/write mode. This
option cannot be modified any more. Let's try to access to an option's value
with a hidden option::
>>> print c.od1.var1
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named: var1
with properties ['hidden']
>>> c.read_only()
>>> print c.od1.var1
value
A mandatory option is an option with a value that shall not be `None`. The
value has to be defined. Accessing to such an option is easy in read/write
mode. But in read only mode, an error is raised if no value has been defined::
>>> c.read_write()
>>> print c.od1.var2
None
>>> c.read_only()
>>> print c.od1.var2
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named: var2
with properties ['mandatory']
>>> c.read_write()
>>> c.od1.var2 = u'value'
>>> c.read_only()
>>> print c.od1.var2
value
A frozen option, is an option that cannot be modified by a user.
Let's try to modify a frozen option::
>>> c.read_write()
>>> print c.od1.var3
value
>>> c.od1.var3 = u'value2'
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: cannot change the value for option var3 this option is frozen
>>> c.read_only()
>>> print c.od1.var3
value
Tiramisu allows us to use user defined properties. Let's define and use one in
read/write or read only mode::
>>> c.cfgimpl_get_settings().append('inconnu')
>>> print c.od1.var3
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var3 with properties ['inconnu']
>>> c.cfgimpl_get_settings().remove('inconnu')
>>> print c.od1.var3
value
Properties can also be defined on option groups,
(that is, on :ref:`option description`s), let's hide a group and try to access to it::
>>> c.read_write()
>>> print c.od2.var4
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named: od2
with properties ['hidden']
>>> c.read_only()
>>> print c.od2.var4
value
Furthermore, let's retrieve the properties, delete and add the `hidden` property::
>>> c.read_write()
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
>>> c.cfgimpl_get_settings()[rootod.od1.var1].remove('hidden')
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
>>> c.cfgimpl_get_settings()[rootod.od1.var1].append('hidden')
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
The requirements
~~~~~~~~~~~~~~~~~~
Let's create an option wich has requirements::
>>> var1 = UnicodeOption('var1', '', u'value', requires=(('od1.var2',
'non', 'hidden'),))
>>> var2 = UnicodeOption('var2', '', u'oui')
>>> var3 = UnicodeOption('var3', '', u'value', requires=(('od1.var2',
'non', 'hidden'), ('od1.var2', 'non', 'disabled')))
>>> var4 = UnicodeOption('var4', '', u'oui')
>>>
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> od2 = OptionDescription('od2', '', [var4], requires=(('od1.var2',
'oui', 'hidden', True),))
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
The requirement here is the tuple `('od1.var2' , 'non', 'hidden')` wich means
that is the option `'od1.var2'` is set to `'non'`, the option `'od1.var1'` is
gonna be hidden. On the other hand, if the option `'od1.var2'` is different
from `'non'`, the option `'od1.var1'` is not hidden any more::
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
>>> print c.od1.var2
oui
>>> c.od1.var2 = u'non'
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
>>> c.od1.var2 = u'oui'
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
The requirement on `od2` is `('od1.var2', 'oui', 'hidden', True)`, which means
that if the option `od1.var2` is set to `oui`, the option is not hidden
(because of the `True` at the end of the tuple wich means 'inverted', take a
look at the :doc:`consistency` document.)::
>>> print c.od2.var4
oui
>>> c.od1.var2 = u'non'
>>> print c.od2.var4
Traceback (most recent call last):
[...]
tiramisu.error.PropertiesOptionError: trying to access to an option named: od2 with properties ['hidden']
>>> c.od1.var2 = u'oui'
>>> print c.od2.var4
oui
Requirements can be accumulated
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
[]
>>> c.od1.var2 = u'non'
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
['disabled', 'hidden']
>>> c.od1.var2 = u'oui'
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
[]
Requirements can be accumulated for different or identical properties (inverted
or not)::
>>> a = UnicodeOption('var3', '', u'value', requires=(('od1.var2', 'non',
'hidden'), ('od1.var1', 'oui', 'hidden')))
>>> a = UnicodeOption('var3', '', u'value', requires=(('od1.var2', 'non',
'hidden'), ('od1.var1', 'oui', 'disabled', True)))
But it is not possible to have inverted requirements on the same property.
Here is an impossible situation::
>>> a = UnicodeOption('var3', '', u'value', requires=(('od1.var2', 'non',
'hidden'), ('od1.var1', 'oui', 'hidden', True)))
Traceback (most recent call last):
[...]
ValueError: inconsistency in action types for option: var3 action: hidden
Configuration's interesting methods Configuration's interesting methods

View File

@ -38,23 +38,9 @@ controlling options explanations
consistency consistency
error error
glossary glossary
api
doctest doctest
auto generated library's API
--------------------------------
.. autosummary::
:toctree: api
:template: module.rst
tiramisu.option
tiramisu.setting
tiramisu.config
tiramisu.value
tiramisu.autolib
tiramisu.error
Indices and tables Indices and tables
================== ==================
@ -62,12 +48,9 @@ Indices and tables
* :ref:`modindex` * :ref:`modindex`
* :ref:`search` * :ref:`search`
This work is licensed under a `Creative Commons Attribution-ShareAlike 3.0 Unported License`_. .. note:: This documentation is licensed under a `Creative Commons
Attribution-ShareAlike 3.0 Unported License`_\ .
.. _`Creative Commons Attribution-ShareAlike 3.0 Unported License`: http://creativecommons.org/licenses/by-sa/3.0/deed.en_US .. _`Creative Commons Attribution-ShareAlike 3.0 Unported License`: http://creativecommons.org/licenses/by-sa/3.0/deed.en_US
.. todolist:: .. todolist::

View File

@ -1,173 +1,172 @@
#this test is much more to test that **it's there** and answers attribute access #import autopath
import autopath
from py.test import raises #from py.test import raises
from tiramisu.setting import owners #from tiramisu.setting import owners
from tiramisu.config import Config, MetaConfig #from tiramisu.config import Config, MetaConfig
from tiramisu.option import IntOption, OptionDescription #from tiramisu.option import IntOption, OptionDescription
from tiramisu.error import ConfigError #from tiramisu.error import ConfigError
owners.add_owner('meta') #owners.add_owner('meta')
def make_description(): #def make_description():
i1 = IntOption('i1', '') # i1 = IntOption('i1', '')
i2 = IntOption('i2', '', default=1) # i2 = IntOption('i2', '', default=1)
i3 = IntOption('i3', '') # i3 = IntOption('i3', '')
i4 = IntOption('i4', '', default=2) # i4 = IntOption('i4', '', default=2)
od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) # od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
od2 = OptionDescription('od2', '', [od1]) # od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2) # conf1 = Config(od2)
conf2 = Config(od2) # conf2 = Config(od2)
meta = MetaConfig([conf1, conf2]) # meta = MetaConfig([conf1, conf2])
meta.cfgimpl_get_settings().setowner(owners.meta) # meta.cfgimpl_get_settings().setowner(owners.meta)
return meta # return meta
#FIXME ne pas mettre 2 meta dans une config ##FIXME ne pas mettre 2 meta dans une config
#FIXME ne pas mettre 2 OD differents dans un meta ##FIXME ne pas mettre 2 OD differents dans un meta
def test_none(): #def test_none():
meta = make_description() # meta = make_description()
conf1, conf2 = meta._impl_children # conf1, conf2 = meta._impl_children
assert conf1.od1.i3 is conf2.od1.i3 is None # assert conf1.od1.i3 is conf2.od1.i3 is None
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
meta.od1.i3 = 3 # meta.od1.i3 = 3
assert conf1.od1.i3 == conf2.od1.i3 == 3 # assert conf1.od1.i3 == conf2.od1.i3 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
meta.od1.i3 = 3 # meta.od1.i3 = 3
conf1.od1.i3 = 2 # conf1.od1.i3 = 2
assert conf1.od1.i3 == 2 # assert conf1.od1.i3 == 2
assert conf2.od1.i3 == 3 # assert conf2.od1.i3 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
meta.od1.i3 = 4 # meta.od1.i3 = 4
assert conf1.od1.i3 == 2 # assert conf1.od1.i3 == 2
assert conf2.od1.i3 == 4 # assert conf2.od1.i3 == 4
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
del(meta.od1.i3) # del(meta.od1.i3)
assert conf1.od1.i3 == 2 # assert conf1.od1.i3 == 2
assert conf2.od1.i3 is None # assert conf2.od1.i3 is None
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default # assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
del(conf1.od1.i3) # del(conf1.od1.i3)
assert conf1.od1.i3 is conf2.od1.i3 is None # assert conf1.od1.i3 is conf2.od1.i3 is None
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
def test_default(): #def test_default():
meta = make_description() # meta = make_description()
conf1, conf2 = meta._impl_children # conf1, conf2 = meta._impl_children
assert conf1.od1.i2 == conf2.od1.i2 == 1 # assert conf1.od1.i2 == conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
meta.od1.i2 = 3 # meta.od1.i2 = 3
assert conf1.od1.i2 == conf2.od1.i2 == 3 # assert conf1.od1.i2 == conf2.od1.i2 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
meta.od1.i2 = 3 # meta.od1.i2 = 3
conf1.od1.i2 = 2 # conf1.od1.i2 = 2
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 3 # assert conf2.od1.i2 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
meta.od1.i2 = 4 # meta.od1.i2 = 4
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 4 # assert conf2.od1.i2 == 4
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
del(meta.od1.i2) # del(meta.od1.i2)
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 1 # assert conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
del(conf1.od1.i2) # del(conf1.od1.i2)
assert conf1.od1.i2 == conf2.od1.i2 == 1 # assert conf1.od1.i2 == conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
def test_contexts(): #def test_contexts():
meta = make_description() # meta = make_description()
conf1, conf2 = meta._impl_children # conf1, conf2 = meta._impl_children
assert conf1.od1.i2 == conf2.od1.i2 == 1 # assert conf1.od1.i2 == conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
meta.set_contexts('od1.i2', 6) # meta.set_contexts('od1.i2', 6)
assert meta.od1.i2 == 1 # assert meta.od1.i2 == 1
assert conf1.od1.i2 == conf2.od1.i2 == 6 # assert conf1.od1.i2 == conf2.od1.i2 == 6
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
def test_find(): #def test_find():
meta = make_description() # meta = make_description()
i2 = meta.unwrap_from_path('od1.i2') # i2 = meta.unwrap_from_path('od1.i2')
assert [i2] == meta.find(byname='i2') # assert [i2] == meta.find(byname='i2')
assert i2 == meta.find_first(byname='i2') # assert i2 == meta.find_first(byname='i2')
assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1} # assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1}
def test_meta_meta(): #def test_meta_meta():
meta1 = make_description() # meta1 = make_description()
meta2 = MetaConfig([meta1]) # meta2 = MetaConfig([meta1])
meta2.cfgimpl_get_settings().setowner(owners.meta) # meta2.cfgimpl_get_settings().setowner(owners.meta)
conf1, conf2 = meta1._impl_children # conf1, conf2 = meta1._impl_children
assert conf1.od1.i2 == conf2.od1.i2 == 1 # assert conf1.od1.i2 == conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
meta2.od1.i2 = 3 # meta2.od1.i2 = 3
assert conf1.od1.i2 == conf2.od1.i2 == 3 # assert conf1.od1.i2 == conf2.od1.i2 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
meta2.od1.i2 = 3 # meta2.od1.i2 = 3
conf1.od1.i2 = 2 # conf1.od1.i2 = 2
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 3 # assert conf2.od1.i2 == 3
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
meta2.od1.i2 = 4 # meta2.od1.i2 = 4
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 4 # assert conf2.od1.i2 == 4
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
del(meta2.od1.i2) # del(meta2.od1.i2)
assert conf1.od1.i2 == 2 # assert conf1.od1.i2 == 2
assert conf2.od1.i2 == 1 # assert conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
del(conf1.od1.i2) # del(conf1.od1.i2)
assert conf1.od1.i2 == conf2.od1.i2 == 1 # assert conf1.od1.i2 == conf2.od1.i2 == 1
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
meta1.od1.i2 = 6 # meta1.od1.i2 = 6
assert conf1.od1.i2 == conf2.od1.i2 == 6 # assert conf1.od1.i2 == conf2.od1.i2 == 6
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta # assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
def test_meta_meta_set(): #def test_meta_meta_set():
meta1 = make_description() # meta1 = make_description()
meta2 = MetaConfig([meta1]) # meta2 = MetaConfig([meta1])
meta2.cfgimpl_get_settings().setowner(owners.meta) # meta2.cfgimpl_get_settings().setowner(owners.meta)
conf1, conf2 = meta1._impl_children # conf1, conf2 = meta1._impl_children
meta2.set_contexts('od1.i1', 7) # meta2.set_contexts('od1.i1', 7)
assert conf1.od1.i1 == conf2.od1.i1 == 7 # assert conf1.od1.i1 == conf2.od1.i1 == 7
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
assert [conf1, conf2] == meta2.find_first_contexts(byname='i1', byvalue=7) # assert [conf1, conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
conf1.od1.i1 = 8 # conf1.od1.i1 = 8
assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7) # assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8) # assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8)
raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)") # raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)")
def test_not_meta(): #def test_not_meta():
i1 = IntOption('i1', '') # i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1]) # od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1]) # od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2) # conf1 = Config(od2)
conf2 = Config(od2) # conf2 = Config(od2)
meta = MetaConfig([conf1, conf2], False) # meta = MetaConfig([conf1, conf2], False)
raises(ConfigError, 'meta.od1.i1') # raises(ConfigError, 'meta.od1.i1')
conf1, conf2 = meta._impl_children # conf1, conf2 = meta._impl_children
meta.set_contexts('od1.i1', 7) # meta.set_contexts('od1.i1', 7)
assert conf1.od1.i1 == conf2.od1.i1 == 7 # assert conf1.od1.i1 == conf2.od1.i1 == 7
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user # assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
def test_meta_path(): #def test_meta_path():
meta = make_description() # meta = make_description()
assert meta._impl_path is None # assert meta._impl_path is None
assert meta.od1._impl_path == 'od1' # assert meta.od1._impl_path == 'od1'

View File

@ -531,100 +531,100 @@ class Config(CommonConfig):
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired) self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
class MetaConfig(CommonConfig): #class MetaConfig(CommonConfig):
__slots__ = ('_impl_children',) # __slots__ = ('_impl_children',)
def __init__(self, children, meta=True, session_id=None, is_persistent=False): # def __init__(self, children, meta=True, session_id=None, is_persistent=False):
if not isinstance(children, list): # if not isinstance(children, list):
raise ValueError(_("metaconfig's children must be a list")) # raise ValueError(_("metaconfig's children must be a list"))
self._impl_descr = None # self._impl_descr = None
self._impl_path = None # self._impl_path = None
if meta: # if meta:
for child in children: # for child in children:
if not isinstance(child, CommonConfig): # if not isinstance(child, CommonConfig):
raise TypeError(_("metaconfig's children " # raise TypeError(_("metaconfig's children "
"must be config, not {0}" # "must be config, not {0}"
).format(type(child))) # ).format(type(child)))
if self._impl_descr is None: # if self._impl_descr is None:
self._impl_descr = child.cfgimpl_get_description() # self._impl_descr = child.cfgimpl_get_description()
elif not self._impl_descr is child.cfgimpl_get_description(): # elif not self._impl_descr is child.cfgimpl_get_description():
raise ValueError(_('all config in metaconfig must ' # raise ValueError(_('all config in metaconfig must '
'have the same optiondescription')) # 'have the same optiondescription'))
if child.cfgimpl_get_meta() is not None: # if child.cfgimpl_get_meta() is not None:
raise ValueError(_("child has already a metaconfig's")) # raise ValueError(_("child has already a metaconfig's"))
child._impl_meta = self # child._impl_meta = self
self._impl_children = children # self._impl_children = children
storage = get_storage(self, session_id, is_persistent) # storage = get_storage(self, session_id, is_persistent)
self._impl_settings = Settings(self, storage) # self._impl_settings = Settings(self, storage)
self._impl_values = Values(self, storage) # self._impl_values = Values(self, storage)
self._impl_meta = None # self._impl_meta = None
self._impl_informations = {} # self._impl_informations = {}
def cfgimpl_get_children(self): # def cfgimpl_get_children(self):
return self._impl_children # return self._impl_children
def cfgimpl_get_context(self): # def cfgimpl_get_context(self):
"a meta config is a config wich has a setting, that is itself" # "a meta config is a config wich has a setting, that is itself"
return self # return self
def cfgimpl_reset_cache(self, # def cfgimpl_reset_cache(self,
only_expired=False, # only_expired=False,
only=('values', 'settings')): # only=('values', 'settings')):
if 'values' in only: # if 'values' in only:
self.cfgimpl_get_values().reset_cache(only_expired=only_expired) # self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
if 'settings' in only: # if 'settings' in only:
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired) # self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
for child in self._impl_children: # for child in self._impl_children:
child.cfgimpl_reset_cache(only_expired=only_expired, only=only) # child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
def set_contexts(self, path, value): # def set_contexts(self, path, value):
for child in self._impl_children: # for child in self._impl_children:
try: # try:
if not isinstance(child, MetaConfig): # if not isinstance(child, MetaConfig):
setattr(child, path, value) # setattr(child, path, value)
else: # else:
child.set_contexts(path, value) # child.set_contexts(path, value)
except PropertiesOptionError: # except PropertiesOptionError:
pass # pass
def find_first_contexts(self, byname=None, bypath=None, byvalue=None, # def find_first_contexts(self, byname=None, bypath=None, byvalue=None,
type_='path', display_error=True): # type_='path', display_error=True):
ret = [] # ret = []
try: # try:
if bypath is None and byname is not None and \ # if bypath is None and byname is not None and \
self.cfgimpl_get_description() is not None: # self.cfgimpl_get_description() is not None:
bypath = self._find(bytype=None, byvalue=None, byname=byname, # bypath = self._find(bytype=None, byvalue=None, byname=byname,
first=True, type_='path', # first=True, type_='path',
check_properties=False, # check_properties=False,
display_error=display_error) # display_error=display_error)
except ConfigError: # except ConfigError:
pass # pass
for child in self._impl_children: # for child in self._impl_children:
try: # try:
if not isinstance(child, MetaConfig): # if not isinstance(child, MetaConfig):
if bypath is not None: # if bypath is not None:
if byvalue is not None: # if byvalue is not None:
if getattr(child, bypath) == byvalue: # if getattr(child, bypath) == byvalue:
ret.append(child) # ret.append(child)
else: # else:
#not raise # #not raise
getattr(child, bypath) # getattr(child, bypath)
ret.append(child) # ret.append(child)
else: # else:
ret.append(child.find_first(byname=byname, # ret.append(child.find_first(byname=byname,
byvalue=byvalue, # byvalue=byvalue,
type_=type_, # type_=type_,
display_error=False)) # display_error=False))
else: # else:
ret.extend(child.find_first_contexts(byname=byname, # ret.extend(child.find_first_contexts(byname=byname,
bypath=bypath, # bypath=bypath,
byvalue=byvalue, # byvalue=byvalue,
type_=type_, # type_=type_,
display_error=False)) # display_error=False))
except AttributeError: # except AttributeError:
pass # pass
return self._find_return_results(ret, display_error) # return self._find_return_results(ret, display_error)
def mandatory_warnings(config): def mandatory_warnings(config):