values are in value objects now
This commit is contained in:
parent
29914051e0
commit
9259a6e3f7
13 changed files with 303 additions and 234 deletions
|
@ -89,13 +89,13 @@ def test_base_config_in_a_tree():
|
||||||
assert config.gc.name == 'ref'
|
assert config.gc.name == 'ref'
|
||||||
config.wantframework = True
|
config.wantframework = True
|
||||||
|
|
||||||
def test_config_values():
|
#def test_config_values():
|
||||||
"_cfgimpl_values appears to be a simple dict"
|
# "_cfgimpl_values appears to be a simple dict"
|
||||||
descr = make_description()
|
# descr = make_description()
|
||||||
config = Config(descr)
|
# config = Config(descr)
|
||||||
config.bool = False
|
# config.bool = False
|
||||||
config.set(dummy=False)
|
# config.set(dummy=False)
|
||||||
assert config.gc._cfgimpl_values == {'dummy': False, 'float': 2.3, 'name': 'ref'}
|
# assert config.gc._cfgimpl_values == {'dummy': False, 'float': 2.3, 'name': 'ref'}
|
||||||
|
|
||||||
def test_cfgimpl_get_home_by_path():
|
def test_cfgimpl_get_home_by_path():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
|
|
|
@ -3,7 +3,6 @@ from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
from tiramisu.setting import settings
|
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -126,14 +125,14 @@ def test_newoption_add_in_subdescr():
|
||||||
config.bool = False
|
config.bool = False
|
||||||
assert config.gc.newoption == False
|
assert config.gc.newoption == False
|
||||||
|
|
||||||
def test_newoption_add_in_config():
|
#def test_newoption_add_in_config():
|
||||||
descr = make_description()
|
# descr = make_description()
|
||||||
config = Config(descr)
|
# config = Config(descr)
|
||||||
config.bool = False
|
# config.bool = False
|
||||||
newoption = BoolOption('newoption', 'dummy twoo', default=False)
|
# newoption = BoolOption('newoption', 'dummy twoo', default=False)
|
||||||
descr.add_child(newoption)
|
# descr.add_child(newoption)
|
||||||
config.cfgimpl_update()
|
# config.cfgimpl_update()
|
||||||
assert config.newoption == False
|
# assert config.newoption == False
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
def make_description_requires():
|
def make_description_requires():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -236,6 +235,7 @@ def test_has_callback():
|
||||||
config.bool = False
|
config.bool = False
|
||||||
# because dummy has a callback
|
# because dummy has a callback
|
||||||
dummy = config.unwrap_from_path('gc.dummy')
|
dummy = config.unwrap_from_path('gc.dummy')
|
||||||
|
settings = config.cfgimpl_get_settings()
|
||||||
settings.freeze()
|
settings.freeze()
|
||||||
dummy.freeze()
|
dummy.freeze()
|
||||||
raises(TypeError, "config.gc.dummy = True")
|
raises(TypeError, "config.gc.dummy = True")
|
||||||
|
@ -244,6 +244,7 @@ def test_freeze_and_has_callback_with_setoption():
|
||||||
descr = make_description_callback()
|
descr = make_description_callback()
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
config.bool = False
|
config.bool = False
|
||||||
|
settings = config.cfgimpl_get_settings()
|
||||||
settings.freeze()
|
settings.freeze()
|
||||||
dummy = config.unwrap_from_path('gc.dummy')
|
dummy = config.unwrap_from_path('gc.dummy')
|
||||||
dummy.freeze()
|
dummy.freeze()
|
||||||
|
|
|
@ -79,18 +79,18 @@ def test_force_default_on_freeze():
|
||||||
assert config.dummy1 == False
|
assert config.dummy1 == False
|
||||||
assert config.dummy2 == False
|
assert config.dummy2 == False
|
||||||
|
|
||||||
def test_override_are_defaults():
|
#def test_override_are_defaults():
|
||||||
descr = make_description()
|
# descr = make_description()
|
||||||
config = Config(descr)
|
# config = Config(descr)
|
||||||
config.bool = False
|
# config.bool = False
|
||||||
config.gc.dummy = True
|
# config.gc.dummy = True
|
||||||
assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'user'
|
# assert config._cfgimpl_values['gc']._cfgimpl_values.owners['dummy'] == 'user'
|
||||||
#Options have an available default setting and can give it back
|
# #Options have an available default setting and can give it back
|
||||||
assert config._cfgimpl_descr._children[0]._children[1].getdefault() == False
|
# assert config._cfgimpl_descr._children[0]._children[1].getdefault() == False
|
||||||
# config.override({'gc.dummy':True})
|
## config.override({'gc.dummy':True})
|
||||||
#assert config.gc.dummy == True
|
# #assert config.gc.dummy == True
|
||||||
#assert config._cfgimpl_descr._children[0]._children[1].getdefault() == True
|
# #assert config._cfgimpl_descr._children[0]._children[1].getdefault() == True
|
||||||
#assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'default'
|
# #assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'default'
|
||||||
|
|
||||||
def test_overrides_changes_option_value():
|
def test_overrides_changes_option_value():
|
||||||
"with config.override(), the default is changed and the value is changed"
|
"with config.override(), the default is changed and the value is changed"
|
||||||
|
|
|
@ -3,7 +3,7 @@ import autopath
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
from tiramisu.setting import settings, owners
|
from tiramisu.setting import owners
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
|
|
@ -51,10 +51,10 @@ def test_reset():
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
config.string = "foo"
|
config.string = "foo"
|
||||||
assert config.string == "foo"
|
assert config.string == "foo"
|
||||||
assert config._cfgimpl_value_owners['string'] == owners.user
|
assert config._cfgimpl_values.owners[s] == owners.user
|
||||||
config.unwrap_from_path("string").reset(config)
|
config.unwrap_from_path("string").reset(config)
|
||||||
assert config.string == 'string'
|
assert config.string == 'string'
|
||||||
assert config._cfgimpl_value_owners['string'] == owners.default
|
assert config._cfgimpl_values.owners[s] == owners.default
|
||||||
|
|
||||||
def test_reset_with_multi():
|
def test_reset_with_multi():
|
||||||
s = StrOption("string", "", default=["string"], default_multi="string" , multi=True)
|
s = StrOption("string", "", default=["string"], default_multi="string" , multi=True)
|
||||||
|
@ -63,13 +63,13 @@ def test_reset_with_multi():
|
||||||
# config.string = []
|
# config.string = []
|
||||||
config.unwrap_from_path("string").reset(config)
|
config.unwrap_from_path("string").reset(config)
|
||||||
assert config.string == ["string"]
|
assert config.string == ["string"]
|
||||||
assert config._cfgimpl_value_owners['string'] == 'default'
|
assert config._cfgimpl_values.owners[s] == 'default'
|
||||||
config.string = ["eggs", "spam", "foo"]
|
config.string = ["eggs", "spam", "foo"]
|
||||||
assert config._cfgimpl_value_owners['string'] == 'user'
|
assert config._cfgimpl_values.owners[s] == 'user'
|
||||||
config.string = []
|
config.string = []
|
||||||
config.unwrap_from_path("string").reset(config)
|
config.unwrap_from_path("string").reset(config)
|
||||||
# assert config.string == ["string"]
|
# assert config.string == ["string"]
|
||||||
assert config._cfgimpl_value_owners['string'] == 'default'
|
assert config._cfgimpl_values.owners[s] == 'default'
|
||||||
raises(ConfigError, "config.string = None")
|
raises(ConfigError, "config.string = None")
|
||||||
|
|
||||||
def test_default_with_multi():
|
def test_default_with_multi():
|
||||||
|
@ -111,10 +111,10 @@ def test_access_with_multi_default():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
descr = OptionDescription("options", "", [s])
|
descr = OptionDescription("options", "", [s])
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
assert config._cfgimpl_value_owners["string"] == 'default'
|
assert config._cfgimpl_values.owners[s] == 'default'
|
||||||
config.string = ["foo", "bar"]
|
config.string = ["foo", "bar"]
|
||||||
assert config.string == ["foo", "bar"]
|
assert config.string == ["foo", "bar"]
|
||||||
assert config._cfgimpl_value_owners["string"] == 'user'
|
assert config._cfgimpl_values.owners[s] == 'user'
|
||||||
|
|
||||||
#def test_attribute_access_with_multi2():
|
#def test_attribute_access_with_multi2():
|
||||||
# s = StrOption("string", "", default="string", multi=True)
|
# s = StrOption("string", "", default="string", multi=True)
|
||||||
|
@ -227,7 +227,7 @@ def test_multi_with_bool():
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
assert descr.bool.multi == True
|
assert descr.bool.multi == True
|
||||||
config.bool = [True, False]
|
config.bool = [True, False]
|
||||||
assert config._cfgimpl_values['bool'] == [True, False]
|
assert config._cfgimpl_context._cfgimpl_values[s] == [True, False]
|
||||||
assert config.bool == [True, False]
|
assert config.bool == [True, False]
|
||||||
|
|
||||||
def test_multi_with_bool_two():
|
def test_multi_with_bool_two():
|
||||||
|
@ -323,22 +323,22 @@ def test_set_symlink_option():
|
||||||
assert config.s1.b == False
|
assert config.s1.b == False
|
||||||
assert config.c == False
|
assert config.c == False
|
||||||
|
|
||||||
#____________________________________________________________
|
##____________________________________________________________
|
||||||
def test_config_impl_values():
|
#def test_config_impl_values():
|
||||||
descr = make_description()
|
# descr = make_description()
|
||||||
config = Config(descr)
|
# config = Config(descr)
|
||||||
config.bool = False
|
# config.bool = False
|
||||||
# gcdummy.setoption(config, True, "user")
|
## gcdummy.setoption(config, True, "user")
|
||||||
# config.setoption("gc.dummy", True, "user")
|
## config.setoption("gc.dummy", True, "user")
|
||||||
#config.gc.dummy = True
|
# #config.gc.dummy = True
|
||||||
# config.setoption("bool", False, "user")
|
## config.setoption("bool", False, "user")
|
||||||
config.set(dummy=False)
|
# config.set(dummy=False)
|
||||||
assert config.gc._cfgimpl_values == {'dummy': False, 'float': 2.3, 'name': 'ref'}
|
# assert config.gc._cfgimpl_context._cfgimpl_values.values == {'dummy': False, 'float': 2.3, 'name': 'ref'}
|
||||||
## acces to the option object
|
# ## acces to the option object
|
||||||
# config.gc._cfgimpl_descr.dummy.setoption(config, True, "user")
|
## config.gc._cfgimpl_descr.dummy.setoption(config, True, "user")
|
||||||
assert config.gc.dummy == False
|
# assert config.gc.dummy == False
|
||||||
# config.set(dummy=True)
|
## config.set(dummy=True)
|
||||||
# assert config.gc.dummy == True
|
## assert config.gc.dummy == True
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
def test_accepts_multiple_changes_from_option():
|
def test_accepts_multiple_changes_from_option():
|
||||||
|
|
|
@ -5,7 +5,6 @@ from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
from tiramisu.setting import settings
|
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -64,6 +63,7 @@ def make_description_freeze():
|
||||||
def test_freeze_whole_config():
|
def test_freeze_whole_config():
|
||||||
descr = make_description_freeze()
|
descr = make_description_freeze()
|
||||||
conf = Config(descr)
|
conf = Config(descr)
|
||||||
|
settings = conf.cfgimpl_get_settings()
|
||||||
settings.freeze_everything()
|
settings.freeze_everything()
|
||||||
assert conf.gc.dummy == False
|
assert conf.gc.dummy == False
|
||||||
raises(TypeError, "conf.gc.dummy = True")
|
raises(TypeError, "conf.gc.dummy = True")
|
||||||
|
@ -85,6 +85,7 @@ def test_frozen_value():
|
||||||
s = StrOption("string", "", default="string")
|
s = StrOption("string", "", default="string")
|
||||||
descr = OptionDescription("options", "", [s])
|
descr = OptionDescription("options", "", [s])
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
|
settings = config.cfgimpl_get_settings()
|
||||||
settings.freeze()
|
settings.freeze()
|
||||||
s.freeze()
|
s.freeze()
|
||||||
raises(TypeError, 'config.string = "egg"')
|
raises(TypeError, 'config.string = "egg"')
|
||||||
|
@ -93,6 +94,7 @@ def test_freeze():
|
||||||
"freeze a whole configuration object"
|
"freeze a whole configuration object"
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
conf = Config(descr)
|
conf = Config(descr)
|
||||||
|
settings = conf.cfgimpl_get_settings()
|
||||||
settings.freeze()
|
settings.freeze()
|
||||||
name = conf.unwrap_from_path("gc.name")
|
name = conf.unwrap_from_path("gc.name")
|
||||||
name.freeze()
|
name.freeze()
|
||||||
|
@ -107,9 +109,8 @@ def test_is_hidden():
|
||||||
# getattr
|
# getattr
|
||||||
raises(PropertiesOptionError, "config.gc.dummy")
|
raises(PropertiesOptionError, "config.gc.dummy")
|
||||||
# I want to access to this option anyway
|
# I want to access to this option anyway
|
||||||
path = 'gc.dummy'
|
opt = config.unwrap_from_path("gc.dummy")
|
||||||
homeconfig, name = config._cfgimpl_get_home_by_path(path)
|
assert config._cfgimpl_context._cfgimpl_values[opt] == False
|
||||||
assert homeconfig._cfgimpl_values[name] == False
|
|
||||||
|
|
||||||
def test_group_is_hidden():
|
def test_group_is_hidden():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
|
|
|
@ -4,7 +4,6 @@ from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
from tiramisu.setting import settings
|
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -40,6 +39,7 @@ def test_root_config_answers_ok():
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
||||||
descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
|
descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
settings = cfg.cfgimpl_get_settings()
|
||||||
settings.enable_property('hiddend') #cfgimpl_hide()
|
settings.enable_property('hiddend') #cfgimpl_hide()
|
||||||
assert cfg.dummy == False
|
assert cfg.dummy == False
|
||||||
assert cfg.boolop == True
|
assert cfg.boolop == True
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import autopath
|
#import autopath
|
||||||
from py.test import raises
|
#from py.test import raises
|
||||||
|
|
||||||
from tool import reverse_from_paths
|
#from tool import reverse_from_paths
|
||||||
|
|
||||||
#def make_description():
|
#def make_description():
|
||||||
# gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
# gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -24,15 +24,15 @@ from tool import reverse_from_paths
|
||||||
# intoption, boolop])
|
# intoption, boolop])
|
||||||
# return descr
|
# return descr
|
||||||
|
|
||||||
def test_rebuild():
|
#def test_rebuild():
|
||||||
# pouvoir faire une comparaison avec equal
|
# # pouvoir faire une comparaison avec equal
|
||||||
d = {"s1.s2.s3.s4.a": True, "int": 43, "s2.b":True, "s3.c": True, "s3.d":[1,2,3]}
|
# d = {"s1.s2.s3.s4.a": True, "int": 43, "s2.b":True, "s3.c": True, "s3.d":[1,2,3]}
|
||||||
cfg = reverse_from_paths(d)
|
# cfg = reverse_from_paths(d)
|
||||||
assert cfg.s1.s2.s3.s4.a == True
|
# assert cfg.s1.s2.s3.s4.a == True
|
||||||
assert cfg.int == 43
|
# assert cfg.int == 43
|
||||||
assert cfg.s2.b == True
|
# assert cfg.s2.b == True
|
||||||
assert cfg.s3.c == True
|
# assert cfg.s3.c == True
|
||||||
assert cfg.s3.d == [1,2,3]
|
# assert cfg.s3.d == [1,2,3]
|
||||||
|
|
||||||
# assert config.getpaths() == ['gc.name', 'gc.dummy', 'gc.float', 'bool',
|
# assert config.getpaths() == ['gc.name', 'gc.dummy', 'gc.float', 'bool',
|
||||||
# 'objspace', 'wantref', 'str', 'wantframework',
|
# 'objspace', 'wantref', 'str', 'wantframework',
|
||||||
|
|
|
@ -26,31 +26,50 @@ from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
|
||||||
MandatoryError, MethodCallError, NoValueReturned)
|
MandatoryError, MethodCallError, NoValueReturned)
|
||||||
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
||||||
Multi, apply_requires)
|
Multi, apply_requires)
|
||||||
from tiramisu.setting import settings, groups, owners
|
from tiramisu.setting import groups, owners, Setting
|
||||||
|
from tiramisu.value import OptionValues
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
class Config(object):
|
class Config(object):
|
||||||
"main configuration management entry"
|
"main configuration management entry"
|
||||||
_cfgimpl_toplevel = None
|
_cfgimpl_toplevel = None
|
||||||
|
|
||||||
def __init__(self, descr, parent=None):
|
def __init__(self, descr, parent=None, context=None):
|
||||||
""" Configuration option management master class
|
""" Configuration option management master class
|
||||||
:param descr: describes the configuration schema
|
:param descr: describes the configuration schema
|
||||||
:type descr: an instance of ``option.OptionDescription``
|
:type descr: an instance of ``option.OptionDescription``
|
||||||
:param parent: is None if the ``Config`` is root parent Config otherwise
|
:param parent: is None if the ``Config`` is root parent Config otherwise
|
||||||
:type parent: ``Config``
|
:type parent: ``Config``
|
||||||
|
:param context: the current root config
|
||||||
|
:type context: `Config`
|
||||||
"""
|
"""
|
||||||
self._cfgimpl_descr = descr
|
self._cfgimpl_descr = descr
|
||||||
self._cfgimpl_value_owners = {}
|
|
||||||
self._cfgimpl_parent = parent
|
self._cfgimpl_parent = parent
|
||||||
"`Config()` indeed is in charge of the `Option()`'s values"
|
if parent == None:
|
||||||
self._cfgimpl_values = {}
|
self._cfgimpl_settings = Setting()
|
||||||
self._cfgimpl_previous_values = {}
|
self._cfgimpl_values = OptionValues()
|
||||||
|
else:
|
||||||
|
if context is None:
|
||||||
|
raise ConfigError("cannot find a value for this config")
|
||||||
|
self._cfgimpl_settings = None
|
||||||
|
self._cfgimpl_values = None
|
||||||
|
if context is None:
|
||||||
|
self._cfgimpl_context = self
|
||||||
|
else:
|
||||||
|
self._cfgimpl_context = context
|
||||||
"warnings are a great idea, let's make up a better use of it"
|
"warnings are a great idea, let's make up a better use of it"
|
||||||
self._cfgimpl_warnings = []
|
self._cfgimpl_warnings = []
|
||||||
self._cfgimpl_toplevel = self._cfgimpl_get_toplevel()
|
self._cfgimpl_toplevel = self._cfgimpl_get_toplevel()
|
||||||
self._cfgimpl_build()
|
self._cfgimpl_build()
|
||||||
|
|
||||||
|
def cfgimpl_get_settings(self):
|
||||||
|
return self._cfgimpl_context._cfgimpl_settings
|
||||||
|
|
||||||
|
def cfgimpl_set_settings(self, settings):
|
||||||
|
if not isinstance(settings, Setting):
|
||||||
|
raise ConfigError("setting not allowed")
|
||||||
|
self._cfgimpl_context._cfgimpl_settings = settings
|
||||||
|
|
||||||
def _validate_duplicates(self, children):
|
def _validate_duplicates(self, children):
|
||||||
"""duplicates Option names in the schema
|
"""duplicates Option names in the schema
|
||||||
:type children: list of `Option` or `OptionDescription`
|
:type children: list of `Option` or `OptionDescription`
|
||||||
|
@ -77,34 +96,35 @@ class Config(object):
|
||||||
childdef = Multi(copy(child.getdefault()), config=self,
|
childdef = Multi(copy(child.getdefault()), config=self,
|
||||||
opt=child)
|
opt=child)
|
||||||
max_len_child = max(max_len_child, len(childdef))
|
max_len_child = max(max_len_child, len(childdef))
|
||||||
self._cfgimpl_values[child._name] = childdef
|
self._cfgimpl_context._cfgimpl_values[child] = childdef
|
||||||
self._cfgimpl_previous_values[child._name] = list(childdef)
|
self._cfgimpl_context._cfgimpl_values.previous_values[child] = list(childdef)
|
||||||
else:
|
else:
|
||||||
childdef = child.getdefault()
|
childdef = child.getdefault()
|
||||||
self._cfgimpl_values[child._name] = childdef
|
self._cfgimpl_context._cfgimpl_values[child] = childdef
|
||||||
self._cfgimpl_previous_values[child._name] = childdef
|
self._cfgimpl_context._cfgimpl_values.previous_values[child] = childdef
|
||||||
child.setowner(self, owners.default)
|
child.setowner(self, owners.default)
|
||||||
elif isinstance(child, OptionDescription):
|
elif isinstance(child, OptionDescription):
|
||||||
self._validate_duplicates(child._children)
|
self._validate_duplicates(child._children)
|
||||||
self._cfgimpl_values[child._name] = Config(child, parent=self)
|
self._cfgimpl_context._cfgimpl_values[child] = Config(child, parent=self,
|
||||||
|
context=self._cfgimpl_context)
|
||||||
|
|
||||||
def cfgimpl_update(self):
|
# def cfgimpl_update(self):
|
||||||
"""dynamically adds `Option()` or `OptionDescription()`
|
# """dynamically adds `Option()` or `OptionDescription()`
|
||||||
"""
|
# """
|
||||||
# FIXME this is an update for new options in the schema only
|
# # FIXME this is an update for new options in the schema only
|
||||||
# see the update_child() method of the descr object
|
# # see the update_child() method of the descr object
|
||||||
for child in self._cfgimpl_descr._children:
|
# for child in self._cfgimpl_descr._children:
|
||||||
if isinstance(child, Option):
|
# if isinstance(child, Option):
|
||||||
if child._name not in self._cfgimpl_values:
|
# if child._name not in self._cfgimpl_values:
|
||||||
if child.is_multi():
|
# if child.is_multi():
|
||||||
self._cfgimpl_values[child._name] = Multi(
|
# self._cfgimpl_values[child._name] = Multi(
|
||||||
copy(child.getdefault()), config=self, opt=child)
|
# copy(child.getdefault()), config=self, opt=child)
|
||||||
else:
|
# else:
|
||||||
self._cfgimpl_values[child._name] = copy(child.getdefault())
|
# self._cfgimpl_values[child._name] = copy(child.getdefault())
|
||||||
child.setowner(self, owners.default)
|
# child.setowner(self, owners.default)
|
||||||
elif isinstance(child, OptionDescription):
|
# elif isinstance(child, OptionDescription):
|
||||||
if child._name not in self._cfgimpl_values:
|
# if child._name not in self._cfgimpl_values:
|
||||||
self._cfgimpl_values[child._name] = Config(child, parent=self)
|
# self._cfgimpl_values[child._name] = Config(child, parent=self)
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# attribute methods
|
# attribute methods
|
||||||
|
@ -118,7 +138,8 @@ class Config(object):
|
||||||
return setattr(homeconfig, name, value)
|
return setattr(homeconfig, name, value)
|
||||||
if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
|
if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
|
||||||
self._validate(name, getattr(self._cfgimpl_descr, name))
|
self._validate(name, getattr(self._cfgimpl_descr, name))
|
||||||
self.setoption(name, value, settings.get_owner())
|
self.setoption(name, value,
|
||||||
|
self._cfgimpl_context._cfgimpl_settings.get_owner())
|
||||||
|
|
||||||
def _validate(self, name, opt_or_descr, permissive=False):
|
def _validate(self, name, opt_or_descr, permissive=False):
|
||||||
"validation for the setattr and the getattr"
|
"validation for the setattr and the getattr"
|
||||||
|
@ -128,10 +149,10 @@ class Config(object):
|
||||||
raise TypeError('Unexpected object: {0}'.format(repr(opt_or_descr)))
|
raise TypeError('Unexpected object: {0}'.format(repr(opt_or_descr)))
|
||||||
properties = copy(opt_or_descr.properties)
|
properties = copy(opt_or_descr.properties)
|
||||||
for proper in copy(properties):
|
for proper in copy(properties):
|
||||||
if not settings.has_property(proper):
|
if not self._cfgimpl_context._cfgimpl_settings.has_property(proper):
|
||||||
properties.remove(proper)
|
properties.remove(proper)
|
||||||
if permissive:
|
if permissive:
|
||||||
for perm in settings.permissive:
|
for perm in self._cfgimpl_context._cfgimpl_settings.permissive:
|
||||||
if perm in properties:
|
if perm in properties:
|
||||||
properties.remove(perm)
|
properties.remove(perm)
|
||||||
if properties != []:
|
if properties != []:
|
||||||
|
@ -142,15 +163,15 @@ class Config(object):
|
||||||
|
|
||||||
def _is_empty(self, opt):
|
def _is_empty(self, opt):
|
||||||
"convenience method to know if an option is empty"
|
"convenience method to know if an option is empty"
|
||||||
if (not opt.is_multi() and self._cfgimpl_values[opt._name] == None) or \
|
if (not opt.is_multi() and self._cfgimpl_context._cfgimpl_values[opt] == None) or \
|
||||||
(opt.is_multi() and (self._cfgimpl_values[opt._name] == [] or \
|
(opt.is_multi() and (self._cfgimpl_context._cfgimpl_values[opt] == [] or \
|
||||||
None in self._cfgimpl_values[opt._name])):
|
None in self._cfgimpl_context._cfgimpl_values[opt])):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _test_mandatory(self, path, opt):
|
def _test_mandatory(self, path, opt):
|
||||||
# mandatory options
|
# mandatory options
|
||||||
mandatory = settings.mandatory
|
mandatory = self._cfgimpl_context._cfgimpl_settings.mandatory
|
||||||
if opt.is_mandatory() and mandatory:
|
if opt.is_mandatory() and mandatory:
|
||||||
if self._is_empty(opt) and \
|
if self._is_empty(opt) and \
|
||||||
opt.is_empty_by_default():
|
opt.is_empty_by_default():
|
||||||
|
@ -160,10 +181,11 @@ class Config(object):
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return self._getattr(name)
|
return self._getattr(name)
|
||||||
|
|
||||||
def fill_multi(self, name, result, use_default_multi=False, default_multi=None):
|
def fill_multi(self, opt, result, use_default_multi=False, default_multi=None):
|
||||||
"""fills a multi option with default and calculated values
|
"""fills a multi option with default and calculated values
|
||||||
"""
|
"""
|
||||||
value = self._cfgimpl_values[name]
|
# FIXME C'EST ENCORE DU N'IMPORTE QUOI
|
||||||
|
value = self._cfgimpl_context._cfgimpl_values[opt]
|
||||||
if not isinstance(result, list):
|
if not isinstance(result, list):
|
||||||
_result = [result]
|
_result = [result]
|
||||||
else:
|
else:
|
||||||
|
@ -175,7 +197,7 @@ class Config(object):
|
||||||
attribute notation mechanism for accessing the value of an option
|
attribute notation mechanism for accessing the value of an option
|
||||||
:param name: attribute name
|
:param name: attribute name
|
||||||
:param permissive: permissive doesn't raise some property error
|
:param permissive: permissive doesn't raise some property error
|
||||||
(see ``settings.permissive``)
|
(see ``permissive``)
|
||||||
:return: option's value if name is an option name, OptionDescription
|
:return: option's value if name is an option name, OptionDescription
|
||||||
otherwise
|
otherwise
|
||||||
"""
|
"""
|
||||||
|
@ -189,7 +211,7 @@ class Config(object):
|
||||||
if type(opt_or_descr) == SymLinkOption:
|
if type(opt_or_descr) == SymLinkOption:
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
rootconfig = self._cfgimpl_get_toplevel()
|
||||||
return getattr(rootconfig, opt_or_descr.path)
|
return getattr(rootconfig, opt_or_descr.path)
|
||||||
if name not in self._cfgimpl_values:
|
if opt_or_descr not in self._cfgimpl_context._cfgimpl_values:
|
||||||
raise AttributeError("%s object has no attribute %s" %
|
raise AttributeError("%s object has no attribute %s" %
|
||||||
(self.__class__, name))
|
(self.__class__, name))
|
||||||
self._validate(name, opt_or_descr, permissive)
|
self._validate(name, opt_or_descr, permissive)
|
||||||
|
@ -202,7 +224,7 @@ class Config(object):
|
||||||
if not isinstance(opt_or_descr, OptionDescription):
|
if not isinstance(opt_or_descr, OptionDescription):
|
||||||
# options with callbacks
|
# options with callbacks
|
||||||
if opt_or_descr.has_callback():
|
if opt_or_descr.has_callback():
|
||||||
value = self._cfgimpl_values[name]
|
value = self._cfgimpl_context._cfgimpl_values[opt_or_descr]
|
||||||
if (not opt_or_descr.is_frozen() or \
|
if (not opt_or_descr.is_frozen() or \
|
||||||
not opt_or_descr.is_forced_on_freeze()) and \
|
not opt_or_descr.is_forced_on_freeze()) and \
|
||||||
not opt_or_descr.is_default_owner(self):
|
not opt_or_descr.is_default_owner(self):
|
||||||
|
@ -214,7 +236,7 @@ class Config(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if opt_or_descr.is_multi():
|
if opt_or_descr.is_multi():
|
||||||
_result = self.fill_multi(name, result)
|
_result = self.fill_multi(opt_or_descr, result)
|
||||||
else:
|
else:
|
||||||
# this result **shall not** be a list
|
# this result **shall not** be a list
|
||||||
if isinstance(result, list):
|
if isinstance(result, list):
|
||||||
|
@ -222,22 +244,22 @@ class Config(object):
|
||||||
' for option {0} : shall not be a list'.format(name))
|
' for option {0} : shall not be a list'.format(name))
|
||||||
_result = result
|
_result = result
|
||||||
if _result != None and not opt_or_descr.validate(_result,
|
if _result != None and not opt_or_descr.validate(_result,
|
||||||
settings.validator):
|
self._cfgimpl_context._cfgimpl_settings.validator):
|
||||||
raise ConfigError('invalid calculated value returned'
|
raise ConfigError('invalid calculated value returned'
|
||||||
' for option {0}'.format(name))
|
' for option {0}'.format(name))
|
||||||
self._cfgimpl_values[name] = _result
|
self._cfgimpl_context._cfgimpl_values[opt_or_descr] = _result
|
||||||
opt_or_descr.setowner(self, owners.default)
|
opt_or_descr.setowner(self, owners.default)
|
||||||
# frozen and force default
|
# frozen and force default
|
||||||
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
|
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
|
||||||
value = opt_or_descr.getdefault()
|
value = opt_or_descr.getdefault()
|
||||||
if opt_or_descr.is_multi():
|
if opt_or_descr.is_multi():
|
||||||
value = self.fill_multi(name, value,
|
value = self.fill_multi(opt_or_descr, value,
|
||||||
use_default_multi=True,
|
use_default_multi=True,
|
||||||
default_multi=opt_or_descr.getdefault_multi())
|
default_multi=opt_or_descr.getdefault_multi())
|
||||||
self._cfgimpl_values[name] = value
|
self._cfgimpl_context._cfgimpl_values[opt_or_descr] = value
|
||||||
opt_or_descr.setowner(self, owners.default)
|
opt_or_descr.setowner(self, owners.default)
|
||||||
self._test_mandatory(name, opt_or_descr)
|
self._test_mandatory(name, opt_or_descr)
|
||||||
value = self._cfgimpl_values[name]
|
value = self._cfgimpl_context._cfgimpl_values[opt_or_descr]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def unwrap_from_name(self, name):
|
def unwrap_from_name(self, name):
|
||||||
|
@ -274,7 +296,7 @@ class Config(object):
|
||||||
child = getattr(self._cfgimpl_descr, name)
|
child = getattr(self._cfgimpl_descr, name)
|
||||||
if type(child) != SymLinkOption:
|
if type(child) != SymLinkOption:
|
||||||
if who == None:
|
if who == None:
|
||||||
who = settings.owner
|
who = self._cfgimpl_context._cfgimpl_settings.owner
|
||||||
if child.is_multi():
|
if child.is_multi():
|
||||||
if not isinstance(who, owners.DefaultOwner):
|
if not isinstance(who, owners.DefaultOwner):
|
||||||
if type(value) != Multi:
|
if type(value) != Multi:
|
||||||
|
@ -284,7 +306,7 @@ class Config(object):
|
||||||
raise ConfigError("invalid value for option:"
|
raise ConfigError("invalid value for option:"
|
||||||
" {0} that is set to multi".format(name))
|
" {0} that is set to multi".format(name))
|
||||||
else:
|
else:
|
||||||
value = self.fill_multi(name, child.getdefault(),
|
value = self.fill_multi(child, child.getdefault(),
|
||||||
use_default_multi=True,
|
use_default_multi=True,
|
||||||
default_multi=child.getdefault_multi())
|
default_multi=child.getdefault_multi())
|
||||||
if not isinstance(who, owners.Owner):
|
if not isinstance(who, owners.Owner):
|
||||||
|
@ -316,7 +338,8 @@ class Config(object):
|
||||||
pass
|
pass
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
raise e # HiddenOptionError or DisabledOptionError
|
raise e # HiddenOptionError or DisabledOptionError
|
||||||
homeconfig.setoption(name, value, settings.get_owner())
|
homeconfig.setoption(name, value,
|
||||||
|
self._cfgimpl_context._cfgimpl_settings.get_owner())
|
||||||
elif len(candidates) > 1:
|
elif len(candidates) > 1:
|
||||||
raise AmbigousOptionError(
|
raise AmbigousOptionError(
|
||||||
'more than one option that ends with %s' % (key, ))
|
'more than one option that ends with %s' % (key, ))
|
||||||
|
@ -371,14 +394,15 @@ class Config(object):
|
||||||
obj = obj._cfgimpl_parent
|
obj = obj._cfgimpl_parent
|
||||||
return ".".join(subpath)
|
return ".".join(subpath)
|
||||||
# ______________________________________________________________________
|
# ______________________________________________________________________
|
||||||
def cfgimpl_previous_value(self, path):
|
# def cfgimpl_previous_value(self, path):
|
||||||
"stores the previous value"
|
# "stores the previous value"
|
||||||
home, name = self._cfgimpl_get_home_by_path(path)
|
# home, name = self._cfgimpl_get_home_by_path(path)
|
||||||
return home._cfgimpl_previous_values[name]
|
# # FIXME fucking name
|
||||||
|
# return home._cfgimpl_context._cfgimpl_values.previous_values[name]
|
||||||
|
|
||||||
def get_previous_value(self, name):
|
# def get_previous_value(self, name):
|
||||||
"for the time being, only the previous Option's value is accessible"
|
# "for the time being, only the previous Option's value is accessible"
|
||||||
return self._cfgimpl_previous_values[name]
|
# return self._cfgimpl_context._cfgimpl_values.previous_values[name]
|
||||||
# ______________________________________________________________________
|
# ______________________________________________________________________
|
||||||
def add_warning(self, warning):
|
def add_warning(self, warning):
|
||||||
"Config implements its own warning pile. Could be useful"
|
"Config implements its own warning pile. Could be useful"
|
||||||
|
@ -420,7 +444,7 @@ class Config(object):
|
||||||
can be filtered by categories (families, or whatever).
|
can be filtered by categories (families, or whatever).
|
||||||
:param group_type: if defined, is an instance of `groups.GroupType`
|
:param group_type: if defined, is an instance of `groups.GroupType`
|
||||||
or `groups.MasterGroupType` that lives in
|
or `groups.MasterGroupType` that lives in
|
||||||
`settings.groups`
|
`setting.groups`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if group_type is not None:
|
if group_type is not None:
|
||||||
|
@ -592,9 +616,10 @@ def mandatory_warnings(config):
|
||||||
where no value has been set
|
where no value has been set
|
||||||
|
|
||||||
:returns: generator of mandatory Option's path
|
:returns: generator of mandatory Option's path
|
||||||
|
FIXME : CAREFULL : not multi-user
|
||||||
"""
|
"""
|
||||||
mandatory = settings.mandatory
|
mandatory = config._cfgimpl_context._cfgimpl_settings.mandatory
|
||||||
settings.mandatory = True
|
config._cfgimpl_context._cfgimpl_settings.mandatory = True
|
||||||
for path in config._cfgimpl_descr.getpaths(include_groups=True):
|
for path in config._cfgimpl_descr.getpaths(include_groups=True):
|
||||||
try:
|
try:
|
||||||
value = config._getattr(path, permissive=True)
|
value = config._getattr(path, permissive=True)
|
||||||
|
@ -602,4 +627,4 @@ def mandatory_warnings(config):
|
||||||
yield path
|
yield path
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError:
|
||||||
pass
|
pass
|
||||||
settings.mandatory = mandatory
|
config._cfgimpl_context._cfgimpl_settings.mandatory = mandatory
|
||||||
|
|
|
@ -26,7 +26,7 @@ from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||||
RequiresError, RequirementRecursionError, MandatoryError,
|
RequiresError, RequirementRecursionError, MandatoryError,
|
||||||
PropertiesOptionError)
|
PropertiesOptionError)
|
||||||
from tiramisu.autolib import carry_out_calculation
|
from tiramisu.autolib import carry_out_calculation
|
||||||
from tiramisu.setting import settings, groups, owners
|
from tiramisu.setting import groups, owners
|
||||||
|
|
||||||
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||||
|
|
||||||
|
@ -53,13 +53,15 @@ class Multi(list):
|
||||||
super(Multi, self).__init__(lst)
|
super(Multi, self).__init__(lst)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
self._setvalue(value, key, who=settings.get_owner())
|
self._setvalue(value, key,
|
||||||
|
who=self.config._cfgimpl_context._cfgimpl_settings.get_owner())
|
||||||
|
|
||||||
def append(self, value):
|
def append(self, value):
|
||||||
"""the list value can be updated (appened)
|
"""the list value can be updated (appened)
|
||||||
only if the option is a master
|
only if the option is a master
|
||||||
"""
|
"""
|
||||||
self._setvalue(value, who=settings.get_owner())
|
self._setvalue(value,
|
||||||
|
who=self.config._cfgimpl_context._cfgimpl_settings.get_owner())
|
||||||
|
|
||||||
def _setvalue(self, value, key=None, who=None):
|
def _setvalue(self, value, key=None, who=None):
|
||||||
if value != None:
|
if value != None:
|
||||||
|
@ -76,7 +78,7 @@ class Multi(list):
|
||||||
raise TypeError("invalid owner {0} for the value {1}".format(
|
raise TypeError("invalid owner {0} for the value {1}".format(
|
||||||
str(who), str(value)))
|
str(who), str(value)))
|
||||||
self.opt.setowner(self.config, getattr(owners, who))
|
self.opt.setowner(self.config, getattr(owners, who))
|
||||||
self.config._cfgimpl_previous_values[self.opt._name] = oldvalue
|
self.config._cfgimpl_context._cfgimpl_values.previous_values[self.opt] = oldvalue
|
||||||
|
|
||||||
def pop(self, key):
|
def pop(self, key):
|
||||||
"""the list value can be updated (poped)
|
"""the list value can be updated (poped)
|
||||||
|
@ -86,8 +88,9 @@ class Multi(list):
|
||||||
:return: the requested element
|
:return: the requested element
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.opt.setowner(self.config, settings.get_owner())
|
self.opt.setowner(self.config,
|
||||||
self.config._cfgimpl_previous_values[self.opt._name] = list(self)
|
self.config._cfgimpl_context._cfgimpl_settings.get_owner())
|
||||||
|
self.config._cfgimpl_context._cfgimpl_values.previous_values[self.opt] = list(self)
|
||||||
return super(Multi, self).pop(key)
|
return super(Multi, self).pop(key)
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
#
|
#
|
||||||
|
@ -260,11 +263,11 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
if not isinstance(owner, owners.Owner):
|
if not isinstance(owner, owners.Owner):
|
||||||
raise ConfigError("invalid type owner for option: {0}".format(
|
raise ConfigError("invalid type owner for option: {0}".format(
|
||||||
str(name)))
|
str(name)))
|
||||||
config._cfgimpl_value_owners[name] = owner
|
config._cfgimpl_context._cfgimpl_values.owners[self] = owner
|
||||||
|
|
||||||
def getowner(self, config):
|
def getowner(self, config):
|
||||||
"config *must* be only the **parent** config (not the toplevel config)"
|
"config *must* be only the **parent** config (not the toplevel config)"
|
||||||
return config._cfgimpl_value_owners[self._name]
|
return config._cfgimpl_context._cfgimpl_values.owners[self]
|
||||||
|
|
||||||
def reset(self, config):
|
def reset(self, config):
|
||||||
"""resets the default value and owner
|
"""resets the default value and owner
|
||||||
|
@ -285,7 +288,8 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
"""
|
"""
|
||||||
name = self._name
|
name = self._name
|
||||||
rootconfig = config._cfgimpl_get_toplevel()
|
rootconfig = config._cfgimpl_get_toplevel()
|
||||||
if not self.validate(value, settings.validator):
|
if not self.validate(value,
|
||||||
|
config._cfgimpl_context._cfgimpl_settings.validator):
|
||||||
raise ConfigError('invalid value %s for option %s' % (value, name))
|
raise ConfigError('invalid value %s for option %s' % (value, name))
|
||||||
if self.is_mandatory():
|
if self.is_mandatory():
|
||||||
# value shall not be '' for a mandatory option
|
# value shall not be '' for a mandatory option
|
||||||
|
@ -294,26 +298,28 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
value = None
|
value = None
|
||||||
if self.is_multi() and '' in value:
|
if self.is_multi() and '' in value:
|
||||||
value = Multi([{'': None}.get(i, i) for i in value], config, self)
|
value = Multi([{'': None}.get(i, i) for i in value], config, self)
|
||||||
if settings.is_mandatory() and ((self.is_multi() and value == []) or \
|
if config._cfgimpl_context._cfgimpl_settings.is_mandatory() \
|
||||||
|
and ((self.is_multi() and value == []) or \
|
||||||
(not self.is_multi() and value is None)):
|
(not self.is_multi() and value is None)):
|
||||||
raise MandatoryError('cannot change the value to %s for '
|
raise MandatoryError('cannot change the value to %s for '
|
||||||
'option %s' % (value, name))
|
'option %s' % (value, name))
|
||||||
if name not in config._cfgimpl_values:
|
if self not in config._cfgimpl_context._cfgimpl_values:
|
||||||
raise AttributeError('unknown option %s' % (name))
|
raise AttributeError('unknown option %s' % (name))
|
||||||
|
|
||||||
if settings.is_frozen_for_everything():
|
if config._cfgimpl_context._cfgimpl_settings.is_frozen_for_everything():
|
||||||
raise TypeError("cannot set a value to the option {} if the whole "
|
raise TypeError("cannot set a value to the option {} if the whole "
|
||||||
"config has been frozen".format(name))
|
"config has been frozen".format(name))
|
||||||
|
|
||||||
if settings.is_frozen() and self.is_frozen():
|
if config._cfgimpl_context._cfgimpl_settings.is_frozen() \
|
||||||
|
and self.is_frozen():
|
||||||
raise TypeError('cannot change the value to %s for '
|
raise TypeError('cannot change the value to %s for '
|
||||||
'option %s this option is frozen' % (str(value), name))
|
'option %s this option is frozen' % (str(value), name))
|
||||||
apply_requires(self, config)
|
apply_requires(self, config)
|
||||||
if type(config._cfgimpl_values[name]) == Multi:
|
if type(config._cfgimpl_context._cfgimpl_values[self]) == Multi:
|
||||||
config._cfgimpl_previous_values[name] = list(config._cfgimpl_values[name])
|
config._cfgimpl_context._cfgimpl_values.previous_values[self] = list(config._cfgimpl_context._cfgimpl_values[self])
|
||||||
else:
|
else:
|
||||||
config._cfgimpl_previous_values[name] = config._cfgimpl_values[name]
|
config._cfgimpl_context._cfgimpl_values.previous_values[self] = config._cfgimpl_context._cfgimpl_values[self]
|
||||||
config._cfgimpl_values[name] = value
|
config._cfgimpl_context._cfgimpl_values[self] = value
|
||||||
|
|
||||||
def getkey(self, value):
|
def getkey(self, value):
|
||||||
return value
|
return value
|
||||||
|
@ -577,7 +583,8 @@ def apply_requires(opt, config, permissive=False):
|
||||||
except PropertiesOptionError, err:
|
except PropertiesOptionError, err:
|
||||||
properties = err.proptype
|
properties = err.proptype
|
||||||
if permissive:
|
if permissive:
|
||||||
for perm in settings.permissive:
|
for perm in \
|
||||||
|
config._cfgimpl_context._cfgimpl_settings.permissive:
|
||||||
if perm in properties:
|
if perm in properties:
|
||||||
properties.remove(perm)
|
properties.remove(perm)
|
||||||
if properties != []:
|
if properties != []:
|
||||||
|
|
|
@ -205,6 +205,3 @@ class Setting():
|
||||||
|
|
||||||
def get_owner(self):
|
def get_owner(self):
|
||||||
return self.owner
|
return self.owner
|
||||||
|
|
||||||
# Setting is actually a singleton
|
|
||||||
settings = Setting()
|
|
||||||
|
|
160
tiramisu/tool.py
160
tiramisu/tool.py
|
@ -25,90 +25,90 @@ from tiramisu.option import (OptionDescription, Option, ChoiceOption, BoolOption
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# reverse factory
|
# reverse factory
|
||||||
# XXX HAAAAAAAAAAAACK (but possibly a good one)
|
# XXX HAAAAAAAAAAAACK (but possibly a good one)
|
||||||
def reverse_from_paths(data):
|
#def reverse_from_paths(data):
|
||||||
"rebuilds a (fake) data structure from an unflatten `make_dict()` result"
|
# "rebuilds a (fake) data structure from an unflatten `make_dict()` result"
|
||||||
# ____________________________________________________________
|
# # ____________________________________________________________
|
||||||
_build_map = {
|
# _build_map = {
|
||||||
bool: BoolOption,
|
# bool: BoolOption,
|
||||||
int: IntOption,
|
# int: IntOption,
|
||||||
float: FloatOption,
|
# float: FloatOption,
|
||||||
str: StrOption,
|
# str: StrOption,
|
||||||
}
|
# }
|
||||||
def option_factory(name, value):
|
# def option_factory(name, value):
|
||||||
"dummy -> Option('dummy')"
|
# "dummy -> Option('dummy')"
|
||||||
if isinstance(value, list):
|
# if isinstance(value, list):
|
||||||
return _build_map[type(value[0])](name, '', multi=True, default=value)
|
# return _build_map[type(value[0])](name, '', multi=True, default=value)
|
||||||
else:
|
# else:
|
||||||
return _build_map[type(value)](name, '', default=value)
|
# return _build_map[type(value)](name, '', default=value)
|
||||||
|
|
||||||
def build_options(data):
|
# def build_options(data):
|
||||||
"config.gc.dummy -> Option('dummy')"
|
# "config.gc.dummy -> Option('dummy')"
|
||||||
for key, value in data.items():
|
# for key, value in data.items():
|
||||||
name = key.split('.')[-1]
|
# name = key.split('.')[-1]
|
||||||
yield (key, option_factory(name, value))
|
# yield (key, option_factory(name, value))
|
||||||
# ____________________________________________________________
|
# # ____________________________________________________________
|
||||||
def parent(pathname):
|
# def parent(pathname):
|
||||||
"config.gc.dummy -> config.gc"
|
# "config.gc.dummy -> config.gc"
|
||||||
if "." in pathname:
|
# if "." in pathname:
|
||||||
return ".".join(pathname.split('.')[:-1])
|
# return ".".join(pathname.split('.')[:-1])
|
||||||
# no parent except rootconfig, naturally returns None
|
# # no parent except rootconfig, naturally returns None
|
||||||
|
|
||||||
def subgroups(pathname):
|
# def subgroups(pathname):
|
||||||
"config.gc.dummy.bool -> [config.gc, config.gc.dummy]"
|
# "config.gc.dummy.bool -> [config.gc, config.gc.dummy]"
|
||||||
group = parent(pathname)
|
# group = parent(pathname)
|
||||||
parents =[]
|
# parents =[]
|
||||||
while group is not None:
|
# while group is not None:
|
||||||
parents.append(group)
|
# parents.append(group)
|
||||||
group = parent(group)
|
# group = parent(group)
|
||||||
return parents
|
# return parents
|
||||||
|
|
||||||
def build_option_descriptions(data):
|
# def build_option_descriptions(data):
|
||||||
all_groups = []
|
# all_groups = []
|
||||||
for key in data.keys():
|
# for key in data.keys():
|
||||||
for group in subgroups(key):
|
# for group in subgroups(key):
|
||||||
# so group is unique in the list
|
# # so group is unique in the list
|
||||||
if group not in all_groups:
|
# if group not in all_groups:
|
||||||
all_groups.append(group)
|
# all_groups.append(group)
|
||||||
for group in all_groups:
|
# for group in all_groups:
|
||||||
name = group.split('.')[-1]
|
# name = group.split('.')[-1]
|
||||||
yield (group, OptionDescription(name, '', []))
|
# yield (group, OptionDescription(name, '', []))
|
||||||
# ____________________________________________________________
|
# # ____________________________________________________________
|
||||||
descr = OptionDescription('tiramisu', 'fake rebuild structure', [])
|
# descr = OptionDescription('tiramisu', 'fake rebuild structure', [])
|
||||||
cfg = Config(descr)
|
# cfg = Config(descr)
|
||||||
# add descrs in cfg
|
# # add descrs in cfg
|
||||||
def compare(a, b):
|
# def compare(a, b):
|
||||||
l1 = a.split(".")
|
# l1 = a.split(".")
|
||||||
l2 = b.split(".")
|
# l2 = b.split(".")
|
||||||
if len(l1) < len(l2):
|
# if len(l1) < len(l2):
|
||||||
return -1
|
# return -1
|
||||||
elif len(l1) > len(l2):
|
# elif len(l1) > len(l2):
|
||||||
return 1
|
# return 1
|
||||||
else:
|
# else:
|
||||||
return 0
|
# return 0
|
||||||
grps = list(build_option_descriptions(data))
|
# grps = list(build_option_descriptions(data))
|
||||||
groups = dict(grps)
|
# groups = dict(grps)
|
||||||
grp_paths = [pathname for pathname, opt_descr in grps]
|
# grp_paths = [pathname for pathname, opt_descr in grps]
|
||||||
grp_paths.sort(compare)
|
# grp_paths.sort(compare)
|
||||||
for grp in grp_paths:
|
# for grp in grp_paths:
|
||||||
if not "." in grp:
|
# if not "." in grp:
|
||||||
cfg._cfgimpl_descr.add_child(groups[grp])
|
# cfg._cfgimpl_descr.add_child(groups[grp])
|
||||||
cfg.cfgimpl_update()
|
# cfg.cfgimpl_update()
|
||||||
else:
|
# else:
|
||||||
parentdescr = cfg.unwrap_from_path(parent(grp))
|
# parentdescr = cfg.unwrap_from_path(parent(grp))
|
||||||
parentdescr.add_child(groups[grp])
|
# parentdescr.add_child(groups[grp])
|
||||||
getattr(cfg, parent(grp)).cfgimpl_update()
|
# getattr(cfg, parent(grp)).cfgimpl_update()
|
||||||
# add options in descrs
|
# # add options in descrs
|
||||||
for pathname, opt in build_options(data):
|
# for pathname, opt in build_options(data):
|
||||||
current_group_name = parent(pathname)
|
# current_group_name = parent(pathname)
|
||||||
if current_group_name == None:
|
# if current_group_name == None:
|
||||||
cfg._cfgimpl_descr.add_child(opt)
|
# cfg._cfgimpl_descr.add_child(opt)
|
||||||
cfg.cfgimpl_update()
|
# cfg.cfgimpl_update()
|
||||||
else:
|
# else:
|
||||||
curr_grp = groups[current_group_name]
|
# curr_grp = groups[current_group_name]
|
||||||
curr_grp.add_child(opt)
|
# curr_grp.add_child(opt)
|
||||||
getattr(cfg, current_group_name).cfgimpl_update()
|
# getattr(cfg, current_group_name).cfgimpl_update()
|
||||||
|
|
||||||
return cfg
|
# return cfg
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# extendable type
|
# extendable type
|
||||||
class extend(type):
|
class extend(type):
|
||||||
|
|
38
tiramisu/value.py
Normal file
38
tiramisu/value.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"takes care of the option's values"
|
||||||
|
# Copyright (C) 2012 Team tiramisu (see AUTHORS 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
|
||||||
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
class OptionValues(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.owners = {}
|
||||||
|
"Config's root indeed is in charge of the `Option()`'s values"
|
||||||
|
self.values = {}
|
||||||
|
self.previous_values = {}
|
||||||
|
|
||||||
|
def __getitem__(self, opt_or_descr):
|
||||||
|
return self.values[opt_or_descr]
|
||||||
|
|
||||||
|
def __setitem__(self, opt_or_descr, value):
|
||||||
|
self.values[opt_or_descr] = value
|
||||||
|
|
||||||
|
def __contains__(self, opt_or_descr):
|
||||||
|
return opt_or_descr in self.values
|
Loading…
Reference in a new issue