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
2715
2729
co_input = StringIO(bytes)
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',
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.
2879
This intended to be used to postpone getting an iterable of sections from a
2894
This is intended to be used to postpone getting an iterable of sections
2883
2898
def __init__(self, store):
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):
3047
3078
except KeyError:
3048
3079
# Not registered
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)
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()
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)
3058
# The conversion failed, fallback to the default value
3059
value = opt.get_default()
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)
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'
3075
elif isinstance(value, (str, unicode)):
3076
value = self._expand_options_in_string(value)
3079
3104
def expand_options(self, string, env=None):
3080
3105
"""Expand option references in the string in the configuration context.
3089
3114
return self._expand_options_in_string(string, env)
3091
def _expand_options_in_list(self, slist, env=None, _refs=None):
3092
"""Expand options in a list of strings in the configuration context.
3094
:param slist: A list of strings.
3096
:param env: An option dict defining additional configuration options or
3097
overriding existing ones.
3099
:param _refs: Private list (FIFO) containing the options being
3100
expanded to detect loops.
3102
:returns: The flatten list of expanded strings.
3104
# expand options in each value separately flattening lists
3107
value = self._expand_options_in_string(s, env, _refs)
3108
if isinstance(value, list):
3109
result.extend(value)
3111
result.append(value)
3114
3116
def _expand_options_in_string(self, string, env=None, _refs=None):
3115
3117
"""Expand options in the string in the configuration context.
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):
3162
chunks.extend(value)
3164
chunks.append(value)
3158
chunks.append(value)
3166
3160
chunk_is_ref = False
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)
3175
result = ''.join(chunks)
3161
result = ''.join(chunks)
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)
3193
value = self._expand_options_in_string(value, env, _refs)
3176
value = self._expand_options_in_string(value, env, _refs)
3196
3179
def _get_mutable_section(self):