~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Patch Queue Manager
  • Date: 2011-09-08 11:01:15 UTC
  • mfrom: (6123.1.16 gpg-typo)
  • Revision ID: pqm@cupuasso-20110908110115-gbb9benwkdksvzk5
(jelmer) Fix a typo (invalid format identifier) in an error message in
 bzrlib.gpg. (Jelmer Vernooij)

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())
2876
2891
class SectionMatcher(object):
2877
2892
    """Select sections into a given Store.
2878
2893
 
2879
 
    This intended to be used to postpone getting an iterable of sections from a
2880
 
    store.
 
2894
    This is intended to be used to postpone getting an iterable of sections
 
2895
    from a store.
2881
2896
    """
2882
2897
 
2883
2898
    def __init__(self, store):
2892
2907
            if self.match(s):
2893
2908
                yield s
2894
2909
 
2895
 
    def match(self, secion):
 
2910
    def match(self, section):
 
2911
        """Does the proposed section match.
 
2912
 
 
2913
        :param section: A Section object.
 
2914
 
 
2915
        :returns: True if the section matches, False otherwise.
 
2916
        """
2896
2917
        raise NotImplementedError(self.match)
2897
2918
 
2898
2919
 
 
2920
class NameMatcher(SectionMatcher):
 
2921
 
 
2922
    def __init__(self, store, section_id):
 
2923
        super(NameMatcher, self).__init__(store)
 
2924
        self.section_id = section_id
 
2925
 
 
2926
    def match(self, section):
 
2927
        return section.id == self.section_id
 
2928
 
 
2929
 
2899
2930
class LocationSection(Section):
2900
2931
 
2901
2932
    def __init__(self, section, length, extra_path):
3047
3078
        except KeyError:
3048
3079
            # Not registered
3049
3080
            opt = None
 
3081
        def expand_and_convert(val):
 
3082
            # This may need to be called twice if the value is None or ends up
 
3083
            # being None during expansion or conversion.
 
3084
            if val is not None:
 
3085
                if expand:
 
3086
                    if isinstance(val, basestring):
 
3087
                        val = self._expand_options_in_string(val)
 
3088
                    else:
 
3089
                        trace.warning('Cannot expand "%s":'
 
3090
                                      ' %s does not support option expansion'
 
3091
                                      % (name, type(val)))
 
3092
                if opt is not None:
 
3093
                    val = opt.convert_from_unicode(val)
 
3094
            return val
 
3095
        value = expand_and_convert(value)
3050
3096
        if opt is not None and value is None:
3051
3097
            # If the option is registered, it may provide a default value
3052
3098
            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)
 
3099
            value = expand_and_convert(value)
3063
3100
        for hook in ConfigHooks['get']:
3064
3101
            hook(self, name, value)
3065
3102
        return value
3066
3103
 
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
3104
    def expand_options(self, string, env=None):
3080
3105
        """Expand option references in the string in the configuration context.
3081
3106
 
3088
3113
        """
3089
3114
        return self._expand_options_in_string(string, env)
3090
3115
 
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
3116
    def _expand_options_in_string(self, string, env=None, _refs=None):
3115
3117
        """Expand options in the string in the configuration context.
3116
3118
 
3139
3141
                # Shorcut the trivial case: no refs
3140
3142
                return result
3141
3143
            chunks = []
3142
 
            list_value = False
3143
3144
            # Split will isolate refs so that every other chunk is a ref
3144
3145
            chunk_is_ref = False
3145
3146
            for chunk in raw_chunks:
3146
3147
                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)
 
3148
                    chunks.append(chunk)
3151
3149
                    chunk_is_ref = True
3152
3150
                else:
3153
3151
                    name = chunk[1:-1]
3157
3155
                    value = self._expand_option(name, env, _refs)
3158
3156
                    if value is None:
3159
3157
                        raise errors.ExpandingUnknownOption(name, string)
3160
 
                    if isinstance(value, list):
3161
 
                        list_value = True
3162
 
                        chunks.extend(value)
3163
 
                    else:
3164
 
                        chunks.append(value)
 
3158
                    chunks.append(value)
3165
3159
                    _refs.pop()
3166
3160
                    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)
 
3161
            result = ''.join(chunks)
3176
3162
        return result
3177
3163
 
3178
3164
    def _expand_option(self, name, env, _refs):
3187
3173
            # configs, getting the option value should restart from the top
3188
3174
            # config, not the current one) -- vila 20101222
3189
3175
            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)
 
3176
            value = self._expand_options_in_string(value, env, _refs)
3194
3177
        return value
3195
3178
 
3196
3179
    def _get_mutable_section(self):