/breezy/unstable

To get this branch, use:
bzr branch https://code.breezy-vcs.org/breezy/unstable

« back to all changes in this revision

Viewing changes to breezy/config.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-24 01:39:33 UTC
  • mfrom: (3815.3776.6)
  • Revision ID: jelmer@jelmer.uk-20170524013933-ir4y4tqtrsiz2ka2
New upstream snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
"""Configuration that affects the behaviour of Bazaar.
20
20
 
21
21
Currently this configuration resides in ~/.bazaar/bazaar.conf
22
 
and ~/.bazaar/locations.conf, which is written to by bzr.
 
22
and ~/.bazaar/locations.conf, which is written to by brz.
23
23
 
24
24
In bazaar.conf the following options may be set:
25
25
[DEFAULT]
48
48
explanation of options
49
49
----------------------
50
50
editor - this option sets the pop up editor to use during commits.
51
 
email - this option sets the user id bzr will use when committing.
52
 
check_signatures - this option will control whether bzr will require good gpg
 
51
email - this option sets the user id brz will use when committing.
 
52
check_signatures - this option will control whether brz will require good gpg
53
53
                   signatures, ignore them, or check them if they are
54
54
                   present.  Currently it is unused except that check_signatures
55
55
                   turns on create_signatures.
56
 
create_signatures - this option controls whether bzr will always create
 
56
create_signatures - this option controls whether brz will always create
57
57
                    gpg signatures or not on commits.  There is an unused
58
58
                    option which in future is expected to work if
59
59
                    branch settings require signatures.
73
73
"""
74
74
 
75
75
from __future__ import absolute_import
76
 
from cStringIO import StringIO
77
76
import os
78
77
import sys
79
78
 
80
 
import bzrlib
81
 
from bzrlib.decorators import needs_write_lock
82
 
from bzrlib.lazy_import import lazy_import
 
79
import configobj
 
80
 
 
81
import breezy
 
82
from .decorators import needs_write_lock
 
83
from .lazy_import import lazy_import
83
84
lazy_import(globals(), """
84
85
import base64
85
86
import fnmatch
86
87
import re
87
88
 
88
 
from bzrlib import (
 
89
from breezy import (
89
90
    atomicfile,
90
91
    controldir,
91
92
    debug,
103
104
    urlutils,
104
105
    win32utils,
105
106
    )
106
 
from bzrlib.i18n import gettext
107
 
from bzrlib.util.configobj import configobj
 
107
from breezy.i18n import gettext
108
108
""")
109
 
from bzrlib import (
 
109
from . import (
110
110
    commands,
111
111
    hooks,
112
112
    lazy_regex,
113
113
    registry,
114
114
    )
115
 
from bzrlib.symbol_versioning import (
 
115
from .sixish import (
 
116
    binary_type,
 
117
    BytesIO,
 
118
    text_type,
 
119
    string_types,
 
120
    )
 
121
from .symbol_versioning import (
116
122
    deprecated_in,
117
123
    deprecated_method,
118
124
    )
176
182
                     % signature_string)
177
183
 
178
184
 
 
185
def _has_decode_bug():
 
186
    """True if configobj will fail to decode to unicode on Python 2."""
 
187
    if sys.version_info > (3,):
 
188
        return False
 
189
    conf = configobj.ConfigObj()
 
190
    decode = getattr(conf, "_decode", None)
 
191
    if decode:
 
192
        result = decode(b"\xc2\xa7", "utf-8")
 
193
        if isinstance(result[0], str):
 
194
            return True
 
195
    return False
 
196
 
 
197
 
 
198
def _has_triplequote_bug():
 
199
    """True if triple quote logic is reversed, see lp:710410."""
 
200
    conf = configobj.ConfigObj()
 
201
    quote = getattr(conf, "_get_triple_quote", None)
 
202
    if quote and quote('"""') != "'''":
 
203
        return True
 
204
    return False
 
205
 
 
206
 
179
207
class ConfigObj(configobj.ConfigObj):
180
208
 
181
209
    def __init__(self, infile=None, **kwargs):
184
212
                                        interpolation=False,
185
213
                                        **kwargs)
186
214
 
 
215
    if _has_decode_bug():
 
216
        def _decode(self, infile, encoding):
 
217
            if isinstance(infile, str) and encoding:
 
