~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Jelmer Vernooij
  • Date: 2011-09-07 11:51:20 UTC
  • mfrom: (6123.1.9 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6130.
  • Revision ID: jelmer@samba.org-20110907115120-ugiagn73ovvd7ylb
Merge bzr.dev.

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
 
2429
2435
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']
2430
2444
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2431
 
    if isinstance(unicode_str, (str, unicode)):
2432
 
        if unicode_str:
 
2445
    if isinstance(maybe_list, basestring):
 
2446
        if maybe_list:
2433
2447
            # A single value, most probably the user forgot (or didn't care to
2434
2448
            # add) the final ','
2435
 
            l = [unicode_str]
 
2449
            l = [maybe_list]
2436
2450
        else:
2437
2451
            # The empty string, convert to empty list
2438
2452
            l = []
2439
2453
    else:
2440
2454
        # We rely on ConfigObj providing us with a list already
2441
 
        l = unicode_str
 
2455
        l = maybe_list
2442
2456
    return l
2443
2457
 
2444
2458
 
2715
2729
        co_input = StringIO(bytes)
2716
2730
        try:
2717
2731
            # The config files are always stored utf8-encoded
2718
 
            self._config_obj = ConfigObj(co_input, encoding='utf-8')
 
2732
            self._config_obj = ConfigObj(co_input, encoding='utf-8',
 
2733
                                         list_values=False)
2719
2734
        except configobj.ConfigObjError, e:
2720
2735
            self._config_obj = None
2721
2736
            raise errors.ParseConfigError(e.errors, self.external_url())
3047
3062
        except KeyError:
3048
3063
            # Not registered
3049
3064
            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)
3050
3080
        if opt is not None and value is None:
3051
3081
            # If the option is registered, it may provide a default value
3052
3082
            value = opt.get_default()
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)
 
3083
            value = expand_and_convert(value)
3063
3084
        for hook in ConfigHooks['get']:
3064
3085
            hook(self, name, value)
3065
3086
        return value
3066
3087
 
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
 
 
3079
3088
    def expand_options(self, string, env=None):
3080
3089
        """Expand option references in the string in the configuration context.
3081
3090
 
3088
3097
        """
3089
3098
        return self._expand_options_in_string(string, env)
3090
3099
 
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
 
 
3114
3100
    def _expand_options_in_string(self, string, env=None, _refs=None):
3115
3101
        """Expand options in the string in the configuration context.
3116
3102
 
3139
3125
                # Shorcut the trivial case: no refs
3140
3126
                return result
3141
3127
            chunks = []
3142
 
            list_value = False
3143
3128
            # Split will isolate refs so that every other chunk is a ref
3144
3129
            chunk_is_ref = False
3145
3130
            for chunk in raw_chunks:
3146
3131
                if not chunk_is_ref:
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)
 
3132
                    chunks.append(chunk)
3151
3133
                    chunk_is_ref = True
3152
3134
                else:
3153
3135
                    name = chunk[1:-1]
3157
3139
                    value = self._expand_option(name, env, _refs)
3158
3140
                    if value is None:
3159
3141
                        raise errors.ExpandingUnknownOption(name, string)
3160
 
                    if isinstance(value, list):
3161
 
                        list_value = True
3162
 
                        chunks.extend(value)
3163
 
                    else:
3164
 
                        chunks.append(value)
 
3142
                    chunks.append(value)
3165
3143
                    _refs.pop()
3166
3144
                    chunk_is_ref = False
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)
 
3145
            result = ''.join(chunks)
3176
3146
        return result
3177
3147
 
3178
3148
    def _expand_option(self, name, env, _refs):
3187
3157
            # configs, getting the option value should restart from the top
3188
3158
            # config, not the current one) -- vila 20101222
3189
3159
            value = self.get(name, expand=False)
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)
 
3160
            value = self._expand_options_in_string(value, env, _refs)
3194
3161
        return value
3195
3162
 
3196
3163
    def _get_mutable_section(self):