/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Martin Packman
  • Date: 2012-01-05 10:44:12 UTC
  • mfrom: (6424 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6427.
  • Revision ID: martin.packman@canonical.com-20120105104412-z03fi9m43h946fvs
Merge bzr.dev to resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
up=pull
73
73
"""
74
74
 
 
75
from __future__ import absolute_import
 
76
 
75
77
import os
76
78
import sys
77
79
 
440
442
            l = [l]
441
443
        return l
442
444
 
 
445
    @deprecated_method(deprecated_in((2, 5, 0)))
443
446
    def get_user_option_as_int_from_SI(self, option_name, default=None):
444
447
        """Get a generic option from a human readable size in SI units, e.g 10MB
445
448
 
490
493
        """See gpg_signing_command()."""
491
494
        return None
492
495
 
 
496
    @deprecated_method(deprecated_in((2, 5, 0)))
493
497
    def log_format(self):
494
498
        """What log format should be used"""
495
499
        result = self._log_format()
1648
1652
    raise errors.NoWhoami()
1649
1653
 
1650
1654
 
1651
 
def email_from_store(unicode_str):
1652
 
    """Unlike other env vars, BZR_EMAIL takes precedence over config settings.
1653
 
 
1654
 
    Whatever comes from a config file is then overridden.
1655
 
    """
1656
 
    value = os.environ.get('BZR_EMAIL')
1657
 
    if value:
1658
 
        return value.decode(osutils.get_user_encoding())
1659
 
    return unicode_str
1660
 
 
1661
 
 
1662
1655
def _auto_user_id():
1663
1656
    """Calculate automatic user identification.
1664
1657
 
2339
2332
    encoutered, in which config files it can be stored.
2340
2333
    """
2341
2334
 
2342
 
    def __init__(self, name, default=None, default_from_env=None,
2343
 
                 help=None, from_unicode=None, invalid=None):
 
2335
    def __init__(self, name, override_from_env=None,
 
2336
                 default=None, default_from_env=None,
 
2337
                 help=None, from_unicode=None, invalid=None, unquote=True):
2344
2338
        """Build an option definition.
2345
2339
 
2346
2340
        :param name: the name used to refer to the option.
2347
2341
 
 
2342
        :param override_from_env: A list of environment variables which can
 
2343
           provide override any configuration setting.
 
2344
 
2348
2345
        :param default: the default value to use when none exist in the config
2349
2346
            stores. This is either a string that ``from_unicode`` will convert
2350
2347
            into the proper type, a callable returning a unicode string so that
2368
2365
            TypeError. Accepted values are: None (ignore invalid values),
2369
2366
            'warning' (emit a warning), 'error' (emit an error message and
2370
2367
            terminates).
 
2368
 
 
2369
        :param unquote: should the unicode value be unquoted before conversion.
 
2370
           This should be used only when the store providing the values cannot
 
2371
           safely unquote them (see http://pad.lv/906897). It is provided so
 
2372
           daughter classes can handle the quoting themselves.
2371
2373
        """
 
2374
        if override_from_env is None:
 
2375
            override_from_env = []
2372
2376
        if default_from_env is None:
2373
2377
            default_from_env = []
2374
2378
        self.name = name
 
2379
        self.override_from_env = override_from_env
2375
2380
        # Convert the default value to a unicode string so all values are
2376
2381
        # strings internally before conversion (via from_unicode) is attempted.
2377
2382
        if default is None:
2394
2399
        self.default_from_env = default_from_env
2395
2400
        self.help = help
2396
2401
        self.from_unicode = from_unicode
 
2402
        self.unquote = unquote
2397
2403
        if invalid and invalid not in ('warning', 'error'):
2398
2404
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2399
2405
        self.invalid = invalid
2400
2406
 
2401
 
    def convert_from_unicode(self, unicode_value):
 
2407
    def convert_from_unicode(self, store, unicode_value):
 
2408
        if self.unquote and store is not None and unicode_value is not None:
 
2409
            unicode_value = store.unquote(unicode_value)
2402
2410
        if self.from_unicode is None or unicode_value is None:
2403
2411
            # Don't convert or nothing to convert
2404
2412
            return unicode_value
2416
2424
                raise errors.ConfigOptionValueError(self.name, unicode_value)
2417
2425
        return converted
2418
2426
 
 
2427
    def get_override(self):
 
2428
        value = None
 
2429
        for var in self.override_from_env:
 
2430
            try:
 
2431
                # If the env variable is defined, its value takes precedence
 
2432
                value = os.environ[var].decode(osutils.get_user_encoding())
 
2433
                break
 
2434
            except KeyError:
 
2435
                continue
 
2436
        return value
 
2437
 
2419
2438
    def get_default(self):
2420
2439
        value = None
2421
2440
        for var in self.default_from_env:
2455
2474
    return int(unicode_str)
2456
2475
 
2457
2476
 
 
2477
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
 
2478
 
 
2479
def int_SI_from_store(unicode_str):
 
2480
    """Convert a human readable size in SI units, e.g 10MB into an integer.
 
2481
 
 
2482
    Accepted suffixes are K,M,G. It is case-insensitive and may be followed
 
2483
    by a trailing b (i.e. Kb, MB). This is intended to be practical and not
 
2484
    pedantic.
 
2485
 
 
2486
    :return Integer, expanded to its base-10 value if a proper SI unit is 
 
2487
        found, None otherwise.
 
2488
    """
 
2489
    regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
 
2490
    p = re.compile(regexp, re.IGNORECASE)
 
2491
    m = p.match(unicode_str)
 
2492
    val = None
 
2493
    if m is not None:
 
2494
        val, _, unit = m.groups()
 
2495
        val = int(val)
 
2496
        if unit:
 
2497
            try:
 
2498
                coeff = _unit_suffixes[unit.upper()]
 
2499
            except KeyError:
 
2500
                raise ValueError(gettext('{0} is not an SI unit.').format(unit))
 
2501
            val *= coeff
 
2502
    return val
 
2503
 
 
2504
 
2458
2505
def float_from_store(unicode_str):
2459
2506
    return float(unicode_str)
2460
2507
 
2465
2512
    {}, encoding='utf-8', list_values=True, interpolation=False)