218
                return infile.decode(encoding).splitlines(True)
 
219
            return super(ConfigObj, self)._decode(infile, encoding)
 
220
 
 
221
    if _has_triplequote_bug():
 
222
        def _get_triple_quote(self, value):
 
223
            quot = super(ConfigObj, self)._get_triple_quote(value)
 
224
            if quot == configobj.tdquot:
 
225
                return configobj.tsquot
 
226
            return configobj.tdquot
 
227
 
187
228
    def get_bool(self, section, key):
188
229
        return self[section].as_bool(key)
189
230
 
208
249
        raise NotImplementedError(self.config_id)
209
250
 
210
251
    def get_change_editor(self, old_tree, new_tree):
211
 
        from bzrlib import diff
 
252
        from breezy import diff
212
253
        cmd = self._get_change_editor()
213
254
        if cmd is None:
214
255
            return None
334
375
            value = env[name]
335
376
        else:
336
377
            # FIXME: This is a limited implementation, what we really need is a
337
 
            # way to query the bzr config for the value of an option,
 
378
            # way to query the brz config for the value of an option,
338
379
            # respecting the scope rules (That is, once we implement fallback
339
380
            # configs, getting the option value should restart from the top
340
381
            # config, not the current one) -- vila 20101222
398
439
            otherwise.
399
440
        """
400
441
        l = self.get_user_option(option_name, expand=expand)
401
 
        if isinstance(l, (str, unicode)):
 
442
        if isinstance(l, string_types):
402
443
            # A single value, most probably the user forgot (or didn't care to
403
444
            # add) the final ','
404
445
            l = [l]
512
553
 
513
554
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
514
555
 
515
 
        $BZR_EMAIL can be set to override this, then
 
556
        $BRZ_EMAIL can be set to override this, then
516
557
        the concrete policy type is checked, and finally
517
558
        $EMAIL is examined.
518
559
        If no username can be found, errors.NoWhoami exception is raised.
519
560
        """
520
 
        v = os.environ.get('BZR_EMAIL')
 
561
        v = os.environ.get('BRZ_EMAIL')
521
562
        if v:
522
563
            return v.decode(osutils.get_user_encoding())
523
564
        v = self._get_user_id()
636
677
        These are all empty initially, because by default nothing should get
637
678
        notified.
638
679
        """
639
 
        super(_ConfigHooks, self).__init__('bzrlib.config', 'ConfigHooks')
 
680
        super(_ConfigHooks, self).__init__('breezy.config', 'ConfigHooks')
640
681
        self.add_hook('load',
641
682
                      'Invoked when a config store is loaded.'
642
683
                      ' The signature is (store).',
671
712
        These are all empty initially, because by default nothing should get
672
713
        notified.
673
714
        """
674
 
        super(_OldConfigHooks, self).__init__('bzrlib.config', 'OldConfigHooks')
 
715
        super(_OldConfigHooks, self).__init__('breezy.config', 'OldConfigHooks')
