← Back to team overview

configglue team mailing list archive

[Merge] lp:~ricardokirkner/configglue/refactor-options-option into lp:configglue

 

Ricardo Kirkner has proposed merging lp:~ricardokirkner/configglue/refactor-options-option into lp:configglue with lp:~ricardokirkner/configglue/refactor-options-tupleoption as a prerequisite.

Requested reviews:
  Configglue developers (configglue)

For more details, see:
https://code.launchpad.net/~ricardokirkner/configglue/refactor-options-option/+merge/64442
-- 
https://code.launchpad.net/~ricardokirkner/configglue/refactor-options-option/+merge/64442
Your team Configglue developers is requested to review the proposed merge of lp:~ricardokirkner/configglue/refactor-options-option into lp:configglue.
=== modified file 'configglue/pyschema/schema.py'
--- configglue/pyschema/schema.py	2011-06-13 18:51:00 +0000
+++ configglue/pyschema/schema.py	2011-06-13 18:51:00 +0000
@@ -24,6 +24,7 @@
     'BoolConfigOption',
     'BoolOption',
     'ConfigOption',
+    'Option',
     'ConfigSection',
     'DictConfigOption',
     'DictOption',
@@ -46,7 +47,7 @@
 def get_config_objects(obj):
     objects = []
     for name, obj in getmembers(obj):
-        if isinstance(obj, (ConfigSection, ConfigOption)):
+        if isinstance(obj, (ConfigSection, Option)):
             objects.append((name, obj))
         elif type(obj) == type and issubclass(obj, ConfigSection):
             instance = obj()
@@ -61,15 +62,15 @@
 
     To define your own configuration schema you should:
      1- Inherit from Schema
-     2- Add ConfigOptions and ConfigSections as class attributes.
+     2- Add Option and ConfigSections as class attributes.
 
     With that your whole configuration schema is defined, and you can now
     load configuration files.
 
-    ConfigOptions that don't go in a ConfigSection will belong in the
+    Options that don't go in a ConfigSection will belong in the
     '__main__' section of the configuration files.
 
-    One ConfigOption comes already defined in Schema, 'includes' in the
+    One Option comes already defined in Schema, 'includes' in the
     '__main__' section, that allows configuration files to include other
     configuration files.
 
@@ -87,7 +88,7 @@
         item.name = name
         if isinstance(item, ConfigSection):
             self._add_section(name, item)
-        elif isinstance(item, ConfigOption):
+        elif isinstance(item, Option):
             self._add_option(name, item)
         # override class attributes with instance attributes to correctly
         # handle schema inheritance
@@ -137,7 +138,7 @@
         return self._sections.values()
 
     def options(self, section=None):
-        """Return all the ConfigOptions within a given section.
+        """Return all the Options within a given section.
 
         If section is omitted, returns all the options in the configuration
         file, flattening out any sections.
@@ -153,7 +154,7 @@
         elif section.name == '__main__':
             class_config_objects = get_config_objects(self.__class__)
             options = [getattr(self, att) for att, _ in class_config_objects
-                           if isinstance(getattr(self, att), ConfigOption)]
+                           if isinstance(getattr(self, att), Option)]
         else:
             options = section.options()
         return options
@@ -162,7 +163,7 @@
 class ConfigSection(object):
     """A group of options.
 
-    This class is just a bag you can dump ConfigOptions in.
+    This class is just a bag you can dump Options in.
 
     After instantiating the Schema, each ConfigSection will know its own
     name.
@@ -187,26 +188,26 @@
         return value
 
     def has_option(self, name):
-        """Return True if a ConfigOption with the given name is available"""
+        """Return True if a Option with the given name is available"""
         opt = getattr(self, name, None)
-        return isinstance(opt, ConfigOption)
+        return isinstance(opt, Option)
 
     def option(self, name):
-        """Return a ConfigOption by name"""
+        """Return a Option by name"""
         opt = getattr(self, name, None)
-        assert opt is not None, "Invalid ConfigOption name '%s'" % name
+        assert opt is not None, "Invalid Option name '%s'" % name
         return opt
 
     def options(self):
-        """Return a list of all available ConfigOptions within this section"""
+        """Return a list of all available Options within this section"""
         return [getattr(self, att) for att in vars(self)
-                if isinstance(getattr(self, att), ConfigOption)]
-
-
-class ConfigOption(object):
+                if isinstance(getattr(self, att), Option)]
+
+
+class Option(object):
     """Base class for Config Options.
 