2466
2513
 
2467
2514
 
2468
 
def list_from_store(unicode_str):
2469
 
    if not isinstance(unicode_str, basestring):
2470
 
        raise TypeError
2471
 
    # Now inject our string directly as unicode. All callers got their value
2472
 
    # from configobj, so values that need to be quoted are already properly
2473
 
    # quoted.
2474
 
    _list_converter_config.reset()
2475
 
    _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2476
 
    maybe_list = _list_converter_config['list']
2477
 
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2478
 
    if isinstance(maybe_list, basestring):
2479
 
        if maybe_list:
2480
 
            # A single value, most probably the user forgot (or didn't care to
2481
 
            # add) the final ','
2482
 
            l = [maybe_list]
 
2515
class ListOption(Option):
 
2516
 
 
2517
    def __init__(self, name, default=None, default_from_env=None,
 
2518
                 help=None, invalid=None):
 
2519
        """A list Option definition.
 
2520
 
 
2521
        This overrides the base class so the conversion from a unicode string
 
2522
        can take quoting into account.
 
2523
        """
 
2524
        super(ListOption, self).__init__(
 
2525
            name, default=default, default_from_env=default_from_env,
 
2526
            from_unicode=self.from_unicode, help=help,
 
2527
            invalid=invalid, unquote=False)
 
2528
 
 
2529
    def from_unicode(self, unicode_str):
 
2530
        if not isinstance(unicode_str, basestring):
 
2531
            raise TypeError
 
2532
        # Now inject our string directly as unicode. All callers got their
 
2533
        # value from configobj, so values that need to be quoted are already
 
2534
        # properly quoted.
 
2535
        _list_converter_config.reset()
 
2536
        _list_converter_config._parse([u"list=%s" % (unicode_str,)])
 
2537
        maybe_list = _list_converter_config['list']
 
2538
        if isinstance(maybe_list, basestring):
 
2539
            if maybe_list:
 
2540
                # A single value, most probably the user forgot (or didn't care
 
2541
                # to add) the final ','
 
2542
                l = [maybe_list]
 
2543
            else:
 
2544
                # The empty string, convert to empty list
 
2545
                l = []
2483
2546
        else:
2484
 
            # The empty string, convert to empty list
