155
def signature_policy_from_unicode(signature_string):
156
"""Convert a string to a signing policy."""
157
if signature_string.lower() == 'check-available':
158
return CHECK_IF_POSSIBLE
159
if signature_string.lower() == 'ignore':
161
if signature_string.lower() == 'require':
163
raise ValueError("Invalid signatures policy '%s'"
167
def signing_policy_from_unicode(signature_string):
168
"""Convert a string to a signing policy."""
169
if signature_string.lower() == 'when-required':
170
return SIGN_WHEN_REQUIRED
171
if signature_string.lower() == 'never':
173
if signature_string.lower() == 'always':
175
raise ValueError("Invalid signing policy '%s'"
155
179
class ConfigObj(configobj.ConfigObj):
157
181
def __init__(self, infile=None, **kwargs):
417
441
# add) the final ','
421
def get_user_option_as_int_from_SI(self, option_name, default=None):
445
@deprecated_method(deprecated_in((2, 5, 0)))
446
def get_user_option_as_int_from_SI(self, option_name, default=None):
422
447
"""Get a generic option from a human readable size in SI units, e.g 10MB
424
449
Accepted suffixes are K,M,G. It is case-insensitive and may be followed
425
450
by a trailing b (i.e. Kb, MB). This is intended to be practical and not
428
453
:return Integer, expanded to its base-10 value if a proper SI unit is
429
454
found. If the option doesn't exist, or isn't a value in
430
455
SI units, return default (which defaults to None)
925
949
"""See Config.post_commit."""
926
950
return self._get_user_option('post_commit')
928
def _string_to_signature_policy(self, signature_string):
929
"""Convert a string to a signing policy."""
930
if signature_string.lower() == 'check-available':
931
return CHECK_IF_POSSIBLE
932
if signature_string.lower() == 'ignore':
934
if signature_string.lower() == 'require':
936
raise errors.BzrError("Invalid signatures policy '%s'"
939
def _string_to_signing_policy(self, signature_string):
940
"""Convert a string to a signing policy."""
941
if signature_string.lower() == 'when-required':
942
return SIGN_WHEN_REQUIRED
943
if signature_string.lower() == 'never':
945
if signature_string.lower() == 'always':
947
raise errors.BzrError("Invalid signing policy '%s'"
950
952
def _get_alias(self, value):
952
954
return self._get_parser().get_value("ALIASES",
2315
2332
encoutered, in which config files it can be stored.
2318
def __init__(self, name, default=None, default_from_env=None,
2320
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):
2321
2338
"""Build an option definition.
2323
2340
:param name: the name used to refer to the option.
2342
:param override_from_env: A list of environment variables which can
2343
provide override any configuration setting.
2325
2345
:param default: the default value to use when none exist in the config
2326
2346
stores. This is either a string that ``from_unicode`` will convert
2327
2347
into the proper type, a callable returning a unicode string so that
2345
2365
TypeError. Accepted values are: None (ignore invalid values),
2346
2366
'warning' (emit a warning), 'error' (emit an error message and
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.
2374
if override_from_env is None:
2375
override_from_env = []
2349
2376
if default_from_env is None:
2350
2377
default_from_env = []
2351
2378
self.name = name
2379
self.override_from_env = override_from_env
2352
2380
# Convert the default value to a unicode string so all values are
2353
2381
# strings internally before conversion (via from_unicode) is attempted.
2354
2382
if default is None:
2371
2399
self.default_from_env = default_from_env
2372
2400
self.help = help
2373
2401
self.from_unicode = from_unicode
2402
self.unquote = unquote
2374
2403
if invalid and invalid not in ('warning', 'error'):
2375
2404
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2376
2405
self.invalid = invalid
2378
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)
2379
2410
if self.from_unicode is None or unicode_value is None:
2380
2411
# Don't convert or nothing to convert
2381
2412
return unicode_value
2432
2474
return int(unicode_str)
2477
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2479
def int_SI_from_store(unicode_str):
2480
"""Convert a human readable size in SI units, e.g 10MB into an integer.
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
2486
:return Integer, expanded to its base-10 value if a proper SI unit is
2487
found, None otherwise.
2489
regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2490
p = re.compile(regexp, re.IGNORECASE)
2491
m = p.match(unicode_str)
2494
val, _, unit = m.groups()
2498
coeff = _unit_suffixes[unit.upper()]
2500
raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2435
2505
def float_from_store(unicode_str):
2436
2506
return float(unicode_str)
2440
2509
# Use a an empty dict to initialize an empty configobj avoiding all
2441
2510
# parsing and encoding checks
2442
2511
_list_converter_config = configobj.ConfigObj(
2443
2512
{}, encoding='utf-8', list_values=True, interpolation=False)
2446
def list_from_store(unicode_str):
2447
if not isinstance(unicode_str, basestring):
2449
# Now inject our string directly as unicode. All callers got their value
2450
# from configobj, so values that need to be quoted are already properly
2452
_list_converter_config.reset()
2453
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2454
maybe_list = _list_converter_config['list']
2455
# ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2456
if isinstance(maybe_list, basestring):
2458
# A single value, most probably the user forgot (or didn't care to
2459
# add) the final ','
2515
class ListOption(Option):
2517
def __init__(self, name, default=None, default_from_env=None,
2518
help=None, invalid=None):
2519
"""A list Option definition.
2521
This overrides the base class so the conversion from a unicode string
2522
can take quoting into account.
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)
2529
def from_unicode(self, unicode_str):
2530
if not isinstance(unicode_str, basestring):
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
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):
2540
# A single value, most probably the user forgot (or didn't care
2541
# to add) the final ','
2544
# The empty string, convert to empty list
2462
# The empty string, convert to empty list
2465
# We rely on ConfigObj providing us with a list already
2547
# We rely on ConfigObj providing us with a list already
2470
2552
class OptionRegistry(registry.Registry):
2511
2593
# Registered options in lexicographical order
2513
2595
option_registry.register(
2596
Option('append_revisions_only',
2597
default=None, from_unicode=bool_from_store, invalid='warning',
2599
Whether to only append revisions to the mainline.
2601
If this is set to true, then it is not possible to change the
2602
existing mainline of the branch.
2604
option_registry.register(
2605
ListOption('acceptable_keys',
2608
List of GPG key patterns which are acceptable for verification.
2610
option_registry.register(
2611
Option('add.maximum_file_size',
2612
default=u'20MB', from_unicode=int_SI_from_store,
2614
Size above which files should be added manually.
2616
Files below this size are added automatically when using ``bzr add`` without
2619
A negative value means disable the size check.
2621
option_registry.register(
2623
default=None, from_unicode=bool_from_store,
2625
Is the branch bound to ``bound_location``.
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``.
2630
See also: bound_location.
2632
option_registry.register(
2633
Option('bound_location',
2636
The location that commits should go to when acting as a checkout.
2638
This option is normally set by ``bind``.
2642
option_registry.register(
2643
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2645
Whether revisions associated with tags should be fetched.
2647
option_registry.register(
2514
2648
Option('bzr.workingtree.worth_saving_limit', default=10,
2515
2649
from_unicode=int_from_store, invalid='warning',
2523
2657
a file has been touched.
2525
2659
option_registry.register(
2660
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2661
from_unicode=signature_policy_from_unicode,
2663
GPG checking policy.
2665
Possible values: require, ignore, check-available (default)
2667
this option will control whether bzr will require good gpg
2668
signatures, ignore them, or check them if they are
2671
option_registry.register(
2672
Option('child_submit_format',
2673
help='''The preferred format of submissions to this branch.'''))
2674
option_registry.register(
2675
Option('child_submit_to',
2676
help='''Where submissions to this branch are mailed to.'''))
2677
option_registry.register(
2678
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2679
from_unicode=signing_policy_from_unicode,
2683
Possible values: always, never, when-required (default)
2685
This option controls whether bzr will always create
2686
gpg signatures or not on commits.
2688
option_registry.register(
2526
2689
Option('dirstate.fdatasync', default=True,
2527
2690
from_unicode=bool_from_store,
2552
2715
Option('editor',
2553
2716
help='The command called to launch an editor to enter a message.'))
2554
2717
option_registry.register(
2718
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2719
help='The users identity'))
2720
option_registry.register(
2721
Option('gpg_signing_command',
2724
Program to use use for creating signatures.
2726
This should support at least the -u and --clearsign options.
2728
option_registry.register(
2729
Option('gpg_signing_key',
2732
GPG key to use for signing.
2734
This defaults to the first key associated with the users email.
2736
option_registry.register(
2555
2737
Option('ignore_missing_extensions', default=False,
2556
2738
from_unicode=bool_from_store,
2587
2769
help= 'Unicode encoding for output'
2588
2770
' (terminal encoding if not specified).'))
2589
2771
option_registry.register(
2772
Option('parent_location',
2775
The location of the default branch for pull or merge.
2777
This option is normally set when creating a branch, the first ``pull`` or by
2778
``pull --remember``.
2780
option_registry.register(
2781
Option('post_commit', default=None,
2783
Post commit functions.
2785
An ordered list of python functions to call, separated by spaces.
2787
Each function takes branch, rev_id as parameters.
2789
option_registry.register(
2790
Option('public_branch',
2793
A publically-accessible version of this branch.
2795
This implies that the branch setting this option is not publically-accessible.
2796
Used and set by ``bzr send``.
2798
option_registry.register(
2799
Option('push_location',
2802
The location of the default branch for push.
2804
This option is normally set by the first ``push`` or ``push --remember``.
2806
option_registry.register(
2590
2807
Option('push_strict', default=None,
2591
2808
from_unicode=bool_from_store,
2605
2822
to physical disk. This is somewhat slower, but means data should not be
2606
2823
lost if the machine crashes. See also dirstate.fdatasync.
2825
option_registry.register_lazy('smtp_server',
2826
'bzrlib.smtp_connection', 'smtp_server')
2827
option_registry.register_lazy('smtp_password',
2828
'bzrlib.smtp_connection', 'smtp_password')
2829
option_registry.register_lazy('smtp_username',
2830
'bzrlib.smtp_connection', 'smtp_username')
2609
2831
option_registry.register(
2610
2832
Option('selftest.timeout',
2628
2850
default=300.0, from_unicode=float_from_store,
2629
2851
help="If we wait for a new request from a client for more than"
2630
2852
" X seconds, consider the client idle, and hangup."))
2853
option_registry.register(
2854
Option('stacked_on_location',
2856
help="""The location where this branch is stacked on."""))
2857
option_registry.register(
2858
Option('submit_branch',
2861
The branch you intend to submit your current work to.
2863
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2864
by the ``submit:`` revision spec.
2866
option_registry.register(
2868
help='''Where submissions from this branch are mailed to.'''))
2633
2871
class Section(object):
2679
2919
self.orig[name] = self.get(name, None)
2680
2920
del self.options[name]
2922
def reset_changes(self):
2925
def apply_changes(self, dirty, store):
2926
"""Apply option value changes.
2928
``self`` has been reloaded from the persistent storage. ``dirty``
2929
contains the changes made since the previous loading.
2931
:param dirty: the mutable section containing the changes.
2933
:param store: the store containing the section
2935
for k, expected in dirty.orig.iteritems():
2936
actual = dirty.get(k, _DeletedOption)
2937
reloaded = self.get(k, _NewlyCreatedOption)
2938
if actual is _DeletedOption:
2939
if k in self.options:
2943
# Report concurrent updates in an ad-hoc way. This should only
2944
# occurs when different processes try to update the same option
2945
# which is not supported (as in: the config framework is not meant
2946
# to be used a sharing mechanism).
2947
if expected != reloaded:
2948
if actual is _DeletedOption:
2949
actual = '<DELETED>'
2950
if reloaded is _NewlyCreatedOption:
2951
reloaded = '<CREATED>'
2952
if expected is _NewlyCreatedOption:
2953
expected = '<CREATED>'
2954
# Someone changed the value since we get it from the persistent
2956
trace.warning(gettext(
2957
"Option {0} in section {1} of {2} was changed"
2958
" from {3} to {4}. The {5} value will be saved.".format(
2959
k, self.id, store.external_url(), expected,
2961
# No need to keep track of these changes
2962
self.reset_changes()
2683
2965
class Store(object):
2684
2966
"""Abstract interface to persistent storage for configuration options."""
2715
3001
raise NotImplementedError(self.unload)
3003
def quote(self, value):
3004
"""Quote a configuration option value for storing purposes.
3006
This allows Stacks to present values as they will be stored.
3010
def unquote(self, value):
3011
"""Unquote a configuration option value into unicode.
3013
The received value is quoted as stored.
2717
3017
def save(self):
2718
3018
"""Saves the Store to persistent storage."""
2719
3019
raise NotImplementedError(self.save)
3021
def _need_saving(self):
3022
for s in self.dirty_sections:
3024
# At least one dirty section contains a modification
3028
def apply_changes(self, dirty_sections):
3029
"""Apply changes from dirty sections while checking for coherency.
3031
The Store content is discarded and reloaded from persistent storage to
3032
acquire up-to-date values.
3034
Dirty sections are MutableSection which kept track of the value they
3035
are expected to update.
3037
# We need an up-to-date version from the persistent storage, unload the
3038
# store. The reload will occur when needed (triggered by the first
3039
# get_mutable_section() call below.
3041
# Apply the changes from the preserved dirty sections
3042
for dirty in dirty_sections:
3043
clean = self.get_mutable_section(dirty.id)
3044
clean.apply_changes(dirty, self)
3045
# Everything is clean now
3046
self.dirty_sections = []
3048
def save_changes(self):
3049
"""Saves the Store to persistent storage if changes occurred.
3051
Apply the changes recorded in the mutable sections to a store content
3052
refreshed from persistent storage.
3054
raise NotImplementedError(self.save_changes)
2721
3056
def external_url(self):
2722
3057
raise NotImplementedError(self.external_url)
2884
3233
section = self._config_obj
2886
3235
section = self._config_obj.setdefault(section_id, {})
2887
return self.mutable_section_class(section_id, section)
3236
mutable_section = self.mutable_section_class(section_id, section)
3237
# All mutable sections can become dirty
3238
self.dirty_sections.append(mutable_section)
3239
return mutable_section
3241
def quote(self, value):
3243
# configobj conflates automagical list values and quoting
3244
self._config_obj.list_values = True
3245
return self._config_obj._quote(value)
3247
self._config_obj.list_values = False
3249
def unquote(self, value):
3250
if value and isinstance(value, basestring):
3251
# _unquote doesn't handle None nor empty strings nor anything that
3252
# is not a string, really.
3253
value = self._config_obj._unquote(value)
2890
3257
class TransportIniFileStore(IniFileStore):
3245
3604
trace.warning('Cannot expand "%s":'
3246
3605
' %s does not support option expansion'
3247
3606
% (name, type(val)))
3249
val = opt.convert_from_unicode(val)
3608
val = found_store.unquote(val)
3610
val = opt.convert_from_unicode(found_store, val)
3251
value = expand_and_convert(value)
3252
if opt is not None and value is None:
3253
# If the option is registered, it may provide a default value
3254
value = opt.get_default()
3255
value = expand_and_convert(value)
3613
# First of all, check if the environment can override the configuration
3615
if opt is not None and opt.override_from_env:
3616
value = opt.get_override()
3617
value = expand_and_convert(value)
3619
# Ensuring lazy loading is achieved by delaying section matching
3620
# (which implies querying the persistent storage) until it can't be
3621
# avoided anymore by using callables to describe (possibly empty)
3623
for sections in self.sections_def:
3624
for store, section in sections():
3625
value = section.get(name)
3626
if value is not None:
3629
if value is not None:
3631
value = expand_and_convert(value)
3632
if opt is not None and value is None:
3633
# If the option is registered, it may provide a default value
3634
value = opt.get_default()
3635
value = expand_and_convert(value)
3256
3636
for hook in ConfigHooks['get']:
3257
3637
hook(self, name, value)
3330
3710
or deleting an option. In practice the store will often be loaded but
3331
3711
this helps catching some programming errors.
3333
section = self.store.get_mutable_section(self.mutable_section_id)
3714
section = store.get_mutable_section(self.mutable_section_id)
3715
return store, section
3336
3717
def set(self, name, value):
3337
3718
"""Set a new value for the option."""
3338
section = self._get_mutable_section()
3339
section.set(name, value)
3719
store, section = self._get_mutable_section()
3720
section.set(name, store.quote(value))
3340
3721
for hook in ConfigHooks['set']:
3341
3722
hook(self, name, value)
3343
3724
def remove(self, name):
3344
3725
"""Remove an existing option."""
3345
section = self._get_mutable_section()
3726
_, section = self._get_mutable_section()
3346
3727
section.remove(name)
3347
3728
for hook in ConfigHooks['remove']:
3348
3729
hook(self, name)
3742
class MemoryStack(Stack):
3743
"""A configuration stack defined from a string.
3745
This is mainly intended for tests and requires no disk resources.
3748
def __init__(self, content=None):
3749
"""Create an in-memory stack from a given content.
3751
It uses a single store based on configobj and support reading and
3754
:param content: The initial content of the store. If None, the store is
3755
not loaded and ``_load_from_string`` can and should be used if
3758
store = IniFileStore()
3759
if content is not None:
3760
store._load_from_string(content)
3761
super(MemoryStack, self).__init__(
3762
[store.get_sections], store)
3361
3765
class _CompatibleStack(Stack):
3362
3766
"""Place holder for compatibility with previous design.
3392
3796
class GlobalStack(_CompatibleStack):
3393
"""Global options only stack."""
3797
"""Global options only stack.
3799
The following sections are queried:
3801
* command-line overrides,
3803
* the 'DEFAULT' section in bazaar.conf
3805
This stack will use the ``DEFAULT`` section in bazaar.conf as its
3395
3809
def __init__(self):
3397
3810
gstore = GlobalStore()
3398
3811
super(GlobalStack, self).__init__(
3399
[self._get_overrides, NameMatcher(gstore, 'DEFAULT').get_sections],
3812
[self._get_overrides,
3813
NameMatcher(gstore, 'DEFAULT').get_sections],
3400
3814
gstore, mutable_section_id='DEFAULT')
3403
3817
class LocationStack(_CompatibleStack):
3404
"""Per-location options falling back to global options stack."""
3818
"""Per-location options falling back to global options stack.
3821
The following sections are queried:
3823
* command-line overrides,
3825
* the sections matching ``location`` in ``locations.conf``, the order being
3826
defined by the number of path components in the section glob, higher
3827
numbers first (from most specific section to most generic).
3829
* the 'DEFAULT' section in bazaar.conf
3831
This stack will use the ``location`` section in locations.conf as its
3406
3835
def __init__(self, location):
3407
3836
"""Make a new stack for a location and global configuration.
3409
3838
:param location: A URL prefix to """
3410
3839
lstore = LocationStore()
3411
3840
if location.startswith('file://'):
3412
3841
location = urlutils.local_path_from_url(location)
3413
matcher = LocationMatcher(lstore, location)
3414
3842
gstore = GlobalStore()
3415
3843
super(LocationStack, self).__init__(
3416
3844
[self._get_overrides,
3417
matcher.get_sections, NameMatcher(gstore, 'DEFAULT').get_sections],
3845
LocationMatcher(lstore, location).get_sections,
3846
NameMatcher(gstore, 'DEFAULT').get_sections],
3418
3847
lstore, mutable_section_id=location)
3421
3850
class BranchStack(_CompatibleStack):
3422
"""Per-location options falling back to branch then global options stack."""
3851
"""Per-location options falling back to branch then global options stack.
3853
The following sections are queried:
3855
* command-line overrides,
3857
* the sections matching ``location`` in ``locations.conf``, the order being
3858
defined by the number of path components in the section glob, higher
3859
numbers first (from most specific section to most generic),
3861
* the no-name section in branch.conf,
3863
* the ``DEFAULT`` section in ``bazaar.conf``.
3865
This stack will use the no-name section in ``branch.conf`` as its
3424
3869
def __init__(self, branch):
3870
lstore = LocationStore()
3425
3871
bstore = branch._get_config_store()
3426
lstore = LocationStore()
3427
matcher = LocationMatcher(lstore, branch.base)
3428
3872
gstore = GlobalStore()
3429
3873
super(BranchStack, self).__init__(
3430
3874
[self._get_overrides,
3431
matcher.get_sections, bstore.get_sections,
3875
LocationMatcher(lstore, branch.base).get_sections,
3876
NameMatcher(bstore, None).get_sections,
3432
3877
NameMatcher(gstore, 'DEFAULT').get_sections],
3434
3879
self.branch = branch
3444
3889
def __init__(self, bzrdir):
3445
3890
cstore = bzrdir._get_config_store()
3446
3891
super(RemoteControlStack, self).__init__(
3447
[cstore.get_sections],
3892
[NameMatcher(cstore, None).get_sections],
3449
3894
self.bzrdir = bzrdir
3452
class RemoteBranchStack(_CompatibleStack):
3453
"""Remote branch-only options stack."""
3897
class BranchOnlyStack(_CompatibleStack):
3898
"""Branch-only options stack."""
3455
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3456
# with the stack used for remote branches. RemoteBranchStack only uses
3457
# branch.conf and is used only for the stack options.
3900
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3901
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3902
# -- vila 2011-12-16
3459
3904
def __init__(self, branch):
3460
3905
bstore = branch._get_config_store()
3461
super(RemoteBranchStack, self).__init__(
3462
[bstore.get_sections],
3906
super(BranchOnlyStack, self).__init__(
3907
[NameMatcher(bstore, None).get_sections],
3464
3909
self.branch = branch
3466
3912
# Use a an empty dict to initialize an empty configobj avoiding all
3467
3913
# parsing and encoding checks
3468
3914
_quoting_config = configobj.ConfigObj(
3469
{}, encoding='utf-8', interpolation=False)
3915
{}, encoding='utf-8', interpolation=False, list_values=True)
3471
3917
class cmd_config(commands.Command):
3472
3918
__doc__ = """Display, set or remove a configuration option.
3592
4038
self.outf.write('%s:\n' % (store.id,))
3593
4039
cur_store_id = store.id
3594
4040
cur_section = None
3595
if (section.id not in (None, 'DEFAULT')
4041
if (section.id is not None
3596
4042
and cur_section != section.id):
3597
# Display the section if it's not the default (or
4043
# Display the section id as it appears in the store
4044
# (None doesn't appear by definition)
3599
4045
self.outf.write(' [%s]\n' % (section.id,))
3600
4046
cur_section = section.id
3601
4047
value = section.get(oname, expand=False)
4048
# Since we don't use the stack, we need to restore a
4051
opt = option_registry.get(oname)
4052
value = opt.convert_from_unicode(store, value)
4054
value = store.unquote(value)
3602
4055
value = _quoting_config._quote(value)
3603
4056
self.outf.write(' %s = %s\n' % (oname, value))