-    ConfigOptions are never bound to a particular conguration file, and
+    Options are never bound to a particular conguration file, and
     simply describe one particular available option.
 
     They also know how to parse() the content of a config file in to the right
@@ -226,7 +227,7 @@
     file.  Otherwise, the self.default value will be used if the option is
     omitted.
 
-    In runtime, after instantiating the Schema, each ConfigOption will also
+    In runtime, after instantiating the Schema, each Option will also
     know its own name and to which section it belongs.
 
     """
@@ -270,12 +271,12 @@
         extra += ' fatal' if self.fatal else ''
         section = self.section.name if self.section is not None else None
         if section is not None:
-            name = " %s.%s" % (section, self.name)
+            name = " {0}.{1}".format(section, self.name)
         elif self.name:
-            name = " %s" % self.name
+            name = " {0}".format(self.name)
         else:
             name = ''
-        value = "<ConfigOption%s%s>" % (name, extra)
+        value = "<{0}{1}{2}>".format(self.__class__.__name__, name, extra)
         return value
 
     def _get_default(self):
@@ -293,8 +294,8 @@
         return str(value)
 
 
-class BoolOption(ConfigOption):
-    """A ConfigOption that is parsed into a bool"""
+class BoolOption(Option):
+    """A Option that is parsed into a bool"""
 
     def _get_default(self):
         return False
@@ -319,8 +320,8 @@
         return isinstance(value, bool)
 
 
-class IntOption(ConfigOption):
-    """A ConfigOption that is parsed into an int"""
+class IntOption(Option):
+    """A Option that is parsed into an int"""
 
     def _get_default(self):
         return 0
@@ -340,12 +341,12 @@
         return isinstance(value, int)
 
 
-class ListOption(ConfigOption):
-    """A ConfigOption that is parsed into a list of objects
+class ListOption(Option):
+    """A Option that is parsed into a list of objects
 
     All items in the list need to be of the same type.  The 'item' constructor
     argument determines the type of the list items. item should be another
-    child of ConfigOption.
+    child of Option.
 
     self.require_parser will be True if the item provided in turn has
     require_parser == True.
@@ -394,8 +395,8 @@
         return isinstance(value, list)
 
 
-class StringOption(ConfigOption):
-    """A ConfigOption that is parsed into a string.
+class StringOption(Option):
+    """A Option that is parsed into a string.
 
     If null==True, a value of 'None' will be parsed in to None instead of
     just leaving it as the string 'None'.
@@ -434,8 +435,8 @@
         return isinstance(value, basestring)
 
 
-class TupleOption(ConfigOption):
-    """A ConfigOption that is parsed into a fixed-size tuple of strings.
+class TupleOption(Option):
+    """A Option that is parsed into a fixed-size tuple of strings.
 
     The number of items in the tuple should be specified with the 'length'
     constructor argument.
@@ -476,8 +477,8 @@
         return isinstance(value, tuple)
 
 
-class DictOption(ConfigOption):
-    """A ConfigOption that is parsed into a dictionary.
+class DictOption(Option):
+    """A Option that is parsed into a dictionary.
 
     In the configuration file you'll need to specify the name of a section,
     and all that section's items will be parsed as a dictionary.
@@ -485,7 +486,7 @@
     The available keys for the dict are specified with the 'spec' constructor
     argument, that should be in turn a dictionary.  spec's keys are the
     available keys for the config file, and spec's values should be
-    ConfigOptions that will be used to parse the values in the config file.
+    Options that will be used to parse the values in the config file.
 
     """
 
@@ -616,3 +617,7 @@
 
 class TupleConfigOption(TupleOption):
     __metaclass__ = DeprecatedOption
+
+
+class ConfigOption(Option):
+    __metaclass__ = DeprecatedOption

=== modified file 'doc/howto/custom-schema-options.rst'
--- doc/howto/custom-schema-options.rst	2011-06-13 18:51:00 +0000
+++ doc/howto/custom-schema-options.rst	2011-06-13 18:51:00 +0000
@@ -18,28 +18,28 @@
 configglue's built-in option types don't cover every possible data type --
 only the common types, such as ``bool`` and ``int``. For more obscure data
 types, such as complex numbers or even user-created types you can define your
-own configglue :class:`~configglue.pyschema.schema.ConfigOption` subclasses.
+own configglue :class:`~configglue.pyschema.schema.Option` subclasses.
 
 Writing an option subclass
 ==========================
 