2485
 
            l = []
2486
 
    else:
2487
 
        # We rely on ConfigObj providing us with a list already
2488
 
        l = maybe_list
2489
 
    return l
 
2547
            # We rely on ConfigObj providing us with a list already
 
2548
            l = maybe_list
 
2549
        return l
2490
2550
 
2491
2551
 
2492
2552
class OptionRegistry(registry.Registry):
2542
2602
existing mainline of the branch.
2543
2603
'''))
2544
2604
option_registry.register(
2545
 
    Option('acceptable_keys',
2546
 
           default=None, from_unicode=list_from_store,
 
2605
    ListOption('acceptable_keys',
 
2606
           default=None,
2547
2607
           help="""\
2548
2608
List of GPG key patterns which are acceptable for verification.
2549
2609
"""))
2550
2610
option_registry.register(
 
2611
    Option('add.maximum_file_size',
 
2612
           default=u'20MB', from_unicode=int_SI_from_store,
 
2613
           help="""\
 
2614
Size above which files should be added manually.
 
2615
 
 
2616
Files below this size are added automatically when using ``bzr add`` without
 
2617
arguments.
 
2618
 
 
2619
A negative value means disable the size check.
 
2620
"""))
 
2621
option_registry.register(
 
2622
    Option('bound',
 
2623
           default=None, from_unicode=bool_from_store,
 
2624
           help="""\
 
2625
Is the branch bound to ``bound_location``.
 
2626
 
 
2627
If set to "True", the branch should act as a checkout, and push each commit to
 
2628
the bound_location.  This option is normally set by ``bind``/``unbind``.
 
2629
 
 
2630
See also: bound_location.
 
2631
"""))
 
2632
option_registry.register(
 
2633
    Option('bound_location',
 
2634
           default=None,
 
2635
           help="""\
 
2636
The location that commits should go to when acting as a checkout.
 
2637
 
 
2638
This option is normally set by ``bind``.
 
2639
 
 
2640
See also: bound.
 
2641
"""))
 
2642
option_registry.register(
 
2643
    Option('branch.fetch_tags', default=False,  from_unicode=bool_from_store,
 
2644
           help="""\
 
2645
Whether revisions associated with tags should be fetched.
 
2646
"""))
 
2647
option_registry.register(
2551
2648
    Option('bzr.workingtree.worth_saving_limit', default=10,
2552
2649
           from_unicode=int_from_store,  invalid='warning',
2553
2650
           help='''\
2593
2690
should not be lost if the machine crashes.  See also repository.fdatasync.
2594
2691
'''))
2595
2692
option_registry.register(
2596
 
    Option('debug_flags', default=[], from_unicode=list_from_store,
 
2693
    ListOption('debug_flags', default=[],
2597
2694
           help='Debug flags to activate.'))
2598
2695
option_registry.register(
2599
2696
    Option('default_format', default='2a',
2612
2709
    Option('editor',
2613
2710
           help='The command called to launch an editor to enter a message.'))
2614
2711
option_registry.register(
2615
 
    Option('email', default=default_email,
2616
 
           from_unicode=email_from_store,
 
2712
    Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2617
2713
           help='The users identity'))
2618
2714
option_registry.register(
2619
2715
    Option('gpg_signing_command',
2667
2763
           help= 'Unicode encoding for output'
2668
2764
           ' (terminal encoding if not specified).'))
2669
2765
option_registry.register(
 
2766
    Option('parent_location',
 
2767
           default=None,
 
2768
           help="""\
 
2769
The location of the default branch for pull or merge.
 
2770
 
 
2771
This option is normally set when creating a branch, the first ``pull`` or by
 
2772
``pull --remember``.
 
2773
"""))
 
2774
option_registry.register(
2670
2775
    Option('post_commit', default=None,
2671
2776
           help='''\
