2426
2426
return int(unicode_str)
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)
2429
2435
def list_from_store(unicode_str):
2436
if not isinstance(unicode_str, basestring):
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
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)):
2445
if isinstance(maybe_list, basestring):
2433
2447
# A single value, most probably the user forgot (or didn't care to
2434
2448
# add) the final ','
2437
2451
# The empty string, convert to empty list
2440
2454
# We rely on ConfigObj providing us with a list already
2892
2907
if self.match(s):
2895
def match(self, secion):
2910
def match(self, section):
2911
"""Does the proposed section match.
2913
:param section: A Section object.
2915
:returns: True if the section matches, False otherwise.
2896
2917
raise NotImplementedError(self.match)
2920
class NameMatcher(SectionMatcher):
2922
def __init__(self, store, section_id):
2923
super(NameMatcher, self).__init__(store)
2924
self.section_id = section_id
2926
def match(self, section):
2927
return section.id == self.section_id
2899
2930
class LocationSection(Section):
2901
2932
def __init__(self, section, length, extra_path):
2978
3009
class Stack(object):
2979
3010
"""A stack of configurations where an option can be defined"""
3012
_option_ref_re = lazy_regex.lazy_compile('({[^{}]+})')
3013
"""Describes an exandable option reference.
3015
We want to match the most embedded reference first.
3017
I.e. for '{{foo}}' we will get '{foo}',
3018
for '{bar{baz}}' we will get '{baz}'
2981
3021
def __init__(self, sections_def, store=None, mutable_section_name=None):
2982
3022
"""Creates a stack of sections with an optional store for changes.
3004
3044
option exists or get its value, which in turn may require to discover
3005
3045
in which sections it can be defined. Both of these (section and option
3006
3046
existence) require loading the store (even partially).
3048
:param name: The queried option.
3050
:param expand: Whether options references should be expanded.
3052
:returns: The value of the option.
3008
3054
# FIXME: No caching of options nor sections yet -- vila 20110503
3056
expand = _get_expand_default_value()
3010
3058
# Ensuring lazy loading is achieved by delaying section matching (which
3011
3059
# implies querying the persistent storage) until it can't be avoided
3030
3078
except KeyError:
3031
3079
# Not registered
3034
value = opt.convert_from_unicode(value)
3036
# The conversion failed or there was no value to convert,
3037
# fallback to the default value
3038
value = opt.convert_from_unicode(opt.get_default())
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.
3086
if isinstance(val, basestring):
3087
val = self._expand_options_in_string(val)
3089
trace.warning('Cannot expand "%s":'
3090
' %s does not support option expansion'
3091
% (name, type(val)))
3093
val = opt.convert_from_unicode(val)
3095
value = expand_and_convert(value)
3096
if opt is not None and value is None:
3097
# If the option is registered, it may provide a default value
3098
value = opt.get_default()
3099
value = expand_and_convert(value)
3039
3100
for hook in ConfigHooks['get']:
3040
3101
hook(self, name, value)
3104
def expand_options(self, string, env=None):
3105
"""Expand option references in the string in the configuration context.
3107
:param string: The string containing option(s) to expand.
3109
:param env: An option dict defining additional configuration options or
3110
overriding existing ones.
3112
:returns: The expanded string.
3114
return self._expand_options_in_string(string, env)
3116
def _expand_options_in_string(self, string, env=None, _refs=None):
3117
"""Expand options in the string in the configuration context.
3119
:param string: The string to be expanded.
3121
:param env: An option dict defining additional configuration options or
3122
overriding existing ones.
3124
:param _refs: Private list (FIFO) containing the options being expanded
3127
:returns: The expanded string.
3130
# Not much to expand there
3133
# What references are currently resolved (to detect loops)
3136
# We need to iterate until no more refs appear ({{foo}} will need two
3137
# iterations for example).
3139
raw_chunks = Stack._option_ref_re.split(result)
3140
if len(raw_chunks) == 1:
3141
# Shorcut the trivial case: no refs
3144
# Split will isolate refs so that every other chunk is a ref
3145
chunk_is_ref = False
3146
for chunk in raw_chunks:
3147
if not chunk_is_ref:
3148
chunks.append(chunk)
3153
raise errors.OptionExpansionLoop(string, _refs)
3155
value = self._expand_option(name, env, _refs)
3157
raise errors.ExpandingUnknownOption(name, string)
3158
chunks.append(value)
3160
chunk_is_ref = False
3161
result = ''.join(chunks)
3164
def _expand_option(self, name, env, _refs):
3165
if env is not None and name in env:
3166
# Special case, values provided in env takes precedence over
3170
# FIXME: This is a limited implementation, what we really need is a
3171
# way to query the bzr config for the value of an option,
3172
# respecting the scope rules (That is, once we implement fallback
3173
# configs, getting the option value should restart from the top
3174
# config, not the current one) -- vila 20101222
3175
value = self.get(name, expand=False)
3176
value = self._expand_options_in_string(value, env, _refs)
3043
3179
def _get_mutable_section(self):
3044
3180
"""Get the MutableSection for the Stack.