~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-08-29 12:01:49 UTC
  • mfrom: (6091.3.6 convert-default-values)
  • Revision ID: pqm@pqm.ubuntu.com-20110829120149-68n9rlsc5b0ft4wc
(vila) Better conversion for default values of config Options. (Vincent
 Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2322
2322
        :param name: the name used to refer to the option.
2323
2323
 
2324
2324
        :param default: the default value to use when none exist in the config
2325
 
            stores.
 
2325
            stores. This is either a string that ``from_unicode`` will convert
 
2326
            into the proper type or a python object that can be stringified (so
 
2327
            only the empty list is supported for example).
2326
2328
 
2327
2329
        :param default_from_env: A list of environment variables which can
2328
2330
           provide a default value. 'default' will be used only if none of the
2344
2346
        if default_from_env is None:
2345
2347
            default_from_env = []
2346
2348
        self.name = name
2347
 
        self.default = default
 
2349
        # Convert the default value to a unicode string so all values are
 
2350
        # strings internally before conversion (via from_unicode) is attempted.
 
2351
        if default is None:
 
2352
            self.default = None
 
2353
        elif isinstance(default, list):
 
2354
            # Only the empty list is supported
 
2355
            if default:
 
2356
                raise AssertionError(
 
2357
                    'Only empty lists are supported as default values')
 
2358
            self.default = u','
 
2359
        elif isinstance(default, (str, unicode, bool, int)):
 
2360
            # Rely on python to convert strings, booleans and integers
 
2361
            self.default = u'%s' % (default,)
 
2362
        else:
 
2363
            # other python objects are not expected
 
2364
            raise AssertionError('%r is not supported as a default value'
 
2365
                                 % (default,))
2348
2366
        self.default_from_env = default_from_env
2349
2367
        self.help = help
2350
2368
        self.from_unicode = from_unicode
2352
2370
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2353
2371
        self.invalid = invalid
2354
2372
 
 
2373
    def convert_from_unicode(self, unicode_value):
 
2374
        if self.from_unicode is None or unicode_value is None:
 
2375
            # Don't convert or nothing to convert
 
2376
            return unicode_value
 
2377
        try:
 
2378
            converted = self.from_unicode(unicode_value)
 
2379
        except (ValueError, TypeError):
 
2380
            # Invalid values are ignored
 
2381
            converted = None
 
2382
        if converted is None and self.invalid is not None:
 
2383
            # The conversion failed
 
2384
            if self.invalid == 'warning':
 
2385
                trace.warning('Value "%s" is not valid for "%s"',
 
2386
                              unicode_value, self.name)
 
2387
            elif self.invalid == 'error':
 
2388
                raise errors.ConfigOptionValueError(self.name, unicode_value)
 
2389
        return converted
 
2390
 
2355
2391
    def get_default(self):
 
2392
        value = None
2356
2393
        for var in self.default_from_env:
2357
2394
            try:
2358
 
                return os.environ[var]
 
2395
                # If the env variable is defined, its value is the default one
 
2396
                value = os.environ[var]
 
2397
                break
2359
2398
            except KeyError:
2360
2399
                continue
2361
 
        return self.default
 
2400
        if value is None:
 
2401
            # Otherwise, fallback to the value defined at registration
 
2402
            value = self.default
 
2403
        return value
2362
2404
 
2363
2405
    def get_help_text(self, additional_see_also=None, plain=True):
2364
2406
        result = self.help
2497
2539
           help= 'Unicode encoding for output'
2498
2540
           ' (terminal encoding if not specified).'))
2499
2541
option_registry.register(
2500
 
    Option('repository.fdatasync', default=True, from_unicode=bool_from_store,
 
2542
    Option('repository.fdatasync', default=True,
 
2543
           from_unicode=bool_from_store,
2501
2544
           help='''\
2502
2545
Flush repository changes onto physical disk?
2503
2546
 
2977
3020
        except KeyError:
2978
3021
            # Not registered
2979
3022
            opt = None
2980
 
        if (opt is not None and opt.from_unicode is not None
2981
 
            and value is not None):
2982
 
            # If a value exists and the option provides a converter, use it
2983
 
            try:
2984
 
                converted = opt.from_unicode(value)
2985
 
            except (ValueError, TypeError):
2986
 
                # Invalid values are ignored
2987
 
                converted = None
2988
 
            if converted is None and opt.invalid is not None:
2989
 
                # The conversion failed
2990
 
                if opt.invalid == 'warning':
2991
 
                    trace.warning('Value "%s" is not valid for "%s"',
2992
 
                                  value, name)
2993
 
                elif opt.invalid == 'error':
2994
 
                    raise errors.ConfigOptionValueError(name, value)
2995
 
            value = converted
2996
 
        if value is None:
2997
 
            # If the option is registered, it may provide a default value
2998
 
            if opt is not None:
2999
 
                value = opt.get_default()
 
3023
        if opt is not None:
 
3024
            value = opt.convert_from_unicode(value)
 
3025
            if value is None:
 
3026
                # The conversion failed or there was no value to convert,
 
3027
                # fallback to the default value
 
3028
                value = opt.convert_from_unicode(opt.get_default())
3000
3029
        for hook in ConfigHooks['get']:
3001
3030
            hook(self, name, value)
3002
3031
        return value