2672
2777
Post commit functions.
2676
2781
Each function takes branch, rev_id as parameters.
2677
2782
'''))
2678
2783
option_registry.register(
 
2784
    Option('public_branch',
 
2785
           default=None,
 
2786
           help="""\
 
2787
A publically-accessible version of this branch.
 
2788
 
 
2789
This implies that the branch setting this option is not publically-accessible.
 
2790
Used and set by ``bzr send``.
 
2791
"""))
 
2792
option_registry.register(
 
2793
    Option('push_location',
 
2794
           default=None,
 
2795
           help="""\
 
2796
The location of the default branch for push.
 
2797
 
 
2798
This option is normally set by the first ``push`` or ``push --remember``.
 
2799
"""))
 
2800
option_registry.register(
2679
2801
    Option('push_strict', default=None,
2680
2802
           from_unicode=bool_from_store,
2681
2803
           help='''\
2694
2816
to physical disk.  This is somewhat slower, but means data should not be
2695
2817
lost if the machine crashes.  See also dirstate.fdatasync.
2696
2818
'''))
2697
 
 
 
2819
option_registry.register_lazy('smtp_server',
 
2820
    'bzrlib.smtp_connection', 'smtp_server')
 
2821
option_registry.register_lazy('smtp_password',
 
2822
    'bzrlib.smtp_connection', 'smtp_password')
 
2823
option_registry.register_lazy('smtp_username',
 
2824
    'bzrlib.smtp_connection', 'smtp_username')
2698
2825
option_registry.register(
2699
2826
    Option('selftest.timeout',
2700
2827
        default='600',
2709
2836
The default value for ``send --strict``.
2710
2837
 
2711
2838
If present, defines the ``--strict`` option default value for checking
2712
 
uncommitted changes before pushing.
 
2839
uncommitted changes before sending a bundle.
2713
2840
'''))
2714
2841
 
2715
2842
option_registry.register(
2717
2844
           default=300.0, from_unicode=float_from_store,
2718
2845
           help="If we wait for a new request from a client for more than"
2719
2846
                " X seconds, consider the client idle, and hangup."))
 
2847
option_registry.register(
 
2848
    Option('stacked_on_location',
 
2849
           default=None,
 
2850
           help="""The location where this branch is stacked on."""))
 
2851
option_registry.register(
 
2852
    Option('submit_branch',
 
2853
           default=None,
 
2854
           help="""\
 
2855
The branch you intend to submit your current work to.
 
2856
 
 
2857
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
 
2858
by the ``submit:`` revision spec.
 
2859
"""))
2720
2860
 
2721
2861
 
2722
2862
class Section(object):
2803
2943
        """
2804
2944
        raise NotImplementedError(self.unload)
2805
2945
 
 
2946
    def quote(self, value):
 
2947
        """Quote a configuration option value for storing purposes.
 
2948
 
 
2949
        This allows Stacks to present values as they will be stored.
 
2950
        """
 
2951
        return value
 
2952
 
 
2953
    def unquote(self, value):
 
2954
        """Unquote a configuration option value into unicode.
 
2955
 
 
2956
        The received value is quoted as stored.
 
2957
        """
 
2958
        return value
 
2959
 
2806
2960
    def save(self):
2807
2961
        """Saves the Store to persistent storage."""
2808
2962
        raise NotImplementedError(self.save)
2838
2992
        if opts is None:
2839
2993
            opts = {}
2840
2994
        self.options = {}
 
2995
        self.id = 'cmdline'
2841
2996
 
2842
2997
    def _reset(self):
2843
2998
        # The dict should be cleared but not replaced so it can be shared.
2861
3016
        return 'cmdline'
2862
3017
 
2863
3018
    def get_sections(self):
2864
 
        yield self,  self.readonly_section_class('cmdline_overrides',
2865
 
                                                 self.options)
 
3019
        yield self,  self.readonly_section_class(None, self.options)
2866
3020
 
2867
3021
 
2868
3022
class IniFileStore(Store):
2975
3129
            section = self._config_obj.setdefault(section_id, {})
2976
3130
        return self.mutable_section_class(section_id, section)
2977
3131
 
 
3132
    def quote(self, value):
 
3133
        try:
 
3134
            # configobj conflates automagical list values and quoting
 
3135
            self._config_obj.list_values = True
 
3136
            return self._config_obj._quote(value)
 
3137
        finally:
 
3138
            self._config_obj.list_values = False
 
3139
 
 
3140
    def unquote(self, value):
 
3141
        if value and isinstance(value, basestring):
 
3142
            # _unquote doesn't handle None nor empty strings nor anything that
 
3143
            # is not a string, really.
 
3144
            value = self._config_obj._unquote(value)
 
3145
        return value
 
3146
 
2978
3147
 
2979
3148
class TransportIniFileStore(IniFileStore):
2980
3149
    """IniFileStore that loads files from a transport.
