Rev 6064: (vila) Allow option to require a warning or error when an invalid value is in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Aug 12 07:57:47 UTC 2011


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

------------------------------------------------------------
revno: 6064 [merge]
revision-id: pqm at pqm.ubuntu.com-20110812075738-z6kjnvy20806946j
parent: pqm at pqm.ubuntu.com-20110812045846-15hlipqj7f69wn7f
parent: v.ladeuil+lp at free.fr-20110810132627-fefpin201fbzkjjs
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-08-12 07:57:38 +0000
message:
  (vila) Allow option to require a warning or error when an invalid value is
   found in a config file. (Vincent Ladeuil)
modified:
  bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  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-12 04:58:46 +0000
+++ b/bzrlib/config.py	2011-08-12 07:57:38 +0000
@@ -2272,14 +2272,39 @@
     The option *values* are stored in config files and found in sections.
 
     Here we define various properties about the option itself, its default
-    value, in which config files it can be stored, etc (TBC).
+    value, how to convert it from stores, what to do when invalid values are
+    encoutered, in which config files it can be stored.
     """
 
-    def __init__(self, name, default=None, help=None, from_unicode=None):
+    def __init__(self, name, default=None, help=None, from_unicode=None,
+                 invalid=None):
+        """Build an option definition.
+
+        :param name: the name used to refer to the option.
+
+        :param default: the default value to use when none exist in the config
+            stores.
+
+        :param help: a doc string to explain the option to the user.
+
+        :param from_unicode: a callable to convert the unicode string
+            representing the option value in a store. This is not called for
+            the default value.
+
+        :param invalid: the action to be taken when an invalid value is
+            encountered in a store. This is called only when from_unicode is
+            invoked to convert a string and returns None or raise
+            ValueError. Accepted values are: None (ignore invalid values),
+            'warning' (emit a warning), 'error' emit an error message and
+            terminates.
+        """
         self.name = name
         self.default = default
         self.help = help
         self.from_unicode = from_unicode
+        if invalid and invalid not in ('warning', 'error'):
+            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
+        self.invalid = invalid
 
     def get_default(self):
         return self.default
@@ -2829,10 +2854,18 @@
             and value is not None):
             # If a value exists and the option provides a converter, use it
             try:
-                value = opt.from_unicode(value)
+                converted = opt.from_unicode(value)
             except ValueError:
                 # Invalid values are ignored
-                value = None
+                converted = None
+            if converted is None and opt.invalid is not None:
+                # The conversion failed
+                if opt.invalid == 'warning':
+                    trace.warning('Value "%s" is not valid for "%s"',
+                                  value, name)
+                elif opt.invalid == 'error':
+                    raise errors.ConfigOptionValueError(name, value)
+            value = converted
         if value is None:
             # If the option is registered, it may provide a default value
             if opt is not None:

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2011-08-02 01:10:27 +0000
+++ b/bzrlib/errors.py	2011-08-10 13:26:27 +0000
@@ -1802,6 +1802,14 @@
         self.errors = '\n'.join(e.msg for e in errors)
 
 
+class ConfigOptionValueError(BzrError):
+
+    _fmt = """Bad value "%(value)s" for option "%(name)s"."""
+
+    def __init__(self, name, value):
+        BzrError.__init__(self, name=name, value=value)
+
+
 class NoEmailInUsername(BzrError):
 
     _fmt = "%(username)r does not seem to contain a reasonable email address"

=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py	2011-08-09 13:59:53 +0000
+++ b/bzrlib/tests/test_config.py	2011-08-10 13:26:27 +0000
@@ -2964,9 +2964,10 @@
         self.overrideAttr(config, 'option_registry', config.OptionRegistry())
         self.registry = config.option_registry
 
-    def register_bool_option(self, name, default):
+    def register_bool_option(self, name, default, invalid=None):
         b = config.Option(name, default=default, help='A boolean.',
-                          from_unicode=config.bool_from_store)
+                          from_unicode=config.bool_from_store,
+                          invalid=invalid)
         self.registry.register(b)
 
     def test_get_with_bool_not_defined_default_true(self):
@@ -2987,6 +2988,23 @@
         self.conf.store._load_from_string('foo=not-a-boolean')
         self.assertEquals(False, self.conf.get('foo'))
 
+    def test_get_invalid_warns(self):
+        self.register_bool_option('foo', False, invalid='warning')
+        self.conf.store._load_from_string('foo=not-a-boolean')
+        warnings = []
+        def warning(*args):
+            warnings.append(args[0] % args[1:])
+        self.overrideAttr(trace, 'warning', warning)
+        self.assertEquals(False, self.conf.get('foo'))
+        self.assertLength(1, warnings)
+        self.assertEquals('Value "not-a-boolean" is not valid for "foo"',
+                          warnings[0])
+
+    def test_get_invalid_errors(self):
+        self.register_bool_option('foo', False, invalid='error')
+        self.conf.store._load_from_string('foo=not-a-boolean')
+        self.assertRaises(errors.ConfigOptionValueError, self.conf.get, 'foo')
+
 
 class TestStackSet(TestStackWithTransport):
 

=== modified file 'doc/developers/configuration.txt'
--- a/doc/developers/configuration.txt	2011-08-09 13:51:55 +0000
+++ b/doc/developers/configuration.txt	2011-08-10 13:26:27 +0000
@@ -27,6 +27,9 @@
   suitable value for the option. If the string cannot be coerced it should
   return None.
 
+* invalid: the action to be taken when an invalid value is encountered in a
+  store (during a Stack.get()).
+
 Sections
 --------
 

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2011-08-11 10:45:34 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2011-08-12 07:57:38 +0000
@@ -49,6 +49,11 @@
   which matches user_email() as set by whoami. (Jonathan Riddell,
   #68501)
 
+* An ``invalid`` parameter can be specified when registering a config option
+  to decide what should be done when invalid values are
+  encountered. 'warning' and 'eeror' will respectively emit a warning and
+  ignore the value or errors out. (Vincent Ladeuil)
+
 * bzr log -m now matches message, author, committer and bugs instead
   of just matching the message.  --message keeps its original meaning,
   while --match-message, --match-author, --match-committer and




More information about the bazaar-commits mailing list