~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Jelmer Vernooij
  • Date: 2011-09-04 21:41:05 UTC
  • mto: This revision was merged to the branch mainline in revision 6127.
  • Revision ID: jelmer@samba.org-20110904214105-uconiohsax3u25u6
removeĀ unusedĀ imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2426
2426
    return int(unicode_str)
2427
2427
 
2428
2428
 
2429
 
# Use a an empty dict to initialize an empty configobj avoiding all
2430
 
# parsing and encoding checks
2431
 
_list_converter_config = configobj.ConfigObj(
2432
 
    {}, encoding='utf-8', list_values=True, interpolation=False)
2433
 
 
2434
 
 
2435
2429
def list_from_store(unicode_str):
2436
 
    if not isinstance(unicode_str, basestring):
2437
 
        raise TypeError
2438
 
    # Now inject our string directly as unicode. All callers got their value
2439
 
    # from configobj, so values that need to be quoted are already properly
2440
 
    # quoted.
2441
 
    _list_converter_config.reset()
2442
 
    _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2443
 
    maybe_list = _list_converter_config['list']
2444
2430
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2445
 
    if isinstance(maybe_list, basestring):
2446
 
        if maybe_list:
 
2431
    if isinstance(unicode_str, (str, unicode)):
 
2432
        if unicode_str:
2447
2433
            # A single value, most probably the user forgot (or didn't care to
2448
2434
            # add) the final ','
2449
 
            l = [maybe_list]
 
2435
            l = [unicode_str]
2450
2436
        else:
2451
2437
            # The empty string, convert to empty list
2452
2438
            l = []
2453
2439
    else:
2454
2440
        # We rely on ConfigObj providing us with a list already
2455
 
        l = maybe_list
 
2441
        l = unicode_str
2456
2442
    return l
2457
2443
 
2458
2444
 
2729
2715
        co_input = StringIO(bytes)
2730
2716
        try:
2731
2717
            # The config files are always stored utf8-encoded
2732
 
            self._config_obj = ConfigObj(co_input, encoding='utf-8',
2733
 
                                         list_values=False)
 
2718
            self._config_obj = ConfigObj(co_input, encoding='utf-8')
2734
2719
        except configobj.ConfigObjError, e:
2735
2720
            self._config_obj = None
2736
2721
            raise errors.ParseConfigError(e.errors, self.external_url())
3062
3047
        except KeyError:
3063
3048
            # Not registered
3064
3049
            opt = None
3065
 
        def expand_and_convert(val):
3066
 
            # This may need to be called twice if the value is None or ends up
3067
 
            # being None during expansion or conversion.
3068
 
            if val is not None:
3069
 
                if expand:
3070
 
                    if isinstance(val, basestring):
3071
 
                        val = self._expand_options_in_string(val)
3072
 
                    else:
3073
 
                        trace.warning('Cannot expand "%s":'
3074
 
                                      ' %s does not support option expansion'
3075
 
                                      % (name, type(val)))
3076
 
                if opt is not None:
3077
 
                    val = opt.convert_from_unicode(val)
3078
 
            return val
3079
 
        value = expand_and_convert(value)
3080
3050
        if opt is not None and value is None:
3081
3051
            # If the option is registered, it may provide a default value
3082
3052
            value = opt.get_default()
3083
 
            value = expand_and_convert(value)
 
3053
        if expand:
 
3054
            value = self._expand_option_value(value)
 
3055
        if opt is not None and value is not None:
 
3056
            value = opt.convert_from_unicode(value)
 
3057
            if value is None:
 
3058
                # The conversion failed, fallback to the default value
 
3059
                value = opt.get_default()
 
3060
                if expand:
 
3061
                    value = self._expand_option_value(value)
 
3062
                value = opt.convert_from_unicode(value)
3084
3063
        for hook in ConfigHooks['get']:
3085
3064
            hook(self, name, value)
3086
3065
        return value
3087
3066
 
 
3067
    def _expand_option_value(self, value):
 
3068
        """Expand the option value depending on its type."""
 
3069
        if isinstance(value, list):
 
