Rev 6059: (vila) Introduce OptionRegistry (Vincent Ladeuil) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Aug 9 12:34:04 UTC 2011


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 6059 [merge]
revision-id: pqm at pqm.ubuntu.com-20110809123400-x521f2j9jkxx8ze2
parent: pqm at pqm.ubuntu.com-20110809090406-sjx052uyb3t9c6o0
parent: v.ladeuil+lp at free.fr-20110809100234-74gcwshwv4hsgzo2
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2011-08-09 12:34:00 +0000
message:
  (vila) Introduce OptionRegistry (Vincent Ladeuil)
modified:
  bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
  bzrlib/tests/test_config.py    testconfig.py-20051011041908-742d0c15d8d8c8eb
  doc/developers/configuration.txt configuration.txt-20110408142435-korjxxnskvq44sta-1
  doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2011-08-08 17:03:51 +0000
+++ b/bzrlib/config.py	2011-08-09 10:02:34 +0000
@@ -2274,40 +2274,90 @@
     value, in which config files it can be stored, etc (TBC).
     """
 
-    def __init__(self, name, default=None):
+    def __init__(self, name, default=None, help=None):
         self.name = name
         self.default = default
+        self.help = help
 
     def get_default(self):
         return self.default
 
 
-# Options registry
-
-option_registry = registry.Registry()
+class OptionRegistry(registry.Registry):
+    """Register config options by their name.
+
+    This overrides ``registry.Registry`` to simplify registration by acquiring
+    some information from the option object itself.
+    """
+
+    def register(self, option):
+        """Register a new option to its name.
+
+        :param option: The option to register. Its name is used as the key.
+        """
+        super(OptionRegistry, self).register(option.name, option,
+                                             help=option.help)
+
+    def register_lazy(self, key, module_name, member_name):
+        """Register a new option to be loaded on request.
+
+        :param key: This is the key to use to request the option later. Since
+            the registration is lazy, it should be provided and match the
+            option name.
+
+        :param module_name: The python path to the module. Such as 'os.path'.
+
+        :param member_name: The member of the module to return.  If empty or
+                None, get() will return the module itself.
+        """
+        super(OptionRegistry, self).register_lazy(key,
+                                                  module_name, member_name)
+
+    def get_help(self, key=None):
+        """Get the help text associated with the given key"""
+        option = self.get(key)
+        the_help = option.help
+        if callable(the_help):
+            return the_help(self, key)
+        return the_help
+
+
+option_registry = OptionRegistry()
 
 
 # Registered options in lexicographical order
 
 option_registry.register(
-    'dirstate.fdatasync', Option('dirstate.fdatasync', default=True),
-    help='Flush dirstate changes onto physical disk?')
-option_registry.register(
-    'default_format', Option('default_format', default='2a'),
-    help='Format used when creating branches.')
-option_registry.register(
-    'editor', Option('editor'),
-    help='The command called to launch an editor to enter a message.')
-option_registry.register(
-    'language', Option('language'),
-    help='Language to translate messages into.')
-option_registry.register(
-    'output_encoding', Option('output_encoding'),
-    help='Unicode encoding for output (terminal encoding if not specified).')
-option_registry.register(
-    'repository.fdatasync',
-    Option('repository.fdatasync', default=True),
-    help='Flush repository changes onto physical disk?')
+    Option('dirstate.fdatasync', default=True,
+           help='''
+Flush dirstate changes onto physical disk?
+
+If true (default), working tree metadata changes are flushed through the
+OS buffers to physical disk.  This is somewhat slower, but means data
+should not be lost if the machine crashes.  See also repository.fdatasync.
+'''))
+option_registry.register(
+    Option('default_format', default='2a',
+           help='Format used when creating branches.'))
+option_registry.register(
+    Option('editor',
+           help='The command called to launch an editor to enter a message.'))
+option_registry.register(
+    Option('language',
+           help='Language to translate messages into.'))
+option_registry.register(
+    Option('output_encoding',
+           help= 'Unicode encoding for output'
+           ' (terminal encoding if not specified).'))
+option_registry.register(
+    Option('repository.fdatasync', default=True,
+           help='''\
+Flush repository changes onto physical disk?
+
+If true (default), repository changes are flushed through the OS buffers
+to physical disk.  This is somewhat slower, but means data should not be
+lost if the machine crashes.  See also dirstate.fdatasync.
+'''))
 
 
 class Section(object):

=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py	2011-07-11 10:53:46 +0000
+++ b/bzrlib/tests/test_config.py	2011-08-09 10:02:34 +0000
@@ -2219,26 +2219,31 @@
     def setUp(self):
         super(TestOptionRegistry, self).setUp()
         # Always start with an empty registry
-        self.overrideAttr(config, 'option_registry', registry.Registry())
+        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
         self.registry = config.option_registry
 
     def test_register(self):
         opt = config.Option('foo')
-        self.registry.register('foo', opt)
+        self.registry.register(opt)
         self.assertIs(opt, self.registry.get('foo'))
 
-    lazy_option = config.Option('lazy_foo')
-
-    def test_register_lazy(self):
-        self.registry.register_lazy('foo', self.__module__,
-                                    'TestOptionRegistry.lazy_option')
-        self.assertIs(self.lazy_option, self.registry.get('foo'))
-
     def test_registered_help(self):
-        opt = config.Option('foo')
-        self.registry.register('foo', opt, help='A simple option')
+        opt = config.Option('foo', help='A simple option')
+        self.registry.register(opt)
         self.assertEquals('A simple option', self.registry.get_help('foo'))
 
+    lazy_option = config.Option('lazy_foo', help='Lazy help')
+
+    def test_register_lazy(self):
+        self.registry.register_lazy('lazy_foo', self.__module__,
+                                    'TestOptionRegistry.lazy_option')
+        self.assertIs(self.lazy_option, self.registry.get('lazy_foo'))
+
+    def test_registered_lazy_help(self):
+        self.registry.register_lazy('lazy_foo', self.__module__,
+                                    'TestOptionRegistry.lazy_option')
+        self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
+
 
 class TestRegisteredOptions(tests.TestCase):
     """All registered options should verify some constraints."""
@@ -2258,8 +2263,9 @@
     def test_help_is_set(self):
         option_help = self.registry.get_help(self.option_name)
         self.assertNotEquals(None, option_help)
-        # Come on, think about the user, he really wants to know whst the
+        # Come on, think about the user, he really wants to know what the
         # option is about
+        self.assertIsNot(None, option_help)
         self.assertNotEquals('', option_help)
 
 
@@ -2866,6 +2872,9 @@
     # FIXME: This should be parametrized for all known Stack or dedicated
     # paramerized tests created to avoid bloating -- vila 2011-03-31
 
+    def overrideOptionRegistry(self):
+        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
+
     def test_single_config_get(self):
         conf = dict(foo='bar')
         conf_stack = config.Stack([conf])
@@ -2874,21 +2883,21 @@
     def test_get_with_registered_default_value(self):
         conf_stack = config.Stack([dict()])
         opt = config.Option('foo', default='bar')
-        self.overrideAttr(config, 'option_registry', registry.Registry())
+        self.overrideOptionRegistry()
         config.option_registry.register('foo', opt)
         self.assertEquals('bar', conf_stack.get('foo'))
 
     def test_get_without_registered_default_value(self):
         conf_stack = config.Stack([dict()])
         opt = config.Option('foo')
-        self.overrideAttr(config, 'option_registry', registry.Registry())
+        self.overrideOptionRegistry()
         config.option_registry.register('foo', opt)
         self.assertEquals(None, conf_stack.get('foo'))
 
     def test_get_without_default_value_for_not_registered(self):
         conf_stack = config.Stack([dict()])
         opt = config.Option('foo')
-        self.overrideAttr(config, 'option_registry', registry.Registry())
+        self.overrideOptionRegistry()
         self.assertEquals(None, conf_stack.get('foo'))
 
     def test_get_first_definition(self):

=== modified file 'doc/developers/configuration.txt'
--- a/doc/developers/configuration.txt	2011-05-18 08:47:16 +0000
+++ b/doc/developers/configuration.txt	2011-08-09 09:27:46 +0000
@@ -19,8 +19,9 @@
 * default: the default value that Stack.get() should return if no
   value can be found for the option.
 
-Since plugins should be able to lazily register options, the associated help
-is not part of the object but provided at registration time.
+* help: a doc string describing the option, the first line should be a
+  summary and can be followed by a blank line and a more detailed
+  explanation.
 
 Sections
 --------

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2011-08-08 12:51:16 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2011-08-09 12:34:00 +0000
@@ -105,6 +105,9 @@
   two files in different trees have the same contents.
   (Jelmer Vernooij)
 
+* New registry ``OptionRegistry`` specialized for configuration options.
+  (Vincent Ladeuil)
+
 * Remove ``AtomicFile.closed`` which has been deprecated in bzr 0.10.
   (Vincent Ladeuil)
 




More information about the bazaar-commits mailing list