← Back to team overview

configglue team mailing list archive

[Merge] lp:~ricardokirkner/configglue/inner-classes into lp:configglue

 

Ricardo Kirkner has proposed merging lp:~ricardokirkner/configglue/inner-classes into lp:configglue.

Requested reviews:
  Configglue developers (configglue)

For more details, see:
https://code.launchpad.net/~ricardokirkner/configglue/inner-classes/+merge/61547

This branch introduces support for using inner classes as an improved syntax
for declaring sections in the schema.

Using standard attributes is still supported.
-- 
https://code.launchpad.net/~ricardokirkner/configglue/inner-classes/+merge/61547
Your team Configglue developers is requested to review the proposed merge of lp:~ricardokirkner/configglue/inner-classes into lp:configglue.
=== modified file 'configglue/pyschema/schema.py'
--- configglue/pyschema/schema.py	2011-05-02 15:17:01 +0000
+++ configglue/pyschema/schema.py	2011-05-19 11:58:10 +0000
@@ -37,8 +37,15 @@
 
 
 def get_config_objects(obj):
-    objects = ((n, o) for (n, o) in getmembers(obj)
-        if isinstance(o, (ConfigSection, ConfigOption)))
+    objects = []
+    for name, obj in getmembers(obj):
+        if isinstance(obj, (ConfigSection, ConfigOption)):
+            objects.append((name, obj))
+        elif type(obj) == type and issubclass(obj, ConfigSection):
+            instance = obj()
+            for key, value in get_config_objects(obj):
+                setattr(instance, key, value)
+            objects.append((name, instance))
     return objects
 
 
