in __setattr__, name should never be object's variable name

remove context in type_ find's option
find_first_context return AttributError if no results
This commit is contained in:
Emmanuel Garette 2013-08-24 21:26:10 +02:00
parent 6708fe4522
commit 4c27cb586d
6 changed files with 42 additions and 31 deletions

View File

@ -136,6 +136,17 @@ def test_reset_cache():
assert 'u2' not in settings._p_.get_cached('property', c) assert 'u2' not in settings._p_.get_cached('property', c)
def test_reset_cache_subconfig():
od1 = make_description()
od2 = OptionDescription('od2', '', [od1])
c = Config(od2)
values = c.cfgimpl_get_values()
c.od1.u1
assert 'od1.u1' in values._p_.get_cached('value', c)
c.od1.cfgimpl_reset_cache()
assert 'od1.u1' not in values._p_.get_cached('value', c)
def test_reset_cache_only_expired(): def test_reset_cache_only_expired():
od1 = make_description() od1 = make_description()
c = Config(od1) c = Config(od1)

View File

@ -45,6 +45,10 @@ def test_base_config():
assert dm._name == 'dummy' assert dm._name == 'dummy'
def test_not_config():
assert raises(TypeError, "Config('str')")
def test_base_path(): def test_base_path():
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) descr = OptionDescription('tiramisu', '', [gcdummy])
@ -147,4 +151,9 @@ def test_information_display():
d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5]) d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
root = OptionDescription('root', '', [d1]) root = OptionDescription('root', '', [d1])
config = Config(root) config = Config(root)
str(config.od) config.od == """g1 = 1
g2 = héhé
g3 = héhé
g4 = True
g5 = None"""
config == '[od]'

View File

@ -48,7 +48,8 @@ def test_compare_configs():
conf1.gc.dummy = True conf1.gc.dummy = True
assert conf1 == conf2 assert conf1 == conf2
assert hash(conf1) == hash(conf2) assert hash(conf1) == hash(conf2)
#assert conf1.getkey() == conf2.getkey() assert not conf1 == 'conf2'
assert conf1 != 'conf2'
# ____________________________________________________________ # ____________________________________________________________

View File

@ -150,6 +150,7 @@ def test_meta_meta_set():
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)")
def test_not_meta(): def test_not_meta():

View File

@ -104,6 +104,13 @@ def test_iter_on_empty_group():
assert [] == list(config) assert [] == list(config)
def test_iter_not_group():
config = Config(OptionDescription("name", "descr", []))
config.read_write()
raises(TypeError, "list(config.iter_groups(group_type='family'))")
def test_groups_with_master(): def test_groups_with_master():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)

View File

@ -96,7 +96,6 @@ class SubConfig(BaseInformation):
try: try:
yield child._name, getattr(self, child._name) yield child._name, getattr(self, child._name)
except GeneratorExit: except GeneratorExit:
raise Exception('ca passe ici')
raise StopIteration raise StopIteration
except PropertiesOptionError: except PropertiesOptionError:
pass # option with properties pass # option with properties
@ -175,7 +174,6 @@ class SubConfig(BaseInformation):
def __setattr__(self, name, value): def __setattr__(self, name, value):
"attribute notation mechanism for the setting of the value of an option" "attribute notation mechanism for the setting of the value of an option"
if name.startswith('_impl_'): if name.startswith('_impl_'):
#self.__dict__[name] = value
object.__setattr__(self, name, value) object.__setattr__(self, name, value)
return return
self._setattr(name, value) self._setattr(name, value)
@ -222,17 +220,12 @@ class SubConfig(BaseInformation):
return homeconfig._getattr(name, force_permissive=force_permissive, return homeconfig._getattr(name, force_permissive=force_permissive,
force_properties=force_properties, force_properties=force_properties,
validate=validate) validate=validate)
# special attributes
if name.startswith('_impl_') or name.startswith('cfgimpl_') \
or name.startswith('impl_'):
# if it were in __dict__ it would have been found already
return object.__getattribute__(self, name)
opt_or_descr = getattr(self.cfgimpl_get_description(), name) opt_or_descr = getattr(self.cfgimpl_get_description(), name)
# symlink options
if self._impl_path is None: if self._impl_path is None:
subpath = name subpath = name
else: else:
subpath = self._impl_path + '.' + name subpath = self._impl_path + '.' + name
# symlink options
if isinstance(opt_or_descr, SymLinkOption): if isinstance(opt_or_descr, SymLinkOption):
context = self.cfgimpl_get_context() context = self.cfgimpl_get_context()
path = context.cfgimpl_get_description().impl_get_path_by_opt( path = context.cfgimpl_get_description().impl_get_path_by_opt(
@ -318,18 +311,7 @@ class SubConfig(BaseInformation):
return True return True
return False return False
#def _filter_by_attrs(): if type_ not in ('option', 'path', 'value'):
# if byattrs is None:
# return True
# for key, val in byattrs.items():
# print "----", path, key
# if path == key or path.endswith('.' + key):
# if value == val:
# return True
# else:
# return False
# return False
if type_ not in ('option', 'path', 'context', 'value'):
raise ValueError(_('unknown type_ type {0}' raise ValueError(_('unknown type_ type {0}'
'for _find').format(type_)) 'for _find').format(type_))
find_results = [] find_results = []
@ -354,26 +336,25 @@ class SubConfig(BaseInformation):
continue continue
if not _filter_by_type(): if not _filter_by_type():
continue continue
#if not _filter_by_attrs():
# continue
if type_ == 'value': if type_ == 'value':
retval = value retval = value
elif type_ == 'path': elif type_ == 'path':
retval = path retval = path
elif type_ == 'option': elif type_ == 'option':
retval = option retval = option
elif type_ == 'context':
retval = self.cfgimpl_get_context()
if first: if first:
return retval return retval
else: else:
find_results.append(retval) find_results.append(retval)
return self._find_return_results(find_results, display_error)
def _find_return_results(self, find_results, display_error):
if find_results == []: if find_results == []:
if display_error: if display_error:
raise AttributeError(_("no option found in config" raise AttributeError(_("no option found in config"
" with these criteria")) " with these criteria"))
else: else:
#translation is slow # translation is slow
raise AttributeError() raise AttributeError()
else: else:
return find_results return find_results
@ -620,14 +601,15 @@ class MetaConfig(CommonConfig):
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_='context', 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)
except ConfigError: except ConfigError:
pass pass
for child in self._impl_children: for child in self._impl_children:
@ -654,7 +636,7 @@ class MetaConfig(CommonConfig):
display_error=False)) display_error=False))
except AttributeError: except AttributeError:
pass pass
return ret return self._find_return_results(ret, display_error)
def mandatory_warnings(config): def mandatory_warnings(config):