in __setattr__, name should never be object's variable name
authorEmmanuel Garette <egarette@cadoles.com>
Sat, 24 Aug 2013 19:26:10 +0000 (21:26 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Sat, 24 Aug 2013 19:26:10 +0000 (21:26 +0200)
remove context in type_ find's option
find_first_context return AttributError if no results

test/test_cache.py
test/test_config.py
test/test_config_api.py
test/test_metaconfig.py
test/test_parsing_group.py
tiramisu/config.py

index ec51455..47270ee 100644 (file)
@@ -136,6 +136,17 @@ def test_reset_cache():
     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():
     od1 = make_description()
     c = Config(od1)
index 798db46..0f7d7b3 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-"""theses tests are much more to test that config, option description, vs... 
+"""theses tests are much more to test that config, option description, vs...
 **it's there** and answers via attribute access"""
 
 import autopath
@@ -45,6 +45,10 @@ def test_base_config():
     assert dm._name == 'dummy'
 
 
+def test_not_config():
+    assert raises(TypeError, "Config('str')")
+
+
 def test_base_path():
     gcdummy = BoolOption('dummy', 'dummy', default=False)
     descr = OptionDescription('tiramisu', '', [gcdummy])
@@ -147,4 +151,9 @@ def test_information_display():
     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
     root = OptionDescription('root', '', [d1])
     config = Config(root)
-    str(config.od)
+    config.od == """g1 = 1
+g2 = héhé
+g3 = héhé
+g4 = True
+g5 = None"""
+    config == '[od]'
index 599776d..fee50e7 100644 (file)
@@ -48,7 +48,8 @@ def test_compare_configs():
     conf1.gc.dummy = True
     assert conf1 == conf2
     assert hash(conf1) == hash(conf2)
-    #assert conf1.getkey() == conf2.getkey()
+    assert not conf1 == 'conf2'
+    assert conf1 != 'conf2'
 # ____________________________________________________________
 
 
index 304d227..138fb84 100644 (file)
@@ -150,6 +150,7 @@ def test_meta_meta_set():
     conf1.od1.i1 = 8
     assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
     assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8)
+    raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)")
 
 
 def test_not_meta():
index 373aba2..b649207 100644 (file)
@@ -104,6 +104,13 @@ def test_iter_on_empty_group():
     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():
     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)
index 6907507..b3a65db 100644 (file)
@@ -96,7 +96,6 @@ class SubConfig(BaseInformation):
                 try:
                     yield child._name, getattr(self, child._name)
                 except GeneratorExit:
-                    raise Exception('ca passe ici')
                     raise StopIteration
                 except PropertiesOptionError:
                     pass  # option with properties
@@ -175,7 +174,6 @@ class SubConfig(BaseInformation):
     def __setattr__(self, name, value):
         "attribute notation mechanism for the setting of the value of an option"
         if name.startswith('_impl_'):
-            #self.__dict__[name] = value
             object.__setattr__(self, name, value)
             return
         self._setattr(name, value)
@@ -222,17 +220,12 @@ class SubConfig(BaseInformation):
             return homeconfig._getattr(name, force_permissive=force_permissive,
                                        force_properties=force_properties,
                                        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)
-        # symlink options
         if self._impl_path is None:
             subpath = name
         else:
             subpath = self._impl_path + '.' + name
+        # symlink options
         if isinstance(opt_or_descr, SymLinkOption):
             context = self.cfgimpl_get_context()
             path = context.cfgimpl_get_description().impl_get_path_by_opt(
@@ -318,18 +311,7 @@ class SubConfig(BaseInformation):
                 return True
             return False
 
-        #def _filter_by_attrs():
-        #    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'):
+        if type_ not in ('option', 'path', 'value'):
             raise ValueError(_('unknown type_ type {0}'
                                'for _find').format(type_))
         find_results = []
@@ -354,26 +336,25 @@ class SubConfig(BaseInformation):
                     continue
             if not _filter_by_type():
                 continue
-            #if not _filter_by_attrs():
-            #    continue
             if type_ == 'value':
                 retval = value
             elif type_ == 'path':
                 retval = path
             elif type_ == 'option':
                 retval = option
-            elif type_ == 'context':
-                retval = self.cfgimpl_get_context()
             if first:
                 return retval
             else:
                 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 display_error:
                 raise AttributeError(_("no option found in config"
                                        " with these criteria"))
             else:
-                #translation is slow
+                # translation is slow
                 raise AttributeError()
         else:
             return find_results
@@ -620,14 +601,15 @@ class MetaConfig(CommonConfig):
                 pass
 
     def find_first_contexts(self, byname=None, bypath=None, byvalue=None,
-                            type_='context', display_error=True):
+                            type_='path', display_error=True):
         ret = []
         try:
             if bypath is None and byname is not None and \
                     self.cfgimpl_get_description() is not None:
                 bypath = self._find(bytype=None, byvalue=None, byname=byname,
                                     first=True, type_='path',
-                                    check_properties=False)
+                                    check_properties=False,
+                                    display_error=display_error)
         except ConfigError:
             pass
         for child in self._impl_children:
@@ -654,7 +636,7 @@ class MetaConfig(CommonConfig):
                                                          display_error=False))
             except AttributeError:
                 pass
-        return ret
+        return self._find_return_results(ret, display_error)
 
 
 def mandatory_warnings(config):