675
716
        self.add_hook('load',
676
717
                      'Invoked when a config store is loaded.'
677
718
                      ' The signature is (config).',
736
777
        return conf
737
778
 
738
779
    def _create_from_string(self, str_or_unicode, save):
739
 
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
780
        self._content = BytesIO(str_or_unicode.encode('utf-8'))
740
781
        # Some tests use in-memory configs, some other always need the config
741
782
        # file to exist on disk.
742
783
        if save:
759
800
            co_input = self.file_name
760
801
        try:
761
802
            self._parser = ConfigObj(co_input, encoding='utf-8')
762
 
        except configobj.ConfigObjError, e:
 
803
        except configobj.ConfigObjError as e:
763
804
            raise errors.ParseConfigError(e.errors, e.config.filename)
764
805
        except UnicodeDecodeError:
765
806
            raise errors.ConfigContentError(self.file_name)
1195
1236
 
1196
1237
    def _get_matching_sections(self):
1197
1238
        """Return an ordered list of section names matching this location."""
1198
 
        matches = list(_iter_for_location_by_parts(self._get_parser(),
1199
 
                                                   self.location))
1200
1239
        # put the longest (aka more specific) locations first
1201
 
        matches.sort(
1202
 
            key=lambda (section, extra_path, length): (length, section),
 
1240
        matches = sorted(
 
1241
            _iter_for_location_by_parts(self._get_parser(), self.location),
 
1242
            key=lambda match: (match[2], match[0]),
1203
1243
            reverse=True)
1204
1244
        for (section, extra_path, length) in matches:
1205
1245
            yield section, extra_path
1484
1524
        osutils.copy_ownership_from_path(path)
1485
1525
 
1486
1526
 
1487
 
def config_dir():
 
1527
def bazaar_config_dir():
1488
1528
    """Return per-user configuration directory as unicode string
1489
1529
 
1490
1530
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1515
1555
    return osutils.pathjoin(base, ".bazaar")
1516
1556
 
1517
1557
 
 
1558
def config_dir():
 
1559
    """Return per-user configuration directory as unicode string
 
1560
 
 
1561
    By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
 
1562
    Mac OS X and Linux. If the breezy config directory doesn't exist but
 
1563
    the bazaar one (see bazaar_config_dir()) does, use that instead.
 
1564
 
 
1565
    TODO: Global option --config-dir to override this.
 
1566
    """
 
1567
    base = osutils.path_from_environ('BRZ_HOME')
 
1568
    if sys.platform == 'win32':
 
1569
        if base is None:
 
1570
            base = win32utils.get_appdata_location()
 
1571
        if base is None:
 
1572
            base = win32utils.get_home_location()
 
1573
        # GZ 2012-02-01: Really the two level subdirs only make sense inside
 
1574
        #                APPDATA, but hard to move. See bug 348640 for more.
 
1575
    if base is None:
 
1576
        base = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1577
        if base is None:
 
1578
            base = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1579
    breezy_dir = osutils.pathjoin(base, 'breezy')
 
1580
    if osutils.isdir(breezy_dir):
 
1581
        return breezy_dir
 
1582
    # If the breezy directory doesn't exist, but the bazaar one does, use that:
 
1583
    bazaar_dir = bazaar_config_dir()
 
1584
    if osutils.isdir(bazaar_dir):
 
1585
        trace.mutter(
 
1586
            "Using Bazaar configuration directory (%s)", bazaar_dir)
 
1587
        return bazaar_dir
 
1588
    return breezy_dir
 
1589
 
 
1590
 
1518
1591
def config_filename():
1519
1592
    """Return per-user configuration ini file filename."""
1520
1593
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
1572
1645
        return None
1573
1646
    try:
1574
1647
        f = open(mailname_file)
1575
 
    except (IOError, OSError), e:
 
1648
    except (IOError, OSError) as e:
1576
1649
        return None
1577
1650
    try:
1578
1651
        domain = f.readline().strip()
1582
1655
 
1583
1656
 
1584
1657
def default_email():
1585
 
    v = os.environ.get('BZR_EMAIL')
 
1658
    v = os.environ.get('BRZ_EMAIL')
1586
1659
    if v:
1587
1660
        return v.decode(osutils.get_user_encoding())
1588
1661
    v = os.environ.get('EMAIL')
1639
1712
        try:
1640
1713
            encoding = osutils.get_user_encoding()
1641
1714
            gecos = w.pw_gecos.decode(encoding)
1642
 
        except UnicodeError, e:
 
1715
        except UnicodeError as e:
1643
1716
            trace.mutter("cannot decode passwd entry %s" % w)
1644
1717
            return None, None
1645
1718
    try:
1646
1719
        username = w.pw_name.decode(encoding)
1647
 
    except UnicodeError, e:
 
1720
    except UnicodeError as e:
1648
1721
        trace.mutter("cannot decode passwd entry %s" % w)
1649
1722
        return None, None
1650
1723
 
1751
1824
            # Note: the encoding below declares that the file itself is utf-8
1752
1825
            # encoded, but the values in the ConfigObj are always Unicode.
1753
1826
            self._config = ConfigObj(self._input, encoding='utf-8')
1754
 
        except configobj.ConfigObjError, e:
 
1827
        except configobj.ConfigObjError as e:
1755
1828
            raise errors.ParseConfigError(e.errors, e.config.filename)
1756
1829
        except UnicodeError:
1757
1830
            raise errors.ConfigContentError(self._filename)
1810
1883
        """
1811
1884
        credentials = None
1812
1885
        for auth_def_name, auth_def in self._get_config().items():
1813
 
            if type(auth_def) is not configobj.Section:
 
1886
            if not isinstance(auth_def, configobj.Section):
1814
1887
                raise ValueError("%s defined outside a section" % auth_def_name)
1815
1888
 
1816
1889
            a_scheme, a_host, a_user, a_path = map(
2020
2093
    A credential store provides access to credentials via the password_encoding
2021
2094
    field in authentication.conf sections.
2022
2095
 
2023
 
    Except for stores provided by bzr itself, most stores are expected to be
 
2096
    Except for stores provided by brz itself, most stores are expected to be
2024
2097
    provided by plugins that will therefore use
2025
2098
    register_lazy(password_encoding, module_name, member_name, help=help,
2026
2099
    fallback=fallback) to install themselves.
2243
2316
 
2244
2317
    def _get_config_file(self):
2245
2318
        try:
2246
 
            f = StringIO(self._transport.get_bytes(self._filename))
 
2319
            f = BytesIO(self._transport.get_bytes(self._filename))
2247
2320
            for hook in OldConfigHooks['load']:
2248
2321
                hook(self)
2249
2322
            return f
2250
2323
        except errors.NoSuchFile:
2251
 
            return StringIO()
2252
 
        except errors.PermissionDenied, e:
 
2324
            return BytesIO()
 
2325
        except errors.PermissionDenied as e:
2253
2326
            trace.warning("Permission denied while trying to open "
2254
2327
                "configuration file %s.", urlutils.unescape_for_display(
2255
2328
                urlutils.join(self._transport.base, self._filename), "utf-8"))
2256
 
            return StringIO()
 
2329
            return BytesIO()
2257
2330
 
2258
2331
    def _external_url(self):
2259
2332
        return urlutils.join(self._transport.external_url(), self._filename)
2263
2336
        try:
2264
2337
            try:
2265
2338
                conf = ConfigObj(f, encoding='utf-8')
2266
 
            except configobj.ConfigObjError, e:
 
2339
            except configobj.ConfigObjError as e:
2267
2340
                raise errors.ParseConfigError(e.errors, self._external_url())
2268
2341
            except UnicodeDecodeError:
2269
2342
                raise errors.ConfigContentError(self._external_url())
2272
2345
        return conf
2273
2346
 
2274
2347
    def _set_configobj(self, configobj):
2275
 
        out_file = StringIO()
 
2348
        out_file = BytesIO()
2276
2349
        configobj.write(out_file)
2277
2350
        out_file.seek(0)
2278
2351
        self._transport.put_file(self._filename, out_file)
2344
2417
                raise AssertionError(
2345
2418
                    'Only empty lists are supported as default values')
2346
2419
            self.default = u','
2347
 
        elif isinstance(default, (str, unicode, bool, int, float)):
 
2420
        elif isinstance(default, (binary_type, text_type, bool, int, float)):
2348
2421
            # Rely on python to convert strings, booleans and integers
2349
2422
            self.default = u'%s' % (default,)
2350
2423
        elif callable(default):
2409
2482
            # Otherwise, fallback to the value defined at registration
2410
2483
            if callable(self.default):
2411
2484
                value = self.default()
2412
 
                if not isinstance(value, unicode):
 
2485
                if not isinstance(value, text_type):
2413
2486
                    raise AssertionError(
2414
2487
                        "Callable default value for '%s' should be unicode"
2415
2488
                        % (self.name))
2422
2495
 
2423
2496
    def get_help_text(self, additional_see_also=None, plain=True):
2424
2497
        result = self.help
2425
 
        from bzrlib import help_topics
 
2498
        from breezy import help_topics
2426
2499
        result += help_topics._format_see_also(additional_see_also)
2427
2500
        if plain:
2428
2501
            result = help_topics.help_as_plain_text(result)
2492
2565
            invalid=invalid, unquote=False)
2493
2566
 
2494
2567
    def from_unicode(self, unicode_str):
2495
 
        if not isinstance(unicode_str, basestring):
 
2568
        if not isinstance(unicode_str, string_types):
2496
2569
            raise TypeError
2497
2570
        # Now inject our string directly as unicode. All callers got their
2498
2571
        # value from configobj, so values that need to be quoted are already
2500
2573
        _list_converter_config.reset()
2501
2574
        _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2502
2575
        maybe_list = _list_converter_config['list']
2503
 
        if isinstance(maybe_list, basestring):
 
2576
        if isinstance(maybe_list, string_types):
2504
2577
            if maybe_list:
2505
2578
                # A single value, most probably the user forgot (or didn't care
2506
2579
                # to add) the final ','
2532
2605
        self.registry = registry
2533
2606
 
2534
2607
    def from_unicode(self, unicode_str):
2535
 
        if not isinstance(unicode_str, basestring):
 
2608
        if not isinstance(unicode_str, string_types):
2536
2609
            raise TypeError
2537
2610
        try:
2538
2611
            return self.registry.get(unicode_str)
2673
2746
Whether revisions associated with tags should be fetched.
2674
2747
"""))
2675
2748
option_registry.register_lazy(
2676
 
    'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
 
2749
    'bzr.transform.orphan_policy', 'breezy.transform', 'opt_transform_orphan')
2677
2750
option_registry.register(
2678
2751
    Option('bzr.workingtree.worth_saving_limit', default=10,
2679
2752
           from_unicode=int_from_store,  invalid='warning',
2754
2827
    Option('editor',
2755
2828
           help='The command called to launch an editor to enter a message.'))
2756
2829
option_registry.register(
2757
 
    Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
 
2830
    Option('email', override_from_env=['BRZ_EMAIL'], default=default_email,
2758
2831
           help='The users identity'))
2759
2832
option_registry.register(
2760
2833
    Option('gpg_signing_command',
2803
2876
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2804
2877
may be provided by plugins.
2805
2878
'''))
2806
 
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
 
2879
option_registry.register_lazy('mail_client', 'breezy.mail_client',
2807
2880
    'opt_mail_client')
2808
2881
option_registry.register(
2809
2882
    Option('output_encoding',
2827
2900
 
2828
2901
Each function takes branch, rev_id as parameters.
2829
2902
'''))
2830
 
option_registry.register_lazy('progress_bar', 'bzrlib.ui.text',
 
2903
option_registry.register_lazy('progress_bar', 'breezy.ui.text',
2831
2904
                              'opt_progress_bar')
2832
2905
option_registry.register(
2833
2906
    Option('public_branch',
2866
2939
lost if the machine crashes.  See also dirstate.fdatasync.
2867
2940
'''))
2868
2941
option_registry.register_lazy('smtp_server',
2869
 
    'bzrlib.smtp_connection', 'smtp_server')
 
2942
    'breezy.smtp_connection', 'smtp_server')
2870
2943
option_registry.register_lazy('smtp_password',
2871
 
    'bzrlib.smtp_connection', 'smtp_password')
 
2944
    'breezy.smtp_connection', 'smtp_password')
2872
2945
option_registry.register_lazy('smtp_username',
2873
 
    'bzrlib.smtp_connection', 'smtp_username')
 
2946
    'breezy.smtp_connection', 'smtp_username')
2874
2947
option_registry.register(
2875
2948
    Option('selftest.timeout',
2876
2949
        default='600',
2916
2989
option_registry.register(
2917
2990
    Option('validate_signatures_in_log', default=False,
2918
2991
           from_unicode=bool_from_store, invalid='warning',
2919
 
           help='''Whether to validate signatures in bzr log.'''))
 
2992
           help='''Whether to validate signatures in brz log.'''))
2920
2993
option_registry.register_lazy('ssl.ca_certs',
2921
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
 
2994
    'breezy.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2922
2995
 
2923
2996
option_registry.register_lazy('ssl.cert_reqs',
2924
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
 
2997
    'breezy.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2925
2998
 
2926
2999
 
2927
3000
class Section(object):
3222
3295
        """
3223
3296
        if self.is_loaded():
3224
3297
            raise AssertionError('Already loaded: %r' % (self._config_obj,))
3225
 
        co_input = StringIO(bytes)
 
3298
        co_input = BytesIO(bytes)
3226
3299
        try:
3227
3300
            # The config files are always stored utf8-encoded
3228
3301
            self._config_obj = ConfigObj(co_input, encoding='utf-8',
3229
3302
                                         list_values=False)
3230
 
        except configobj.ConfigObjError, e:
 
3303
        except configobj.ConfigObjError as e:
3231
3304
            self._config_obj = None
3232
3305
            raise errors.ParseConfigError(e.errors, self.external_url())
3233
3306
        except UnicodeDecodeError:
3249
3322
        if not self.is_loaded():
3250
3323
            # Nothing to save
3251
3324
            return
3252
 
        out = StringIO()
 
3325
        out = BytesIO()
3253
3326
        self._config_obj.write(out)
3254
3327
        self._save_content(out.getvalue())
3255
3328
        for hook in ConfigHooks['save']:
3302
3375
            self._config_obj.list_values = False
3303
3376
 
3304
3377
    def unquote(self, value):
3305
 
        if value and isinstance(value, basestring):
 
3378
        if value and isinstance(value, string_types):
3306
3379
            # _unquote doesn't handle None nor empty strings nor anything that
3307
3380
            # is not a string, really.
3308
3381
            value = self._config_obj._unquote(value)
3351
3424
        # The following will do in the interim but maybe we don't want to
3352
3425
        # expose a path here but rather a config ID and its associated
3353
3426
        # object </hand wawe>.
3354
 
        return urlutils.join(self.transport.external_url(), self.file_name)
 
3427
        return urlutils.join(self.transport.external_url(), self.file_name.encode("ascii"))
3355
3428
 
3356
3429
 
3357
3430
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3629
3702
 
3630
3703
    def get_sections(self):
3631
3704
        # Override the default implementation as we want to change the order
3632
 
        matching_sections = self._get_matching_sections()
3633
3705
        # We want the longest (aka more specific) locations first
3634
 
        sections = sorted(matching_sections,
3635
 
                          key=lambda (length, section): (length, section.id),
 
3706
        sections = sorted(self._get_matching_sections(),
 
3707
                          key=lambda match: (match[0], match[1].id),
3636
3708
                          reverse=True)
3637
3709
        # Sections mentioning 'ignore_parents' restrict the selection
3638
3710
        for _, section in sections:
3716
3788
            # None or ends up being None during expansion or conversion.
3717
3789
            if val is not None:
3718
3790
                if expand:
3719
 
                    if isinstance(val, basestring):
 
3791
                    if isinstance(val, string_types):
3720
3792
                        val = self._expand_options_in_string(val)
3721
3793
                    else:
3722
3794
                        trace.warning('Cannot expand "%s":'
3845
3917
 
3846
3918
    def _get_overrides(self):
3847
3919
        # FIXME: Hack around library_state.initialize never called
3848
 
        if bzrlib.global_state is not None:
3849
 
            return bzrlib.global_state.cmdline_overrides.get_sections()
 
3920
        if breezy.global_state is not None:
 
3921
            return breezy.global_state.cmdline_overrides.get_sections()
3850
3922
        return []
3851
3923
 
3852
3924
    def get_shared_store(self, store, state=None):
3863
3935
            otherwise.
3864
3936
        """
3865
3937
        if state is None:
3866
 
            state = bzrlib.global_state
 
3938
            state = breezy.global_state
3867
3939
        if state is None:
3868
3940
            global _shared_stores_at_exit_installed
3869
3941
            stores = _shared_stores
3870
3942
            def save_config_changes():
3871
 
                for k, store in stores.iteritems():
 
3943
                for k, store in stores.items():
3872
3944
                    store.save_changes()
3873
3945
            if not _shared_stores_at_exit_installed:
3874
3946
                # FIXME: Ugly hack waiting for library_state to always be
4121
4193
        # http://pad.lv/788991 -- vila 20101115
4122
4194
        commands.Option('scope', help='Reduce the scope to the specified'
4123
4195
                        ' configuration file.',
4124
 
                        type=unicode),
 
4196
                        type=text_type),
4125
4197
        commands.Option('all',
4126
4198
            help='Display all the defined values for the matching options.',
4127
4199
            ),
4268
4340
# themselves. The builder will receive a test instance and should return a
4269
4341
# ready-to-use store or stack.  Plugins that define new store/stacks can also
4270
4342
# register themselves here to be tested against the tests defined in
4271
 
# bzrlib.tests.test_config. Note that the builder can be called multiple times
 
4343
# breezy.tests.test_config. Note that the builder can be called multiple times
4272
4344
# for the same test.
4273
4345
 
4274
4346
# The registered object should be a callable receiving a test instance