3070
            value = self._expand_options_in_list(value)
 
3071
        elif isinstance(value, dict):
 
3072
            trace.warning('Cannot expand "%s":'
 
3073
                          ' Dicts do not support option expansion'
 
3074
                          % (name,))
 
3075
        elif isinstance(value, (str, unicode)):
 
3076
            value = self._expand_options_in_string(value)
 
3077
        return value
 
3078
 
3088
3079
    def expand_options(self, string, env=None):
3089
3080
        """Expand option references in the string in the configuration context.
3090
3081
 
3097
3088
        """
3098
3089
        return self._expand_options_in_string(string, env)
3099
3090
 
 
3091
    def _expand_options_in_list(self, slist, env=None, _refs=None):
 
3092
        """Expand options in  a list of strings in the configuration context.
 
3093
 
 
3094
        :param slist: A list of strings.
 
3095
 
 
3096
        :param env: An option dict defining additional configuration options or
 
3097
            overriding existing ones.
 
3098
 
 
3099
        :param _refs: Private list (FIFO) containing the options being
 
3100
            expanded to detect loops.
 
3101
 
 
3102
        :returns: The flatten list of expanded strings.
 
3103
        """
 
3104
        # expand options in each value separately flattening lists
 
3105
        result = []
 
3106
        for s in slist:
 
3107
            value = self._expand_options_in_string(s, env, _refs)
 
3108
            if isinstance(value, list):
 
3109
                result.extend(value)
 
3110
            else:
 
3111
                result.append(value)
 
3112
        return result
 
3113
 
3100
3114
    def _expand_options_in_string(self, string, env=None, _refs=None):
3101
3115
        """Expand options in the string in the configuration context.
3102
3116
 
3125
3139
                # Shorcut the trivial case: no refs
3126
3140
                return result
3127
3141
            chunks = []
 
3142
            list_value = False
3128
3143
            # Split will isolate refs so that every other chunk is a ref
3129
3144
            chunk_is_ref = False
3130
3145
            for chunk in raw_chunks:
3131
3146
                if not chunk_is_ref:
3132
 
                    chunks.append(chunk)
 
3147
                    if chunk:
 
3148
                        # Keep only non-empty strings (or we get bogus empty
 
3149
                        # slots when a list value is involved).
 
3150
                        chunks.append(chunk)
3133
3151
                    chunk_is_ref = True
3134
3152
                else:
3135
3153
                    name = chunk[1:-1]
3139
3157
                    value = self._expand_option(name, env, _refs)
3140
3158
                    if value is None:
3141
3159
                        raise errors.ExpandingUnknownOption(name, string)
3142
 
                    chunks.append(value)
 
3160
                    if isinstance(value, list):
 
3161
                        list_value = True
 
3162
                        chunks.extend(value)
 
3163
                    else:
 
3164
                        chunks.append(value)
3143
3165
                    _refs.pop()
3144
3166
                    chunk_is_ref = False
3145
 
            result = ''.join(chunks)
 
3167
            if list_value:
 
3168
                # Once a list appears as the result of an expansion, all
 
3169
                # callers will get a list result. This allows a consistent
 
3170
                # behavior even when some options in the expansion chain
 
3171
                # defined as strings (no comma in their value) but their
 
3172
                # expanded value is a list.
 
3173
                return self._expand_options_in_list(chunks, env, _refs)
 
3174
            else:
 
3175
                result = ''.join(chunks)
3146
3176
        return result
3147
3177
 
3148
3178
    def _expand_option(self, name, env, _refs):
3157
3187
            # configs, getting the option value should restart from the top
3158
3188
            # config, not the current one) -- vila 20101222
3159
3189
            value = self.get(name, expand=False)
3160
 
            value = self._expand_options_in_string(value, env, _refs)
 
3190
            if isinstance(value, list):
 
3191
                value = self._expand_options_in_list(value, env, _refs)
 
3192
            else:
 
3193
                value = self._expand_options_in_string(value, env, _refs)
3161
3194
        return value
3162
3195
 
3163
3196
    def _get_mutable_section(self):