-#!/usr/bin/env python
# -*- coding: utf-8 -*-
+#modification pour python 3 : Laurent Mérat, 6x7 - mai 2020
-u"""Configuration file parser.
+"""Configuration file parser.
A configuration file consists of sections, lead by a "[section]" header,
and followed by "name: value" entries, with continuations and such in
between keys and values are surrounded by spaces.
"""
-from __future__ import with_statement
-from collections import MutableMapping
-from io import open
-try:
- from collections import OrderedDict as _default_dict
-except ImportError:
- from ordereddict import OrderedDict as _default_dict
-import functools
+#------------------------------------
+# import des modules python
+#------------------------------------
+from collections.abc import MutableMapping
import io
import itertools
import re
import sys
import warnings
+#------------------------------------
+# import des fichiers du projet
+#------------------------------------
from configparser_helpers import _ChainMap
-__all__ = [u"NoSectionError", u"DuplicateOptionError", u"DuplicateSectionError",
- u"NoOptionError", u"InterpolationError", u"InterpolationDepthError",
- u"InterpolationSyntaxError", u"ParsingError",
- u"MissingSectionHeaderError",
- u"ConfigParser", u"SafeConfigParser", u"RawConfigParser",
- u"DEFAULTSECT", u"MAX_INTERPOLATION_DEPTH"]
-DEFAULTSECT = u"DEFAULT"
+try:
+ from collections import OrderedDict as _default_dict
+except ImportError:
+ from ordereddict import OrderedDict as _default_dict
+import functools
+
+
+__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError",
+ "NoOptionError", "InterpolationError", "InterpolationDepthError",
+ "InterpolationSyntaxError", "ParsingError",
+ "MissingSectionHeaderError",
+ "ConfigParser", "SafeConfigParser", "RawConfigParser",
+ "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
+
+DEFAULTSECT = "DEFAULT"
MAX_INTERPOLATION_DEPTH = 10
# exception classes
class Error(Exception):
- u"""Base class for ConfigParser exceptions."""
+ """Base class for ConfigParser exceptions."""
def _get_message(self):
- u"""Getter for 'message'; needed only to override deprecation in
+ """Getter for 'message'; needed only to override deprecation in
BaseException.
"""
return self.__message
def _set_message(self, value):
- u"""Setter for 'message'; needed only to override deprecation in
+ """Setter for 'message'; needed only to override deprecation in
BaseException.
"""
self.__message = value
# a new property that takes lookup precedence.
message = property(_get_message, _set_message)
- def __init__(self, msg=u''):
+ def __init__(self, msg=''):
self.message = msg
Exception.__init__(self, msg)
class NoSectionError(Error):
- u"""Raised when no section matches a requested option."""
+ """Raised when no section matches a requested option."""
def __init__(self, section):
- Error.__init__(self, u'No section: %r' % (section,))
+ Error.__init__(self, 'No section: %r' % (section,))
self.section = section
self.args = (section, )
class DuplicateSectionError(Error):
- u"""Raised when a section is repeated in an input source.
+ """Raised when a section is repeated in an input source.
Possible repetitions that raise this exception are: multiple creation
using the API or in strict parsers when a section is found more than once
"""
def __init__(self, section, source=None, lineno=None):
- msg = [repr(section), u" already exists"]
+ msg = [repr(section), " already exists"]
if source is not None:
- message = [u"While reading from ", source]
+ message = ["While reading from ", source]
if lineno is not None:
- message.append(u" [line {0:2d}]".format(lineno))
- message.append(u": section ")
+ message.append(" [line {0:2d}]".format(lineno))
+ message.append(": section ")
message.extend(msg)
msg = message
else:
- msg.insert(0, u"Section ")
- Error.__init__(self, u"".join(msg))
+ msg.insert(0, "Section ")
+ Error.__init__(self, "".join(msg))
self.section = section
self.source = source
self.lineno = lineno
class DuplicateOptionError(Error):
- u"""Raised by strict parsers when an option is repeated in an input source.
+ """Raised by strict parsers when an option is repeated in an input source.
Current implementation raises this exception only when an option is found
more than once in a single file, string or dictionary.
"""
def __init__(self, section, option, source=None, lineno=None):
- msg = [repr(option), u" in section ", repr(section),
- u" already exists"]
+ msg = [repr(option), " in section ", repr(section),
+ " already exists"]
if source is not None:
- message = [u"While reading from ", source]
+ message = ["While reading from ", source]
if lineno is not None:
- message.append(u" [line {0:2d}]".format(lineno))
- message.append(u": option ")
+ message.append(" [line {0:2d}]".format(lineno))
+ message.append(": option ")
message.extend(msg)
msg = message
else:
- msg.insert(0, u"Option ")
- Error.__init__(self, u"".join(msg))
+ msg.insert(0, "Option ")
+ Error.__init__(self, "".join(msg))
self.section = section
self.option = option
self.source = source
class NoOptionError(Error):
- u"""A requested option was not found."""
+ """A requested option was not found."""
def __init__(self, option, section):
- Error.__init__(self, u"No option %r in section: %r" %
+ Error.__init__(self, "No option %r in section: %r" %
(option, section))
self.option = option
self.section = section
class InterpolationError(Error):
- u"""Base class for interpolation-related exceptions."""
+ """Base class for interpolation-related exceptions."""
def __init__(self, option, section, msg):
Error.__init__(self, msg)
class InterpolationMissingOptionError(InterpolationError):
- u"""A string substitution required a setting which was not available."""
+ """A string substitution required a setting which was not available."""
def __init__(self, option, section, rawval, reference):
- msg = (u"Bad value substitution:\n"
- u"\tsection: [%s]\n"
- u"\toption : %s\n"
- u"\tkey : %s\n"
- u"\trawval : %s\n"
+ msg = ("Bad value substitution:\n"
+ "\tsection: [%s]\n"
+ "\toption : %s\n"
+ "\tkey : %s\n"
+ "\trawval : %s\n"
% (section, option, reference, rawval))
InterpolationError.__init__(self, option, section, msg)
self.reference = reference
class InterpolationSyntaxError(InterpolationError):
- u"""Raised when the source text contains invalid syntax.
+ """Raised when the source text contains invalid syntax.
Current implementation raises this exception when the source text into
which substitutions are made does not conform to the required syntax.
class InterpolationDepthError(InterpolationError):
- u"""Raised when substitutions are nested too deeply."""
+ """Raised when substitutions are nested too deeply."""
def __init__(self, option, section, rawval):
- msg = (u"Value interpolation too deeply recursive:\n"
- u"\tsection: [%s]\n"
- u"\toption : %s\n"
- u"\trawval : %s\n"
+ msg = ("Value interpolation too deeply recursive:\n"
+ "\tsection: [%s]\n"
+ "\toption : %s\n"
+ "\trawval : %s\n"
% (section, option, rawval))
InterpolationError.__init__(self, option, section, msg)
self.args = (option, section, rawval)
class ParsingError(Error):
- u"""Raised when a configuration file does not follow legal syntax."""
+ """Raised when a configuration file does not follow legal syntax."""
def __init__(self, source=None, filename=None):
# Exactly one of `source'/`filename' arguments has to be given.
# `filename' kept for compatibility.
if filename and source:
- raise ValueError(u"Cannot specify both `filename' and `source'. "
- u"Use `source'.")
+ raise ValueError("Cannot specify both `filename' and `source'. "
+ "Use `source'.")
elif not filename and not source:
- raise ValueError(u"Required argument `source' not given.")
+ raise ValueError("Required argument `source' not given.")
elif filename:
source = filename
- Error.__init__(self, u'Source contains parsing errors: %s' % source)
+ Error.__init__(self, 'Source contains parsing errors: %s' % source)
self.source = source
self.errors = []
self.args = (source, )
@property
def filename(self):
- u"""Deprecated, use `source'."""
+ """Deprecated, use `source'."""
warnings.warn(
- u"The 'filename' attribute will be removed in future versions. "
- u"Use 'source' instead.",
+ "The 'filename' attribute will be removed in future versions. "
+ "Use 'source' instead.",
DeprecationWarning, stacklevel=2
)
return self.source
@filename.setter
def filename(self, value):
- u"""Deprecated, user `source'."""
+ """Deprecated, user `source'."""
warnings.warn(
- u"The 'filename' attribute will be removed in future versions. "
- u"Use 'source' instead.",
+ "The 'filename' attribute will be removed in future versions. "
+ "Use 'source' instead.",
DeprecationWarning, stacklevel=2
)
self.source = value
def append(self, lineno, line):
self.errors.append((lineno, line))
- self.message += u'\n\t[line %2d]: %s' % (lineno, line)
+ self.message += '\n\t[line %2d]: %s' % (lineno, line)
class MissingSectionHeaderError(ParsingError):
- u"""Raised when a key-value pair is found before any section header."""
+ """Raised when a key-value pair is found before any section header."""
def __init__(self, filename, lineno, line):
Error.__init__(
self,
- u'File contains no section headers.\nfile: %s, line: %d\n%r' %
+ 'File contains no section headers.\nfile: %s, line: %d\n%r' %
(filename, lineno, line))
self.source = filename
self.lineno = lineno
class Interpolation(object):
- u"""Dummy interpolation that passes the value through with no changes."""
+ """Dummy interpolation that passes the value through with no changes."""
def before_get(self, parser, section, option, value, defaults):
return value
class BasicInterpolation(Interpolation):
- u"""Interpolation as implemented in the classic ConfigParser.
+ """Interpolation as implemented in the classic ConfigParser.
The option values can contain format strings which refer to other values in
the same section, or values in the special default section.
a configuration file, she can escape it by writing %%. Other other % usage
is considered a user error and raises `InterpolationSyntaxError'."""
- _KEYCRE = re.compile(ur"%\(([^)]+)\)s")
+ _KEYCRE = re.compile(r"%\(([^)]+)\)s")
def before_get(self, parser, section, option, value, defaults):
L = []
self._interpolate_some(parser, option, L, value, section, defaults, 1)
- return u''.join(L)
+ return ''.join(L)
def before_set(self, parser, section, option, value):
- tmp_value = value.replace(u'%%', u'') # escaped percent signs
- tmp_value = self._KEYCRE.sub(u'', tmp_value) # valid syntax
- if u'%' in tmp_value:
- raise ValueError(u"invalid interpolation syntax in %r at "
- u"position %d" % (value, tmp_value.find(u'%')))
+ tmp_value = value.replace('%%', '') # escaped percent signs
+ tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
+ if '%' in tmp_value:
+ raise ValueError("invalid interpolation syntax in %r at "
+ "position %d" % (value, tmp_value.find('%')))
return value
def _interpolate_some(self, parser, option, accum, rest, section, map,
if depth > MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rest)
while rest:
- p = rest.find(u"%")
+ p = rest.find("%")
if p < 0:
accum.append(rest)
return
rest = rest[p:]
# p is no longer used
c = rest[1:2]
- if c == u"%":
- accum.append(u"%")
+ if c == "%":
+ accum.append("%")
rest = rest[2:]
- elif c == u"(":
+ elif c == "(":
m = self._KEYCRE.match(rest)
if m is None:
raise InterpolationSyntaxError(option, section,
- u"bad interpolation variable reference %r" % rest)
+ "bad interpolation variable reference %r" % rest)
var = parser.optionxform(m.group(1))
rest = rest[m.end():]
try:
except KeyError:
raise InterpolationMissingOptionError(
option, section, rest, var)
- if u"%" in v:
+ if "%" in v:
self._interpolate_some(parser, option, accum, v,
section, map, depth + 1)
else:
else:
raise InterpolationSyntaxError(
option, section,
- u"'%%' must be followed by '%%' or '(', "
- u"found: %r" % (rest,))
+ "'%%' must be followed by '%%' or '(', "
+ "found: %r" % (rest,))
class ExtendedInterpolation(Interpolation):
- u"""Advanced variant of interpolation, supports the syntax used by
+ """Advanced variant of interpolation, supports the syntax used by
`zc.buildout'. Enables interpolation between sections."""
- _KEYCRE = re.compile(ur"\$\{([^}]+)\}")
+ _KEYCRE = re.compile(r"\$\{([^}]+)\}")
def before_get(self, parser, section, option, value, defaults):
L = []
self._interpolate_some(parser, option, L, value, section, defaults, 1)
- return u''.join(L)
+ return ''.join(L)
def before_set(self, parser, section, option, value):
- tmp_value = value.replace(u'$$', u'') # escaped dollar signs
- tmp_value = self._KEYCRE.sub(u'', tmp_value) # valid syntax
- if u'$' in tmp_value:
- raise ValueError(u"invalid interpolation syntax in %r at "
- u"position %d" % (value, tmp_value.find(u'%')))
+ tmp_value = value.replace('$$', '') # escaped dollar signs
+ tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax
+ if '$' in tmp_value:
+ raise ValueError("invalid interpolation syntax in %r at "
+ "position %d" % (value, tmp_value.find('%')))
return value
def _interpolate_some(self, parser, option, accum, rest, section, map,
if depth > MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rest)
while rest:
- p = rest.find(u"$")
+ p = rest.find("$")
if p < 0:
accum.append(rest)
return
rest = rest[p:]
# p is no longer used
c = rest[1:2]
- if c == u"$":
- accum.append(u"$")
+ if c == "$":
+ accum.append("$")
rest = rest[2:]
- elif c == u"{":
+ elif c == "{":
m = self._KEYCRE.match(rest)
if m is None:
raise InterpolationSyntaxError(option, section,
- u"bad interpolation variable reference %r" % rest)
- path = m.group(1).split(u':')
+ "bad interpolation variable reference %r" % rest)
+ path = m.group(1).split(':')
rest = rest[m.end():]
sect = section
opt = option
else:
raise InterpolationSyntaxError(
option, section,
- u"More than one ':' found: %r" % (rest,))
+ "More than one ':' found: %r" % (rest,))
except (KeyError, NoSectionError, NoOptionError):
raise InterpolationMissingOptionError(
- option, section, rest, u":".join(path))
- if u"$" in v:
+ option, section, rest, ":".join(path))
+ if "$" in v:
self._interpolate_some(parser, opt, accum, v, sect,
dict(parser.items(sect, raw=True)),
depth + 1)
else:
raise InterpolationSyntaxError(
option, section,
- u"'$' must be followed by '$' or '{', "
- u"found: %r" % (rest,))
+ "'$' must be followed by '$' or '{', "
+ "found: %r" % (rest,))
class LegacyInterpolation(Interpolation):
- u"""Deprecated interpolation used in old versions of ConfigParser.
+ """Deprecated interpolation used in old versions of ConfigParser.
Use BasicInterpolation or ExtendedInterpolation instead."""
- _KEYCRE = re.compile(ur"%\(([^)]*)\)s|.")
+ _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
def before_get(self, parser, section, option, value, vars):
rawval = value
depth = MAX_INTERPOLATION_DEPTH
while depth: # Loop through this until it's done
depth -= 1
- if value and u"%(" in value:
+ if value and "%(" in value:
replace = functools.partial(self._interpolation_replace,
parser=parser)
value = self._KEYCRE.sub(replace, value)
try:
value = value % vars
- except KeyError, e:
+ except KeyError as e:
raise InterpolationMissingOptionError(
option, section, rawval, e.args[0])
else:
break
- if value and u"%(" in value:
+ if value and "%(" in value:
raise InterpolationDepthError(option, section, rawval)
return value
if s is None:
return match.group()
else:
- return u"%%(%s)s" % parser.optionxform(s)
+ return "%%(%s)s" % parser.optionxform(s)
class RawConfigParser(MutableMapping):
- u"""ConfigParser that does not do interpolation."""
+ """ConfigParser that does not do interpolation."""
# Regular expressions for parsing section headers and options
- _SECT_TMPL = ur"""
+ _SECT_TMPL = r"""
\[ # [
(?P<header>[^]]+) # very permissive!
\] # ]
"""
- _OPT_TMPL = ur"""
+ _OPT_TMPL = r"""
(?P<option>.*?) # very permissive!
\s*(?P<vi>{delim})\s* # any number of space/tab,
# followed by any of the
# followed by any space/tab
(?P<value>.*)$ # everything up to eol
"""
- _OPT_NV_TMPL = ur"""
+ _OPT_NV_TMPL = r"""
(?P<option>.*?) # very permissive!
\s*(?: # any number of space/tab,
(?P<vi>{delim})\s* # optionally followed by
# Compiled regular expression for matching sections
SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE)
# Compiled regular expression for matching options with typical separators
- OPTCRE = re.compile(_OPT_TMPL.format(delim=u"=|:"), re.VERBOSE)
+ OPTCRE = re.compile(_OPT_TMPL.format(delim="=|:"), re.VERBOSE)
# Compiled regular expression for matching options with optional values
# delimited using typical separators
- OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim=u"=|:"), re.VERBOSE)
+ OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE)
# Compiled regular expression for matching leading whitespace in a line
- NONSPACECRE = re.compile(ur"\S")
+ NONSPACECRE = re.compile(r"\S")
# Possible boolean values in the configuration.
- BOOLEAN_STATES = {u'1': True, u'yes': True, u'true': True, u'on': True,
- u'0': False, u'no': False, u'false': False, u'off': False}
+ BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
+ '0': False, 'no': False, 'false': False, 'off': False}
def __init__(self, defaults=None, dict_type=_default_dict,
allow_no_value=False, **_3to2kwargs):
if 'inline_comment_prefixes' in _3to2kwargs: inline_comment_prefixes = _3to2kwargs['inline_comment_prefixes']; del _3to2kwargs['inline_comment_prefixes']
else: inline_comment_prefixes = None
if 'comment_prefixes' in _3to2kwargs: comment_prefixes = _3to2kwargs['comment_prefixes']; del _3to2kwargs['comment_prefixes']
- else: comment_prefixes = (u'#', u';')
+ else: comment_prefixes = ('#', ';')
if 'delimiters' in _3to2kwargs: delimiters = _3to2kwargs['delimiters']; del _3to2kwargs['delimiters']
- else: delimiters = (u'=', u':')
+ else: delimiters = ('=', ':')
self._dict = dict_type
self._sections = self._dict()
self._defaults = self._dict()
self._proxies = self._dict()
self._proxies[default_section] = SectionProxy(self, default_section)
if defaults:
- for key, value in defaults.items():
+ for key, value in list(defaults.items()):
self._defaults[self.optionxform(key)] = value
self._delimiters = tuple(delimiters)
- if delimiters == (u'=', u':'):
+ if delimiters == ('=', ':'):
self._optcre = self.OPTCRE_NV if allow_no_value else self.OPTCRE
else:
- d = u"|".join(re.escape(d) for d in delimiters)
+ d = "|".join(re.escape(d) for d in delimiters)
if allow_no_value:
self._optcre = re.compile(self._OPT_NV_TMPL.format(delim=d),
re.VERBOSE)
return self._defaults
def sections(self):
- u"""Return a list of section names, excluding [DEFAULT]"""
+ """Return a list of section names, excluding [DEFAULT]"""
# self._sections will never have [DEFAULT] in it
return list(self._sections.keys())
def add_section(self, section):
- u"""Create a new section in the configuration.
+ """Create a new section in the configuration.
Raise DuplicateSectionError if a section by the specified name
already exists. Raise ValueError if name is DEFAULT.
"""
if section == self.default_section:
- raise ValueError(u'Invalid section name: %r' % section)
+ raise ValueError('Invalid section name: %r' % section)
if section in self._sections:
raise DuplicateSectionError(section)
self._proxies[section] = SectionProxy(self, section)
def has_section(self, section):
- u"""Indicate whether the named section is present in the configuration.
+ """Indicate whether the named section is present in the configuration.
The DEFAULT section is not acknowledged.
"""
return section in self._sections
def options(self, section):
- u"""Return a list of option names for the given section name."""
+ """Return a list of option names for the given section name."""
try:
opts = self._sections[section].copy()
except KeyError:
return list(opts.keys())
def read(self, filenames, encoding=None):
- u"""Read and parse a filename or a list of filenames.
+ """Read and parse a filename or a list of filenames.
Files that cannot be opened are silently ignored; this is
designed so that you can specify a list of potential
Return list of successfully read files.
"""
- if isinstance(filenames, unicode):
+ if isinstance(filenames, str):
filenames = [filenames]
read_ok = []
for filename in filenames:
try:
- with open(filename, encoding=encoding) as fp:
+ with open(filename, encoding='utf8') as fp:
self._read(fp, filename)
except IOError:
continue
return read_ok
def read_file(self, f, source=None):
- u"""Like read() but the argument must be a file-like object.
+ """Like read() but the argument must be a file-like object.
The `f' argument must be iterable, returning one line at a time.
Optional second argument is the `source' specifying the name of the
try:
source = f.name
except AttributeError:
- source = u'<???>'
+ source = '<???>'
self._read(f, source)
- def read_string(self, string, source=u'<string>'):
- u"""Read configuration from a given string."""
+ def read_string(self, string, source='<string>'):
+ """Read configuration from a given string."""
sfile = io.StringIO(string)
self.read_file(sfile, source)
- def read_dict(self, dictionary, source=u'<dict>'):
- u"""Read configuration from a dictionary.
+ def read_dict(self, dictionary, source='<dict>'):
+ """Read configuration from a dictionary.
Keys are section names, values are dictionaries with keys and values
that should be present in the section. If the used dictionary type
dictionary being read.
"""
elements_added = set()
- for section, keys in dictionary.items():
- section = unicode(section)
+ for section, keys in list(dictionary.items()):
+ section = str(section) #???
try:
self.add_section(section)
except (DuplicateSectionError, ValueError):
if self._strict and section in elements_added:
raise
elements_added.add(section)
- for key, value in keys.items():
- key = self.optionxform(unicode(key))
+ for key, value in list(keys.items()):
+ key = self.optionxform(str(key))#???
if value is not None:
- value = unicode(value)
+ value = str(value) #???
if self._strict and (section, key) in elements_added:
raise DuplicateOptionError(section, key, source)
elements_added.add((section, key))
self.set(section, key, value)
def readfp(self, fp, filename=None):
- u"""Deprecated, use read_file instead."""
+ """Deprecated, use read_file instead."""
warnings.warn(
- u"This method will be removed in future versions. "
- u"Use 'parser.read_file()' instead.",
+ "This method will be removed in future versions. "
+ "Use 'parser.read_file()' instead.",
DeprecationWarning, stacklevel=2
)
self.read_file(fp, source=filename)
else: vars = None
if 'raw' in _3to2kwargs: raw = _3to2kwargs['raw']; del _3to2kwargs['raw']
else: raw = False
- u"""Get an option value for a given section.
+ """Get an option value for a given section.
If `vars' is provided, it must be a dictionary. The option is looked up
in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
return fallback
def items(self, section=_UNSET, raw=False, vars=None):
- u"""Return a list of (name, value) tuples for each option in a section.
+ """Return a list of (name, value) tuples for each option in a section.
All % interpolations are expanded in the return values, based on the
defaults passed into the constructor, unless the optional argument
The section DEFAULT is special.
"""
if section is _UNSET:
- return super(RawConfigParser, self).items()
+ return list(super(RawConfigParser, self).items())
d = self._defaults.copy()
try:
d.update(self._sections[section])
raise NoSectionError(section)
# Update with the entry specific variables
if vars:
- for key, value in vars.items():
+ for key, value in list(vars.items()):
d[self.optionxform(key)] = value
value_getter = lambda option: self._interpolation.before_get(self,
section, option, d[option], d)
if raw:
value_getter = lambda option: d[option]
- return [(option, value_getter(option)) for option in d.keys()]
+ return [(option, value_getter(option)) for option in list(d.keys())]
def optionxform(self, optionstr):
return optionstr.lower()
def has_option(self, section, option):
- u"""Check for the existence of a given option in a given section.
+ """Check for the existence of a given option in a given section.
If the specified `section' is None or an empty string, DEFAULT is
assumed. If the specified `section' does not exist, returns False."""
if not section or section == self.default_section:
or option in self._defaults)
def set(self, section, option, value=None):
- u"""Set an option."""
+ """Set an option."""
if value:
value = self._interpolation.before_set(self, section, option,
value)
sectdict[self.optionxform(option)] = value
def write(self, fp, space_around_delimiters=True):
- u"""Write an .ini-format representation of the configuration state.
+ """Write an .ini-format representation of the configuration state.
If `space_around_delimiters' is True (the default), delimiters
between keys and values are surrounded by spaces.
"""
if space_around_delimiters:
- d = u" {0} ".format(self._delimiters[0])
+ d = " {0} ".format(self._delimiters[0])
else:
d = self._delimiters[0]
if self._defaults:
self._write_section(fp, self.default_section,
- self._defaults.items(), d)
+ list(self._defaults.items()), d)
for section in self._sections:
self._write_section(fp, section,
- self._sections[section].items(), d)
+ list(self._sections[section].items()), d)
def _write_section(self, fp, section_name, section_items, delimiter):
- u"""Write a single section to the specified `fp'."""
- fp.write(u"[{0}]\n".format(section_name))
+ """Write a single section to the specified `fp'."""
+ fp.write("[{0}]\n".format(section_name))
for key, value in section_items:
value = self._interpolation.before_write(self, section_name, key,
value)
if value is not None or not self._allow_no_value:
- value = delimiter + unicode(value).replace(u'\n', u'\n\t')
+ value = delimiter + str(value).replace('\n', '\n\t') #???
else:
- value = u""
- fp.write(u"{0}{1}\n".format(key, value))
- fp.write(u"\n")
+ value = ""
+ fp.write("{0}{1}\n".format(key, value))
+ fp.write("\n")
def remove_option(self, section, option):
- u"""Remove an option."""
+ """Remove an option."""
if not section or section == self.default_section:
sectdict = self._defaults
else:
return existed
def remove_section(self, section):
- u"""Remove a file section."""
+ """Remove a file section."""
existed = section in self._sections
if existed:
del self._sections[section]
def __delitem__(self, key):
if key == self.default_section:
- raise ValueError(u"Cannot remove the default section.")
+ raise ValueError("Cannot remove the default section.")
if not self.has_section(key):
raise KeyError(key)
self.remove_section(key)
def __iter__(self):
# XXX does it break when underlying container state changed?
- return itertools.chain((self.default_section,), self._sections.keys())
+ return itertools.chain((self.default_section,), list(self._sections.keys()))
def _read(self, fp, fpname):
- u"""Parse a sectioned configuration file.
+ """Parse a sectioned configuration file.
Each section in a configuration file contains a header, indicated by
a name in square brackets (`[]'), plus key/value options, indicated by
cursect is not None and
optname and
cursect[optname] is not None):
- cursect[optname].append(u'') # newlines added at join
+ cursect[optname].append('') # newlines added at join
else:
# empty line marks end of value
indent_level = sys.maxsize
# is it a section header?
mo = self.SECTCRE.match(value)
if mo:
- sectname = mo.group(u'header')
+ sectname = mo.group('header')
if sectname in self._sections:
if self._strict and sectname in elements_added:
raise DuplicateSectionError(sectname, fpname,
else:
mo = self._optcre.match(value)
if mo:
- optname, vi, optval = mo.group(u'option', u'vi', u'value')
+ optname, vi, optval = mo.group('option', 'vi', 'value')
if not optname:
e = self._handle_error(e, fpname, lineno, line)
optname = self.optionxform(optname.rstrip())
def _join_multiline_values(self):
defaults = self.default_section, self._defaults
all_sections = itertools.chain((defaults,),
- self._sections.items())
+ list(self._sections.items()))
for section, options in all_sections:
- for name, val in options.items():
+ for name, val in list(options.items()):
if isinstance(val, list):
- val = u'\n'.join(val).rstrip()
+ val = '\n'.join(val).rstrip()
options[name] = self._interpolation.before_read(self,
section,
name, val)
return exc
def _unify_values(self, section, vars):
- u"""Create a sequence of lookups with 'vars' taking priority over
+ """Create a sequence of lookups with 'vars' taking priority over
the 'section' which takes priority over the DEFAULTSECT.
"""
# Update with the entry specific variables
vardict = {}
if vars:
- for key, value in vars.items():
+ for key, value in list(vars.items()):
if value is not None:
- value = unicode(value)
+ value = str(value) #???
vardict[self.optionxform(key)] = value
return _ChainMap(vardict, sectiondict, self._defaults)
def _convert_to_boolean(self, value):
- u"""Return a boolean value translating from other types if necessary.
+ """Return a boolean value translating from other types if necessary.
"""
if value.lower() not in self.BOOLEAN_STATES:
- raise ValueError(u'Not a boolean: %s' % value)
+ raise ValueError('Not a boolean: %s' % value)
return self.BOOLEAN_STATES[value.lower()]
def _validate_value_types(self, **_3to2kwargs):
if 'value' in _3to2kwargs: value = _3to2kwargs['value']; del _3to2kwargs['value']
- else: value = u""
+ else: value = ""
if 'option' in _3to2kwargs: option = _3to2kwargs['option']; del _3to2kwargs['option']
- else: option = u""
+ else: option = ""
if 'section' in _3to2kwargs: section = _3to2kwargs['section']; del _3to2kwargs['section']
- else: section = u""
- u"""Raises a TypeError for non-string values.
+ else: section = ""
+ """Raises a TypeError for non-string values.
The only legal non-string value if we allow valueless
options is None, so we need to check if the value is a
for RawConfigParsers. It is invoked in every case for mapping protocol
access and in ConfigParser.set().
"""
- if not isinstance(section, basestring):
- raise TypeError(u"section names must be strings")
- if not isinstance(option, basestring):
- raise TypeError(u"option keys must be strings")
+ if not isinstance(section, str):
+ raise TypeError("section names must be strings")
+ if not isinstance(option, str):
+ raise TypeError("option keys must be strings")
if not self._allow_no_value or value:
- if not isinstance(value, basestring):
- raise TypeError(u"option values must be strings")
- return (unicode(section), unicode(option), (value if value is None
- else unicode(value)))
+ if not isinstance(value, str):
+ raise TypeError("option values must be strings")
+ return (str(section), str(option), (value if value is None
+ else str(value))) #???
class ConfigParser(RawConfigParser):
- u"""ConfigParser implementing interpolation."""
+ """ConfigParser implementing interpolation."""
_DEFAULT_INTERPOLATION = BasicInterpolation()
def set(self, section, option, value=None):
- u"""Set an option. Extends RawConfigParser.set by validating type and
+ """Set an option. Extends RawConfigParser.set by validating type and
interpolation syntax on the value."""
_, option, value = self._validate_value_types(option=option, value=value)
super(ConfigParser, self).set(section, option, value)
def add_section(self, section):
- u"""Create a new section in the configuration. Extends
+ """Create a new section in the configuration. Extends
RawConfigParser.add_section by validating if the section name is
a string."""
section, _, _ = self._validate_value_types(section=section)
class SafeConfigParser(ConfigParser):
- u"""ConfigParser alias for backwards compatibility purposes."""
+ """ConfigParser alias for backwards compatibility purposes."""
def __init__(self, *args, **kwargs):
super(SafeConfigParser, self).__init__(*args, **kwargs)
warnings.warn(
- u"The SafeConfigParser class has been renamed to ConfigParser "
- u"in Python 3.2. This alias will be removed in future versions."
- u" Use ConfigParser directly instead.",
+ "The SafeConfigParser class has been renamed to ConfigParser "
+ "in Python 3.2. This alias will be removed in future versions."
+ " Use ConfigParser directly instead.",
DeprecationWarning, stacklevel=2
)
class SectionProxy(MutableMapping):
- u"""A proxy for a single section from a parser."""
+ """A proxy for a single section from a parser."""
def __init__(self, parser, name):
- u"""Creates a view on a section of the specified `name` in `parser`."""
+ """Creates a view on a section of the specified `name` in `parser`."""
self._parser = parser
self._name = name
def __repr__(self):
- return u'<Section: {0}>'.format(self._name)
+ return '<Section: {0}>'.format(self._name)
def __getitem__(self, key):
if not self._parser.has_option(self._name, key):