3113
3282
        super(ControlStore, self).__init__(bzrdir.transport,
3114
3283
                                          'control.conf',
3115
3284
                                           lock_dir_name='branch_lock')
 
3285
        self.id = 'control'
3116
3286
 
3117
3287
 
3118
3288
class SectionMatcher(object):
3305
3475
        if expand is None:
3306
3476
            expand = _get_expand_default_value()
3307
3477
        value = None
3308
 
        # Ensuring lazy loading is achieved by delaying section matching (which
3309
 
        # implies querying the persistent storage) until it can't be avoided
3310
 
        # anymore by using callables to describe (possibly empty) section
3311
 
        # lists.
3312
 
        for sections in self.sections_def:
3313
 
            for store, section in sections():
3314
 
                value = section.get(name)
3315
 
                if value is not None:
3316
 
                    break
3317
 
            if value is not None:
3318
 
                break
 
3478
        found_store = None # Where the option value has been found
3319
3479
        # If the option is registered, it may provide additional info about
3320
3480
        # value handling
3321
3481
        try:
3323
3483
        except KeyError:
3324
3484
            # Not registered
3325
3485
            opt = None
 
3486
 
3326
3487
        def expand_and_convert(val):
3327
 
            # This may need to be called twice if the value is None or ends up
3328
 
            # being None during expansion or conversion.
 
3488
            # This may need to be called in different contexts if the value is
 
3489
            # None or ends up being None during expansion or conversion.
3329
3490
            if val is not None:
3330
3491
                if expand:
3331
3492
                    if isinstance(val, basestring):
3334
3495
                        trace.warning('Cannot expand "%s":'
3335
3496
                                      ' %s does not support option expansion'
3336
3497
                                      % (name, type(val)))
3337
 
                if opt is not None:
3338
 
                    val = opt.convert_from_unicode(val)
 
3498
                if opt is None:
 
3499
                    val = found_store.unquote(val)
 
3500
                else:
 
3501
                    val = opt.convert_from_unicode(found_store, val)
3339
3502
            return val
3340
 
        value = expand_and_convert(value)
3341
 
        if opt is not None and value is None:
3342
 
            # If the option is registered, it may provide a default value
3343
 
            value = opt.get_default()
3344
 
            value = expand_and_convert(value)
 
3503
 
 
3504
        # First of all, check if the environment can override the configuration
 
3505
        # value
 
3506
        if opt is not None and opt.override_from_env:
 
3507
            value = opt.get_override()
 
3508
            value = expand_and_convert(value)
 
3509
        if value is None:
 
3510
            # Ensuring lazy loading is achieved by delaying section matching
 
3511
            # (which implies querying the persistent storage) until it can't be
 
3512
            # avoided anymore by using callables to describe (possibly empty)
 
3513
            # section lists.
 
3514
            for sections in self.sections_def:
 
3515
                for store, section in sections():
 
3516
                    value = section.get(name)
 
3517
                    if value is not None:
 
3518
                        found_store = store
 
3519
                        break
 
3520
                if value is not None:
 
3521
                    break
 
3522
            value = expand_and_convert(value)
 
3523
            if opt is not None and value is None:
 
3524
                # If the option is registered, it may provide a default value
 
3525
                value = opt.get_default()
 
3526
                value = expand_and_convert(value)
3345
3527
        for hook in ConfigHooks['get']:
3346
3528
            hook(self, name, value)
3347
3529
        return value
3419
3601
        or deleting an option. In practice the store will often be loaded but
3420
3602
        this helps catching some programming errors.