-When planning your :class:`~configglue.pyschema.schema.ConfigOption` subclass,
+When planning your :class:`~configglue.pyschema.schema.Option` subclass,
 first give some thought to which existing
-:class:`~configglue.pyschema.schema.ConfigOption` class your new option
+:class:`~configglue.pyschema.schema.Option` class your new option
 is most similar to. Can you subclass an existing configglue option and save
 yourself some work? If not, you should subclass the
-:class:`~configglue.pyschema.schema.ConfigOption` class, from which everything
+:class:`~configglue.pyschema.schema.Option` class, from which everything
 is descended.
 
 Initializing your new option is a matter of separating out any arguments that are
 specific to your case from the common arguments and passing the latter to the
-:meth:`~configglue.pyschema.schema.ConfigOption.__init__` method of
-:class:`~configglue.pyschema.schema.ConfigOption` (or your parent class).
+:meth:`~configglue.pyschema.schema.Option.__init__` method of
+:class:`~configglue.pyschema.schema.Option` (or your parent class).
 
 In our example, we'll call our option ``UpperCaseDictOption``. (It's a
-good idea to call your :class:`~configglue.pyschema.schema.ConfigOption`
-subclass ``<Something>ConfigOption``, so it's easily identifiable as a
-:class:`~configglue.pyschema.schema.ConfigOption` subclass.) It behaves
+good idea to call your :class:`~configglue.pyschema.schema.Option`
+subclass ``<Something>Option``, so it's easily identifiable as a
+:class:`~configglue.pyschema.schema.Option` subclass.) It behaves
 mostly like a :class:`~configglue.pyschema.schema.DictOption`, so we'll
 subclass from that::
 

=== modified file 'doc/index.rst'
--- doc/index.rst	2011-04-21 02:42:18 +0000
+++ doc/index.rst	2011-06-13 18:51:00 +0000
@@ -35,7 +35,7 @@
 
     * **Schemas:**
       :doc:`Schema syntax <topics/schemas>` |
-      :doc:`ConfigOption types <ref/schemas/options>`
+      :doc:`Option types <ref/schemas/options>`
 
     * **Advanced:**
       :doc:`Custom options <howto/custom-schema-options>`

=== modified file 'doc/ref/schemas/options.rst'
--- doc/ref/schemas/options.rst	2011-06-13 18:51:00 +0000
+++ doc/ref/schemas/options.rst	2011-06-13 18:51:00 +0000
@@ -21,7 +21,7 @@
     :mod:`configglue.pyschema.schema`, but for convenience they're imported
     into :mod:`configglue.pyschema`; the standard convention is to use
     ``from configglue import pyschema`` and refer to classes as
-    ``pyschema.<Foo>ConfigOption``.
+    ``pyschema.<Foo>Option``.
 
 .. _common-schema-option-attributes:
 
@@ -34,7 +34,7 @@
 ``name``
 --------
 
-.. attribute:: ConfigOption.name
+.. attribute:: Option.name
 
 The name of the option. This will be automatically set to the name assigned to
 the option in the schema definition.
@@ -42,7 +42,7 @@
 ``raw``
 -------
 
-.. attribute:: ConfigOption.raw
+.. attribute:: Option.raw
 
 If ``True``, variable interpolation will not be carried out for this option.
 
@@ -51,7 +51,7 @@
 ``default``
 -----------
 
-.. attribute:: ConfigOption.default
+.. attribute:: Option.default
 
 The default value for this option, if none is provided in the config file.
 
@@ -60,7 +60,7 @@
 ``fatal``
 ---------
 
-.. attribute:: ConfigOption.fatal
+.. attribute:: Option.fatal
 
 If ``True``, ``SchemaConfigParser.parse_all`` will raise an exception if no
 value is provided in the configuration file for this option. Otherwise,
@@ -71,7 +71,7 @@
 ``help``
 --------
 
-.. attribute:: ConfigOption.help
+.. attribute:: Option.help
 
 The help text describing this option. This text will be used as the
 ``optparse.OptParser`` help text.
@@ -81,7 +81,7 @@
 ``section``
 -----------
 
-.. attribute:: ConfigOption.section
+.. attribute:: Option.section
 
 The :class:`~configglue.pyschema.ConfigSection` object where this option was
 defined.