@@ -96,6 +103,9 @@
         return (self._sections == other._sections and
                 self.includes == other.includes)
 
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
     def is_valid(self):
         """Return whether the schema has a valid structure."""
         explicit_default_section = isinstance(getattr(self, '__main__', None),
@@ -157,6 +167,9 @@
         return (self.name == other.name and
                 self.options() == other.options())
 
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
     def __repr__(self):
         if self.name:
             name = " %s" % self.name
@@ -241,6 +254,9 @@
 
         return equal
 
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
     def __repr__(self):
         extra = ' raw' if self.raw else ''
         extra += ' fatal' if self.fatal else ''

=== modified file 'tests/pyschema/test_parser.py'
--- tests/pyschema/test_parser.py	2011-05-02 16:23:04 +0000
+++ tests/pyschema/test_parser.py	2011-05-19 11:58:10 +0000
@@ -225,11 +225,11 @@
 
     def test_interpolate_across_sections(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
 
-            baz = ConfigSection()
-            baz.wham = IntConfigOption()
+            class baz(ConfigSection):
+                wham = IntConfigOption()
 
         config = StringIO("[foo]\nbar=%(wham)s\n[baz]\nwham=42")
         parser = SchemaConfigParser(MySchema())
@@ -239,11 +239,11 @@
 
     def test_interpolate_invalid_key(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
 
-            baz = ConfigSection()
-            baz.wham = IntConfigOption()
+            class baz(ConfigSection):
+                wham = IntConfigOption()
 
         config = StringIO("[foo]\nbar=%(wham)s\n[baz]\nwham=42")
         parser = SchemaConfigParser(MySchema())
@@ -406,7 +406,8 @@
 
     def test_init_invalid_schema(self):
         class MyInvalidSchema(Schema):
-            __main__ = ConfigSection()
+            class __main__(ConfigSection):
+                pass
 
         self.assertRaises(SchemaValidationError, SchemaConfigParser,
                           MyInvalidSchema())
@@ -434,8 +435,9 @@
     def test_items_interpolate(self):
         class MySchema(Schema):
             foo = StringConfigOption()
-            baz = ConfigSection()
-            baz.bar = StringConfigOption()
+
+            class baz(ConfigSection):
+                bar = StringConfigOption()
 
         parser = SchemaConfigParser(MySchema())
         config = StringIO('[__main__]\nfoo=%(bar)s\n[baz]\nbar=42')
@@ -465,11 +467,11 @@
 
     def test_values_many_sections_same_option(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
 
-            baz = ConfigSection()
-            baz.bar = IntConfigOption()
+            class baz(ConfigSection):
+                bar = IntConfigOption()
 
         config = StringIO("[foo]\nbar=3\n[baz]\nbar=4")
         expected_values = {'foo': {'bar': 3}, 'baz': {'bar': 4}}
@@ -482,11 +484,11 @@
 
     def test_values_many_sections_different_options(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
 
-            bar = ConfigSection()
-            bar.baz = IntConfigOption()
+            class bar(ConfigSection):
+                baz = IntConfigOption()
 
         config = StringIO("[foo]\nbar=3\n[bar]\nbaz=4")
         expected_values = {'foo': {'bar': 3}, 'bar': {'baz': 4}}
@@ -499,8 +501,8 @@
 
     def test_parse_option(self):
         class MyOtherSchema(Schema):
-            foo = ConfigSection()
-            foo.bar = StringConfigOption()
+            class foo(ConfigSection):
+                bar = StringConfigOption()
 
         expected_value = 'baz'
         config = StringIO("[foo]\nbar = baz")
@@ -515,9 +517,9 @@
     def test_default_values(self):
         class MySchema(Schema):
             foo = BoolConfigOption(default=True)
-            bar = ConfigSection()
-            bar.baz = IntConfigOption()
-            bar.bla = StringConfigOption(default='hello')
+            class bar(ConfigSection):
+                baz = IntConfigOption()
+                bla = StringConfigOption(default='hello')
         schema = MySchema()
         config = StringIO("[bar]\nbaz=123")
         expected_values = {'__main__': {'foo': True},
@@ -592,8 +594,8 @@
 
     def test_get_default_from_section(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
         config = StringIO("[__main__]\n")
         expected = '0'
 
@@ -722,7 +724,8 @@
     def test_write(self):
         class MySchema(Schema):
             foo = StringConfigOption()
-            DEFAULTSECT = ConfigSection()
+            class DEFAULTSECT(ConfigSection):
+                pass
         parser = SchemaConfigParser(MySchema())
         expected = u"[{0}]\nbaz = 2\n\n[__main__]\nfoo = bar".format(DEFAULTSECT)
         config = StringIO(expected)

=== modified file 'tests/pyschema/test_schema.py'
--- tests/pyschema/test_schema.py	2011-04-09 15:48:22 +0000
+++ tests/pyschema/test_schema.py	2011-05-19 11:58:10 +0000
@@ -17,7 +17,6 @@
 ###############################################################################
 
 import unittest
-from copy import deepcopy
 from StringIO import StringIO
 
 from configglue.pyschema.parser import SchemaConfigParser
@@ -39,15 +38,15 @@
             foo = BoolConfigOption()
 
         class MyOtherSchema(Schema):
-            web = ConfigSection()
-            web.bar = IntConfigOption()
-            froo = ConfigSection()
-            froo.twaddle = LinesConfigOption(item=BoolConfigOption())
+            class web(ConfigSection):
+                bar = IntConfigOption()
+            class froo(ConfigSection):
+                twaddle = LinesConfigOption(item=BoolConfigOption())
 
         class MyThirdSchema(Schema):
             bar = IntConfigOption()
-            froo = ConfigSection()
-            froo.twaddle = LinesConfigOption(item=BoolConfigOption())
+            class froo(ConfigSection):
+                twaddle = LinesConfigOption(item=BoolConfigOption())
 
         schema = MySchema()
         names = set(s.name for s in schema.sections())
@@ -63,11 +62,12 @@
 
     def test_schema_validation(self):
         class BorkenSchema(Schema):
-            __main__ = ConfigSection()
-            __main__.foo = BoolConfigOption()
+            class __main__(ConfigSection):
+                foo = BoolConfigOption()
 
         class SomeSchema(Schema):
-            mysection = ConfigSection()
+            class mysection(ConfigSection):
+                pass
 
         schema = BorkenSchema()
         self.assertFalse(schema.is_valid())
@@ -78,8 +78,8 @@
     def test_names(self):
         class MySchema(Schema):
             foo = BoolConfigOption()
-            bar = ConfigSection()
-            bar.baz = IntConfigOption()
+            class bar(ConfigSection):
+                baz = IntConfigOption()
 
         schema = MySchema()
         self.assertEquals('foo', schema.foo.name)
@@ -91,8 +91,8 @@
     def test_options(self):
         class MySchema(Schema):
             foo = BoolConfigOption()
-            bar = ConfigSection()
-            bar.baz = IntConfigOption()
+            class bar(ConfigSection):
+                baz = IntConfigOption()
 
         schema = MySchema()
         names = set(s.name for s in schema.options())
@@ -116,17 +116,47 @@
         self.assertNotEqual(MySchema(), OtherSchema())
 
 
+class TestConfigOption(unittest.TestCase):
+    def test_equal(self):
+        opt1 = IntConfigOption(name='opt1')
+        opt2 = IntConfigOption(name='opt2')
+        opt3 = StringConfigOption(name='opt1')
+        self.assertEqual(opt1, opt1)
+        self.assertNotEqual(opt1, opt2)
+        self.assertNotEqual(opt1, opt3)
+
+    def test_equal_when_in_section(self):
+        sect1 = ConfigSection(name='sect1')
+        sect2 = ConfigSection(name='sect2')
+        opt1 = IntConfigOption()
+        opt2 = IntConfigOption()
+
+        self.assertEqual(opt1, opt2)
+
+        opt1.section = sect1
+        opt2.section = sect2
+        self.assertNotEqual(opt1, opt2)
+
+    def test_equal_when_error(self):
+        opt1 = IntConfigOption()
+        opt2 = IntConfigOption()
+
+        # make sure an attribute error is raised
+        del opt2.name
+        self.assertNotEqual(opt1, opt2)
+
+
 class TestSchemaInheritance(unittest.TestCase):
     def setUp(self):
         class SchemaA(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
         class SchemaB(SchemaA):
-            baz = ConfigSection()
-            baz.wham = IntConfigOption()
+            class baz(ConfigSection):
+                wham = IntConfigOption()
         class SchemaC(SchemaA):
-            bar = ConfigSection()
-            bar.woof = IntConfigOption()
+            class bar(ConfigSection):
+                woof = IntConfigOption()
 
         self.schema = SchemaB()
         self.other = SchemaC()
@@ -157,13 +187,13 @@
 
     def test_merge_inherited(self):
         class SchemaA(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
             bar = IntConfigOption()
 
         class SchemaB(SchemaA):
-            foo = deepcopy(SchemaA.foo)
-            foo.baz = IntConfigOption()
+            class foo(SchemaA.foo):
+                baz = IntConfigOption()
 
         # SchemaB inherits attributes from SchemaA and merges its own
         # attributes into

=== modified file 'tests/pyschema/test_schemaconfig.py'
--- tests/pyschema/test_schemaconfig.py	2011-03-19 16:33:01 +0000
+++ tests/pyschema/test_schemaconfig.py	2011-05-19 11:58:10 +0000
@@ -97,9 +97,10 @@
         self.assertNotEqual(sec1, sec2)
 
     def test_has_option(self):
-        sec1 = ConfigSection()
-        sec1.foo = IntConfigOption()
+        class sec1(ConfigSection):
+            foo = IntConfigOption()
 
+        sec1 = sec1()
         self.assertTrue(sec1.has_option('foo'))
         self.assertFalse(sec1.has_option('bar'))
 
@@ -107,8 +108,8 @@
 class TestSchemaConfigGlue(unittest.TestCase):
     def setUp(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.bar = IntConfigOption()
+            class foo(ConfigSection):
+                bar = IntConfigOption()
 
             baz = IntConfigOption(help='The baz option')
 
@@ -152,11 +153,11 @@
 
     def test_ambiguous_option(self):
         class MySchema(Schema):
-            foo = ConfigSection()
-            foo.baz = IntConfigOption()
+            class foo(ConfigSection):
+                baz = IntConfigOption()
 
-            bar = ConfigSection()
-            bar.baz = IntConfigOption()
+            class bar(ConfigSection):
+                baz = IntConfigOption()
 
         config = StringIO("[foo]\nbaz=1")
         parser = SchemaConfigParser(MySchema())


Follow ups