3421
3603
        """
3422
 
        section = self.store.get_mutable_section(self.mutable_section_id)
3423
 
        return section
 
3604
        store = self.store
 
3605
        section = store.get_mutable_section(self.mutable_section_id)
 
3606
        return store, section
3424
3607
 
3425
3608
    def set(self, name, value):
3426
3609
        """Set a new value for the option."""
3427
 
        section = self._get_mutable_section()
3428
 
        section.set(name, value)
 
3610
        store, section = self._get_mutable_section()
 
3611
        section.set(name, store.quote(value))
3429
3612
        for hook in ConfigHooks['set']:
3430
3613
            hook(self, name, value)
3431
3614
 
3432
3615
    def remove(self, name):
3433
3616
        """Remove an existing option."""
3434
 
        section = self._get_mutable_section()
 
3617
        _, section = self._get_mutable_section()
3435
3618
        section.remove(name)
3436
3619
        for hook in ConfigHooks['remove']:
3437
3620
            hook(self, name)
3447
3630
        return []
3448
3631
 
3449
3632
 
 
3633
class MemoryStack(Stack):
 
3634
    """A configuration stack defined from a string.
 
3635
 
 
3636
    This is mainly intended for tests and requires no disk resources.
 
3637
    """
 
3638
 
 
3639
    def __init__(self, content=None):
 
3640
        """Create an in-memory stack from a given content.
 
3641
 
 
3642
        It uses a single store based on configobj and support reading and
 
3643
        writing options.
 
3644
 
 
3645
        :param content: The initial content of the store. If None, the store is
 
3646
            not loaded and ``_load_from_string`` can and should be used if
 
3647
            needed.
 
3648
        """
 
3649
        store = IniFileStore()
 
3650
        if content is not None:
 
3651
            store._load_from_string(content)
 
3652
        super(MemoryStack, self).__init__(
 
3653
            [store.get_sections], store)
 
3654
 
 
3655
 
3450
3656
class _CompatibleStack(Stack):
3451
3657
    """Place holder for compatibility with previous design.
3452
3658
 
3579
3785
        self.bzrdir = bzrdir
3580
3786
 
3581
3787
 
3582
 
class RemoteBranchStack(_CompatibleStack):
3583
 
    """Remote branch-only options stack."""
 
3788
class BranchOnlyStack(_CompatibleStack):
 
3789
    """Branch-only options stack."""
3584
3790
 
3585
 
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3586
 
    # with the stack used for remote branches. RemoteBranchStack only uses
3587
 
    # branch.conf and is used only for the stack options.
 
3791
    # FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
 
3792
    # stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
 
3793
    # -- vila 2011-12-16
3588
3794
 
3589
3795
    def __init__(self, branch):
3590
3796
        bstore = branch._get_config_store()
3591
 
        super(RemoteBranchStack, self).__init__(
 
3797
        super(BranchOnlyStack, self).__init__(
3592
3798
            [NameMatcher(bstore, None).get_sections],
3593
3799
            bstore)
3594
3800
        self.branch = branch
3595
3801
 
 
3802
 
3596
3803
# Use a an empty dict to initialize an empty configobj avoiding all
3597
3804
# parsing and encoding checks
3598
3805
_quoting_config = configobj.ConfigObj(
3599
 
    {}, encoding='utf-8', interpolation=False)
 
3806
    {}, encoding='utf-8', interpolation=False, list_values=True)
3600
3807
 
3601
3808
class cmd_config(commands.Command):
3602
3809
    __doc__ = """Display, set or remove a configuration option.
3722
3929
                            self.outf.write('%s:\n' % (store.id,))
3723
3930
                            cur_store_id = store.id
3724
3931
                            cur_section = None
3725
 
                        if (section.id not in (None, 'DEFAULT')
 
3932
                        if (section.id is not None
3726
3933
                            and cur_section != section.id):
3727
 
                            # Display the section if it's not the default (or
3728
 
                            # only) one.
 
3934
                            # Display the section id as it appears in the store
 
3935
                            # (None doesn't appear by definition)
3729
3936
                            self.outf.write('  [%s]\n' % (section.id,))
3730
3937
                            cur_section = section.id
3731
3938
                        value = section.get(oname, expand=False)
 
3939
                        # Since we don't use the stack, we need to restore a
 
3940
                        # proper quoting.
 
3941
                        try:
 
3942
                            opt = option_registry.get(oname)
 
3943
                            value = opt.convert_from_unicode(store, value)
 
3944
                        except KeyError:
 
3945
                            value = store.unquote(value)
3732
3946
                        value = _quoting_config._quote(value)
3733
3947
                        self.outf.write('  %s = %s\n' % (oname, value))
3734
3948