@@ -91,7 +91,7 @@
 .. ``action``
 ..  ----------
 ..
-..  .. attribute:: ConfigOption.action
+..  .. attribute:: Option.action
 ..
 ..  lorem ipsum
 .. 
@@ -130,7 +130,7 @@
     *Required*.
 
     List elements will be parsed as being of this type. Should be an
-    instance of a subclass of :class:`~configglue.pyschema.schema.ConfigOption`.
+    instance of a subclass of :class:`~configglue.pyschema.schema.Option`.
 
 .. attribute:: ListOption.remove_duplicates
 
@@ -180,7 +180,7 @@
 
     If not ``None``, should be a ``dict`` instance, such that its values
     are instances of a subclass of
-    :class:`~configglue.pyschema.schema.ConfigOption`.
+    :class:`~configglue.pyschema.schema.Option`.
 
 .. attribute:: DictOption.strict
 
@@ -195,5 +195,5 @@
 
     Any not explicitly defined attributes will be parsed as being
     of this type. This should be an instance of a subclass of
-    :class:`~configglue.pyschema.schema.ConfigOption`.
+    :class:`~configglue.pyschema.schema.Option`.
 

=== modified file 'doc/topics/config-file.rst'
--- doc/topics/config-file.rst	2011-06-13 18:51:00 +0000
+++ doc/topics/config-file.rst	2011-06-13 18:51:00 +0000
@@ -10,7 +10,7 @@
 
     [my_section]
 
-A ConfigOption is matched by a ConfigParser option, which is defined by a
+A Option is matched by a ConfigParser option, which is defined by a
 simple key, value pair, like::
 
     my_option = the value
@@ -35,7 +35,7 @@
 
 A few special considerations have to be kept in mind while working with these
 configuration files. As ConfigParser requires a config file to have at least
-one section defined, any top-level ConfigOptions are added to an implicitely
+one section defined, any top-level Option are added to an implicitely
 defined section called ``__main__``.
 
 Therefore, if you have a schema like::

=== modified file 'doc/topics/schemas.rst'
--- doc/topics/schemas.rst	2011-06-13 18:51:00 +0000
+++ doc/topics/schemas.rst	2011-06-13 18:51:00 +0000
@@ -15,7 +15,7 @@
 
     * Each attribute of the schema represents either a configuration section
       (see :class:`~configglue.pyschema.schema.ConfigSection`) or
-      option (see :class:`~configglue.pyschema.schema.ConfigOption`).
+      option (see :class:`~configglue.pyschema.schema.Option`).
 
 Quick example
 =============
@@ -58,7 +58,7 @@
 ------------
 
 Each option in your schema should be an instance of the appropriate
-:class:`~configglue.pyschema.schema.ConfigOption` class.
+:class:`~configglue.pyschema.schema.Option` class.
 
 configglue ships with a couple of built-in option types; you can find the
 complete list in the :ref:`schema option reference <schema-option-types>`. You
@@ -79,17 +79,17 @@
 <common-schema-option-attributes>`, but here's a quick summary of the most
 often-used ones:
 
-    :attr:`~ConfigOption.default`
+    :attr:`~Option.default`
         The default value for this option, if none is provided in the config file.
         Default is :attr:`configglue.pyschema.schema.NO_DEFAULT`.
 
-    :attr:`~ConfigOption.fatal`
+    :attr:`~Option.fatal`
         If ``True``, :func:`SchemaConfigParser.parse_all` will raise an exception if no
         value is provided in the configuration file for this option. Otherwise,
         :attr:`self.default` will be used. 
         Default is ``False``.
 
-    :attr:`~ConfigOption.help`
+    :attr:`~Option.help`
         The help text describing this option. This text will be used as the
         :class:`optparse.OptParser` help text.
         Default is ``''``.
@@ -139,7 +139,7 @@
 overriding it. In order to achieve this, in your schema subclass, copy the
 parent's attribute explicitely, to avoid modifying the parent schema class.
 Option attributes (derived from
-:class:`~configglue.pyschema.schema.ConfigOption`) will be overridden, as
+:class:`~configglue.pyschema.schema.Option`) will be overridden, as
 expected.
 
 For example::

=== modified file 'tests/pyschema/test_schema.py'
--- tests/pyschema/test_schema.py	2011-06-13 18:51:00 +0000
+++ tests/pyschema/test_schema.py	2011-06-13 18:51:00 +0000
@@ -24,6 +24,7 @@
     BoolConfigOption,
     BoolOption,
     ConfigOption,
+    Option,
     ConfigSection,
     DictConfigOption,
     DictOption,
@@ -153,7 +154,9 @@
             self.assertEqual(type(objects[key]), type(value))
 
 
-class TestConfigOption(unittest.TestCase):
+class TestOption(unittest.TestCase):
+    cls = Option
+
     def test_equal(self):
         opt1 = IntOption(name='opt1')
         opt2 = IntOption(name='opt2')
@@ -183,10 +186,14 @@
         self.assertNotEqual(opt1, opt2)
 
     def test_validate(self):
-        opt = ConfigOption()
+        opt = self.cls()
         self.assertRaises(NotImplementedError, opt.validate, 0)
 
 
+class TestConfigOption(TestOption):
+    cls = ConfigOption
+
+
 class TestSchemaInheritance(unittest.TestCase):
     def setUp(self):
         class SchemaA(Schema):

=== modified file 'tests/pyschema/test_schemaconfig.py'
--- tests/pyschema/test_schemaconfig.py	2011-06-13 18:51:00 +0000
+++ tests/pyschema/test_schemaconfig.py	2011-06-13 18:51:00 +0000
@@ -29,6 +29,7 @@
 from configglue.pyschema.parser import SchemaConfigParser
 from configglue.pyschema.schema import (
     ConfigOption,
+    Option,
     ConfigSection,
     IntOption,
     Schema,
@@ -36,48 +37,54 @@
 )
 
 
-class TestConfigOption(unittest.TestCase):
+class TestOption(unittest.TestCase):
+    cls = Option
+
     def test_repr_name(self):
-        opt = ConfigOption()
-        expected = "<ConfigOption>"
+        opt = self.cls()
+        expected = "<{0}>".format(self.cls.__name__)
         self.assertEqual(repr(opt), expected)
 
-        opt = ConfigOption(name='name')
-        expected = "<ConfigOption name>"
+        opt = self.cls(name='name')
+        expected = "<{0} name>".format(self.cls.__name__)
         self.assertEqual(repr(opt), expected)
 
         sect = ConfigSection(name='sect')
-        opt = ConfigOption(name='name', section=sect)
-        expected = "<ConfigOption sect.name>"
+        opt = self.cls(name='name', section=sect)
+        expected = "<{0} sect.name>".format(self.cls.__name__)
         self.assertEqual(repr(opt), expected)
 
     def test_repr_extra(self):
-        opt = ConfigOption(name='name', raw=True)
-        expected = "<ConfigOption name raw>"
-        self.assertEqual(repr(opt), expected)
-
-        opt = ConfigOption(name='name', fatal=True)
-        expected = "<ConfigOption name fatal>"
-        self.assertEqual(repr(opt), expected)
-
-        opt = ConfigOption(name='name', raw=True, fatal=True)
-        expected = "<ConfigOption name raw fatal>"
+        opt = self.cls(name='name', raw=True)
+        expected = "<{0} name raw>".format(self.cls.__name__)
+        self.assertEqual(repr(opt), expected)
+
+        opt = self.cls(name='name', fatal=True)
+        expected = "<{0} name fatal>".format(self.cls.__name__)
+        self.assertEqual(repr(opt), expected)
+
+        opt = self.cls(name='name', raw=True, fatal=True)
+        expected = "<{0} name raw fatal>".format(self.cls.__name__)
         self.assertEqual(repr(opt), expected)
 
     def test_parse(self):
-        opt = ConfigOption()
+        opt = self.cls()
         self.assertRaises(NotImplementedError, opt.parse, '')
 
     def test_equal(self):
-        opt1 = ConfigOption()
-        opt2 = ConfigOption(name='name', raw=True)
+        opt1 = self.cls()
+        opt2 = self.cls(name='name', raw=True)
 
-        self.assertEqual(opt1, ConfigOption())
-        self.assertEqual(opt2, ConfigOption(name='name', raw=True))
+        self.assertEqual(opt1, self.cls())
+        self.assertEqual(opt2, self.cls(name='name', raw=True))
         self.assertNotEqual(opt1, opt2)
         self.assertNotEqual(opt1, None)
 
 
+class TestConfigOption(TestOption):
+    cls = ConfigOption
+
+
 class TestConfigSection(unittest.TestCase):
     def test_repr_name(self):
         sect = ConfigSection()


Follow ups