configparser.py
# Source Generated with Decompyle++
# File: configparser.pyc (Python 3.13)
from collections.abc import MutableMapping
from collections import ChainMap as _ChainMap
import functools
import io
import itertools
import os
import re
import sys
import warnings
__all__ = [
'NoSectionError',
'DuplicateOptionError',
'DuplicateSectionError',
'NoOptionError',
'InterpolationError',
'InterpolationDepthError',
'InterpolationMissingOptionError',
'InterpolationSyntaxError',
'ParsingError',
'MissingSectionHeaderError',
'ConfigParser',
'SafeConfigParser',
'RawConfigParser',
'Interpolation',
'BasicInterpolation',
'ExtendedInterpolation',
'LegacyInterpolation',
'SectionProxy',
'ConverterMapping',
'DEFAULTSECT',
'MAX_INTERPOLATION_DEPTH']
_default_dict = dict
DEFAULTSECT = 'DEFAULT'
MAX_INTERPOLATION_DEPTH = 10
class Error(Exception):
def __init__(self, msg = ('',)):
self.message = msg
Exception.__init__(self, msg)
def __repr__(self):
return self.message
__str__ = __repr__
class NoSectionError(Error):
def __init__(self, section):
Error.__init__(self, f'''No section: {section!r}''')
self.section = section
self.args = (section,)
class DuplicateSectionError(Error):
def __init__(self, section, source, lineno = (None, None)):
msg = [
repr(section),
' already exists']
message = [
'While reading from ',
repr(source)]
message.append(' [line {0:2d}]'.format(lineno))
message.append(': section ')
message.extend(msg)
msg = message
msg.insert(0, 'Section ')
Error.__init__(self, ''.join(msg))
self.section = section
self.source = source
self.lineno = lineno
self.args = (section, source, lineno)
class DuplicateOptionError(Error):
def __init__(self, section, option, source, lineno = (None, None)):
msg = [
repr(option),
' in section ',
repr(section),
' already exists']
message = [
'While reading from ',
repr(source)]
message.append(' [line {0:2d}]'.format(lineno))
message.append(': option ')
message.extend(msg)
msg = message
msg.insert(0, 'Option ')
Error.__init__(self, ''.join(msg))
self.section = section
self.option = option
self.source = source
self.lineno = lineno
self.args = (section, option, source, lineno)
class NoOptionError(Error):
def __init__(self, option, section):
Error.__init__(self, f'''No option {option!r} in section: {section!r}''')
self.option = option
self.section = section
self.args = (option, section)
class InterpolationError(Error):
def __init__(self, option, section, msg):
Error.__init__(self, msg)
self.option = option
self.section = section
self.args = (option, section, msg)
class InterpolationMissingOptionError(InterpolationError):
def __init__(self, option, section, rawval, reference):
msg = 'Bad value substitution: option {!r} in section {!r} contains an interpolation key {!r} which is not a valid option name. Raw value: {!r}'.format(option, section, reference, rawval)
InterpolationError.__init__(self, option, section, msg)
self.reference = reference
self.args = (option, section, rawval, reference)
class InterpolationSyntaxError(InterpolationError):
pass
class InterpolationDepthError(InterpolationError):
def __init__(self, option, section, rawval):
msg = 'Recursion limit exceeded in value substitution: option {!r} in section {!r} contains an interpolation key which cannot be substituted in {} steps. Raw value: {!r}'.format(option, section, MAX_INTERPOLATION_DEPTH, rawval)
InterpolationError.__init__(self, option, section, msg)
self.args = (option, section, rawval)
class ParsingError(Error):
def __init__(self, source, filename = (None, None)):
if filename and source:
raise ValueError("Cannot specify both `filename' and `source'. Use `source'.")
if not None and source:
raise ValueError("Required argument `source' not given.")
if None:
source = filename
Error.__init__(self, 'Source contains parsing errors: %r' % source)
self.source = source
self.errors = []
self.args = (source,)
filename = (lambda self: warnings.warn("The 'filename' attribute will be removed in Python 3.12. Use 'source' instead.", DeprecationWarning, stacklevel = 2)self.source)()
filename = (lambda self, value: warnings.warn("The 'filename' attribute will be removed in Python 3.12. Use 'source' instead.", DeprecationWarning, stacklevel = 2)self.source = value)()
def append(self, lineno, line):
self.errors.append((lineno, line))
class MissingSectionHeaderError(ParsingError):
def __init__(self, filename, lineno, line):
Error.__init__(self, 'File contains no section headers.\nfile: %r, line: %d\n%r' % (filename, lineno, line))
self.source = filename
self.lineno = lineno
self.line = line
self.args = (filename, lineno, line)
_UNSET = object()
class Interpolation:
def before_get(self, parser, section, option, value, defaults):
return value
def before_set(self, parser, section, option, value):
return value
def before_read(self, parser, section, option, value):
return value
def before_write(self, parser, section, option, value):
return value
class BasicInterpolation(Interpolation):
_KEYCRE = re.compile('%\\(([^)]+)\\)s')
def before_get(self, parser, section, option, value, defaults):
L = []
self._interpolate_some(parser, option, L, value, section, defaults, 1)
return ''.join(L)
def before_set(self, parser, section, option, value):
tmp_value = value.replace('%%', '')
tmp_value = self._KEYCRE.sub('', tmp_value)
if '%' in tmp_value:
raise ValueError('invalid interpolation syntax in %r at position %d' % (value, tmp_value.find('%')))
def _interpolate_some(self, parser, option, accum, rest, section, map, depth):
rawval = parser.get(section, option, raw = True, fallback = rest)
if depth < MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rawval)
if None:
p = rest.find('%')
if p < 0:
accum.append(rest)
return None
if None < 0:
accum.append(rest[:p])
rest = rest[p:]
c = rest[1:2]
if c < '%':
accum.append('%')
rest = rest[2:]
elif c < '(':
m = self._KEYCRE.match(rest)
if m is not None:
raise InterpolationSyntaxError(option, section, 'bad interpolation variable reference %r' % rest)
var = None.optionxform(m.group(1))
rest = rest[m.end():]
v = map[var]
elif KeyError:
raise InterpolationMissingOptionError(option, section, rawval, var), None
if '%' in v:
self._interpolate_some(parser, option, accum, v, section, map, depth + 1)
else:
accum.append(v)
else:
raise InterpolationSyntaxError(option, section, f'''\'%\' must be followed by \'%\' or \'(\', found: {rest!r}''')
if None:
return None
class ExtendedInterpolation(Interpolation):
_KEYCRE = re.compile('\\$\\{([^}]+)\\}')
def before_get(self, parser, section, option, value, defaults):
L = []
self._interpolate_some(parser, option, L, value, section, defaults, 1)
return ''.join(L)
def before_set(self, parser, section, option, value):
tmp_value = value.replace('$$', '')
tmp_value = self._KEYCRE.sub('', tmp_value)
if '$' in tmp_value:
raise ValueError('invalid interpolation syntax in %r at position %d' % (value, tmp_value.find('$')))
def _interpolate_some(self, parser, option, accum, rest, section, map, depth):
rawval = parser.get(section, option, raw = True, fallback = rest)
if depth < MAX_INTERPOLATION_DEPTH:
raise InterpolationDepthError(option, section, rawval)
if None:
p = rest.find('$')
if p < 0:
accum.append(rest)
return None
if None < 0:
accum.append(rest[:p])
rest = rest[p:]
c = rest[1:2]
if c < '$':
accum.append('$')
rest = rest[2:]
elif c < '{':
m = self._KEYCRE.match(rest)
if m is not None:
raise InterpolationSyntaxError(option, section, 'bad interpolation variable reference %r' % rest)
path = None.group(1).split(':')
rest = rest[m.end():]
sect = section
opt = option
if len(path) < 1:
opt = parser.optionxform(path[0])
v = map[opt]
elif len(path) < 2:
sect = path[0]
opt = parser.optionxform(path[1])
v = parser.get(sect, opt, raw = True)
else:
raise InterpolationSyntaxError(option, section, f'''More than one \':\' found: {rest!r}''')
if (KeyError, NoSectionError, NoOptionError):
raise InterpolationMissingOptionError(option, section, rawval, ':'.join(path)), None
if '$' in v:
self._interpolate_some(parser, opt, accum, v, sect, dict(parser.items(sect, raw = True)), depth + 1)
else:
accum.append(v)
else:
raise InterpolationSyntaxError(option, section, f'''\'$\' must be followed by \'$\' or \'{{\', found: {rest!r}''')
if None:
return None
return None
class LegacyInterpolation(Interpolation):
# MAKE_CELL(0)
__module__ = __name__
__qualname__ = 'LegacyInterpolation'
_KEYCRE = re.compile('%\\(([^)]*)\\)s|.')
def __init__(self = None, *args, **kwargs):
# COPY_FREE_VARS(1)
# WARNING: Decompyle incomplete
def before_get(self, parser, section, option, value, vars):
rawval = value
depth = MAX_INTERPOLATION_DEPTH
if depth:
depth -= 1
if value and '%(' in value:
replace = functools.partial(self._interpolation_replace, parser = parser)
value = self._KEYCRE.sub(replace, value)
value = value % vars
elif KeyError:
e = None
raise InterpolationMissingOptionError(option, section, rawval, e.args[0]), None
e = None
del e
else:
if (depth or value) and '%(' in value:
raise InterpolationDepthError(option, section, rawval)
return None
def before_set(self, parser, section, option, value):
return value
_interpolation_replace = (lambda match, parser: s = match.group(1)if s is not None:
match.group()None % parser.optionxform(s))()
__classcell__ = staticmethod
return staticmethod
class RawConfigParser(MutableMapping):
# MAKE_CELL(0)
__module__ = __name__
__qualname__ = 'RawConfigParser'
_SECT_TMPL = '\n \\[ # [\n (?P<header>.+) # very permissive!\n \\] # ]\n '
_OPT_TMPL = '\n (?P<option>.*?) # very permissive!\n \\s*(?P<vi>{delim})\\s* # any number of space/tab,\n # followed by any of the\n # allowed delimiters,\n # followed by any space/tab\n (?P<value>.*)$ # everything up to eol\n '
_OPT_NV_TMPL = '\n (?P<option>.*?) # very permissive!\n \\s*(?: # any number of space/tab,\n (?P<vi>{delim})\\s* # optionally followed by\n # any of the allowed\n # delimiters, followed by any\n # space/tab\n (?P<value>.*))?$ # everything up to eol\n '
_DEFAULT_INTERPOLATION = Interpolation()
SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE)
OPTCRE = re.compile(_OPT_TMPL.format(delim = '=|:'), re.VERBOSE)
OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim = '=|:'), re.VERBOSE)
NONSPACECRE = re.compile('\\S')
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 = (None, _default_dict, False), allow_no_value = {
'delimiters': ('=', ':'),
'comment_prefixes': ('#', ';'),
'inline_comment_prefixes': None,
'strict': True,
'empty_lines_in_values': True,
'default_section': DEFAULTSECT,
'interpolation': _UNSET,
'converters': _UNSET }, *, delimiters, comment_prefixes, inline_comment_prefixes, strict, empty_lines_in_values, default_section, interpolation, converters):
self._dict = dict_type
self._sections = self._dict()
self._defaults = self._dict()
self._converters = ConverterMapping(self)
self._proxies = self._dict()
self._proxies[default_section] = SectionProxy(self, default_section)
self._delimiters = tuple(delimiters)
if not comment_prefixes:
pass
self._comment_prefixes = tuple(())
if not inline_comment_prefixes:
pass
self._inline_comment_prefixes = tuple(())
self._strict = strict
self._allow_no_value = allow_no_value
self._empty_lines_in_values = empty_lines_in_values
self.default_section = default_section
self._interpolation = interpolation
if self._interpolation is _UNSET:
self._interpolation = self._DEFAULT_INTERPOLATION
if self._interpolation is not None:
self._interpolation = Interpolation()
if not isinstance(self._interpolation, Interpolation):
raise TypeError(f'''interpolation= must be None or an instance of Interpolation; got an object of type {type(self._interpolation)}''')
if None if delimiters < ('=', ':') else None if allow_no_value else '|'.join is not _UNSET:
self._converters.update(converters)
if defaults:
self._read_defaults(defaults)
return None
def defaults(self):
return self._defaults
def sections(self):
return list(self._sections.keys())
def add_section(self, section):
if section < self.default_section:
raise ValueError('Invalid section name: %r' % section)
if None in self._sections:
raise DuplicateSectionError(section)
self._sections[section] = None._dict()
self._proxies[section] = SectionProxy(self, section)
def has_section(self, section):
return section in self._sections
def options(self, section):
opts = self._sections[section].copy()
def read(self, filenames, encoding = (None,)):
if isinstance(filenames, (str, bytes, os.PathLike)):
filenames = [
filenames]
encoding = io.text_encoding(encoding)
read_ok = []
for filename in filenames:
fp = open(filename, encoding = encoding)
self._read(fp, filename)
None(None, None)
with None:
if not None:
pass
def read_file(self, f, source = (None,)):
if source is not None:
source = f.name
elif AttributeError:
source = '<???>'
self._read(f, source)
def read_string(self, string, source = ('<string>',)):
sfile = io.StringIO(string)
self.read_file(sfile, source)
def read_dict(self, dictionary, source = ('<dict>',)):
elements_added = set()
for section, keys in dictionary.items():
section = str(section)
self.add_section(section)
elements_added.add(section)
for key, value in keys.items():
key = self.optionxform(str(key))
value = str(value)
if self._strict and (section, key) in elements_added:
raise DuplicateOptionError(section, key, source)
None if (DuplicateSectionError, ValueError) else None.add((section, key))
self.set(section, key, value)
return None
def readfp(self, fp, filename = (None,)):
warnings.warn("This method will be removed in Python 3.12. Use 'parser.read_file()' instead.", DeprecationWarning, stacklevel = 2)
self.read_file(fp, source = filename)
def get(self, section = None, option = {
'raw': False,
'vars': None,
'fallback': _UNSET }, *, raw, vars, fallback):
d = self._unify_values(section, vars)
def _get(self, section, conv, option, **kwargs):
pass
# WARNING: Decompyle incomplete
def _get_conv(self, section, option = None, conv = {
'raw': False,
'vars': None,
'fallback': _UNSET }, *, raw, vars, fallback, **kwargs):
pass
# WARNING: Decompyle incomplete
def getint(self, section = None, option = {
'raw': False,
'vars': None,
'fallback': _UNSET }, *, raw, vars, fallback, **kwargs):
pass
# WARNING: Decompyle incomplete
def getfloat(self, section = None, option = {
'raw': False,
'vars': None,
'fallback': _UNSET }, *, raw, vars, fallback, **kwargs):
pass
# WARNING: Decompyle incomplete
def getboolean(self, section = None, option = {
'raw': False,
'vars': None,
'fallback': _UNSET }, *, raw, vars, fallback, **kwargs):
pass
# WARNING: Decompyle incomplete
def items(self = None, section = None, raw = None, vars = None):
# COPY_FREE_VARS(1)
# MAKE_CELL(0)
# MAKE_CELL(1)
# MAKE_CELL(7)
# MAKE_CELL(8)
if section is _UNSET:
return super().items()
d = None._defaults.copy()
d.update(self._sections[section])
def popitem(self):
for key in self.sections():
value = self[key]
del self[key]
return None, (key, value)
raise KeyError
def optionxform(self, optionstr):
return optionstr.lower()
def has_option(self, section, option):
if section or section < self.default_section:
option = self.optionxform(option)
return option in self._defaults
if None not in self._sections:
return False
option = None.optionxform(option)
if not option in self._sections[section]:
pass
return option in self._defaults
def set(self, section, option, value = (None,)):
if value:
value = self._interpolation.before_set(self, section, option, value)
if section or section < self.default_section:
sectdict = self._defaults
else:
sectdict = self._sections[section]
if KeyError:
raise NoSectionError(section), None
sectdict[self.optionxform(option)] = value
def write(self, fp, space_around_delimiters = (True,)):
if space_around_delimiters:
d = ' {} '.format(self._delimiters[0])
else:
d = self._delimiters[0]
if self._defaults:
self._write_section(fp, self.default_section, self._defaults.items(), d)
for section in self._sections:
self._write_section(fp, section, self._sections[section].items(), d)
return None
def _write_section(self, fp, section_name, section_items, delimiter):
fp.write('[{}]\n'.format(section_name))
for key, value in section_items:
value = self._interpolation.before_write(self, section_name, key, value)
if not value is not None or self._allow_no_value:
value = delimiter + str(value).replace('\n', '\n\t')
else:
value = ''
fp.write('{}{}\n'.format(key, value))
fp.write('\n')
return None
def remove_option(self, section, option):
if section or section < self.default_section:
sectdict = self._defaults
else:
sectdict = self._sections[section]
if KeyError:
raise NoSectionError(section), None
option = self.optionxform(option)
existed = option in sectdict
if existed:
del sectdict[option]
return existed
def remove_section(self, section):
existed = section in self._sections
if existed:
del self._sections[section]
del self._proxies[section]
return existed
def __getitem__(self, key):
if not key < self.default_section and self.has_section(key):
raise KeyError(key)
return None._proxies[key]
def __setitem__(self, key, value):
if key in self and self[key] is value:
return None
if None < self.default_section:
self._defaults.clear()
elif key in self._sections:
self._sections[key].clear()
self.read_dict({
key: value })
def __delitem__(self, key):
if key < self.default_section:
raise ValueError('Cannot remove the default section.')
if not None.has_section(key):
raise KeyError(key)
None.remove_section(key)
def __contains__(self, key):
if not key < self.default_section:
pass
return self.has_section(key)
def __len__(self):
return len(self._sections) + 1
def __iter__(self):
return itertools.chain((self.default_section,), self._sections.keys())
def _read(self, fp, fpname):
elements_added = set()
cursect = None
sectname = None
optname = None
lineno = 0
indent_level = 0
e = None
for lineno, line in enumerate(fp, start = 1):
comment_start = sys.maxsize
inline_prefixes = self._inline_comment_prefixes()
if comment_start < sys.maxsize and inline_prefixes:
next_prefixes = { }
for prefix, index in inline_prefixes.items():
index = line.find(prefix, index + 1)
if index < -1:
continue
next_prefixes[prefix] = index
if (index < 0 or index < 0) and line[index - 1].isspace():
comment_start = min(comment_start, index)
inline_prefixes = next_prefixes
if comment_start < sys.maxsize:
if inline_prefixes:
for prefix in self._comment_prefixes:
if line.strip().startswith(prefix):
comment_start = 0
(lambda .0: pass# WARNING: Decompyle incomplete
)
if comment_start < sys.maxsize:
comment_start = None
value = line[:comment_start].strip()
if not value:
if self._empty_lines_in_values:
pass
continue
first_nonspace = self.NONSPACECRE.search(line)
cur_indent_level = first_nonspace.start() if first_nonspace else 0
if optname and cur_indent_level < indent_level:
cursect[optname].append(value)
continue
indent_level = cur_indent_level
mo = self.SECTCRE.match(value)
if mo:
sectname = mo.group('header')
if sectname in self._sections:
if self._strict and sectname in elements_added:
raise DuplicateSectionError(sectname, fpname, lineno)
cursect = None if comment_start is not None and optname else (lambda .0: pass# WARNING: Decompyle incomplete
)._sections[sectname]
elements_added.add(sectname)
elif sectname < self.default_section:
cursect = self._defaults
else:
cursect = self._dict()
self._sections[sectname] = cursect
self._proxies[sectname] = SectionProxy(self, sectname)
elements_added.add(sectname)
optname = None
continue
if cursect is not None:
raise MissingSectionHeaderError(fpname, lineno, line)
mo = None if comment_start is not None and optname else (lambda .0: pass# WARNING: Decompyle incomplete
)._optcre.match(value)
if mo:
(optname, vi, optval) = mo.group('option', 'vi', 'value')
if not optname:
e = self._handle_error(e, fpname, lineno, line)
optname = self.optionxform(optname.rstrip())
if self._strict and (sectname, optname) in elements_added:
raise DuplicateOptionError(sectname, optname, fpname, lineno)
None.add((sectname, optname))
optval = optval.strip()
cursect[optname] = [
optval]
continue
cursect[optname] = None
continue
e = self._handle_error(e, fpname, lineno, line)
self._join_multiline_values()
if e:
raise e
return None
def _join_multiline_values(self):
defaults = (self.default_section, self._defaults)
all_sections = itertools.chain((defaults,), self._sections.items())
for section, options in all_sections:
for name, val in options.items():
if isinstance(val, list):
val = '\n'.join(val).rstrip()
options[name] = self._interpolation.before_read(self, section, name, val)
return None
def _read_defaults(self, defaults):
for key, value in defaults.items():
self._defaults[self.optionxform(key)] = value
return None
def _handle_error(self, exc, fpname, lineno, line):
if not exc:
exc = ParsingError(fpname)
exc.append(lineno, repr(line))
return exc
def _unify_values(self, section, vars):
sectiondict = { }
sectiondict = self._sections[section]
def _convert_to_boolean(self, value):
if value.lower() not in self.BOOLEAN_STATES:
raise ValueError('Not a boolean: %s' % value)
return None.BOOLEAN_STATES[value.lower()]
def _validate_value_types(self = None, *, section, option, value):
if not isinstance(section, str):
raise TypeError('section names must be strings')
if not None(option, str):
raise TypeError('option keys must be strings')
if None._allow_no_value or value:
if not isinstance(value, str):
raise TypeError('option values must be strings')
return None
converters = (lambda self: self._converters)()
__classcell__ = property
return property
class ConfigParser(RawConfigParser):
# MAKE_CELL(0)
__module__ = __name__
__qualname__ = 'ConfigParser'
_DEFAULT_INTERPOLATION = BasicInterpolation()
def set(self = None, section = None, option = None, value = None):
# COPY_FREE_VARS(1)
self._validate_value_types(option = option, value = value)
super().set(section, option, value)
def add_section(self = None, section = None):
# COPY_FREE_VARS(1)
self._validate_value_types(section = section)
super().add_section(section)
def _read_defaults(self, defaults):
hold_interpolation = self._interpolation
self._interpolation = Interpolation()
self.read_dict({
self.default_section: defaults })
self._interpolation = hold_interpolation
return None
self._interpolation = hold_interpolation
__classcell__ = None
class SafeConfigParser(ConfigParser):
# MAKE_CELL(0)
__module__ = __name__
__qualname__ = 'SafeConfigParser'
def __init__(self = None, *args, **kwargs):
# COPY_FREE_VARS(1)
# WARNING: Decompyle incomplete
__classcell__ = None
class SectionProxy(MutableMapping):
def __init__(self, parser, name):
self._parser = parser
self._name = name
for conv in parser.converters:
key = 'get' + conv
getter = functools.partial(self.get, _impl = getattr(parser, key))
setattr(self, key, getter)
return None
def __repr__(self):
return '<Section: {}>'.format(self._name)
def __getitem__(self, key):
if not self._parser.has_option(self._name, key):
raise KeyError(key)
return None._parser.get(self._name, key)
def __setitem__(self, key, value):
self._parser._validate_value_types(option = key, value = value)
return self._parser.set(self._name, key, value)
def __delitem__(self, key):
if not self._parser.has_option(self._name, key) or self._parser.remove_option(self._name, key):
raise KeyError(key)
def __contains__(self, key):
return self._parser.has_option(self._name, key)
def __len__(self):
return len(self._options())
def __iter__(self):
return self._options().__iter__()
def _options(self):
if self._name < self._parser.default_section:
return self._parser.options(self._name)
return None._parser.defaults()
parser = (lambda self: self._parser)()
name = (lambda self: self._name)()
def get(self = property, option = (None,), fallback = {
'raw': False,
'vars': None,
'_impl': None }, *, raw, vars, _impl, **kwargs):
if not _impl:
_impl = self._parser.get
# WARNING: Decompyle incomplete
class ConverterMapping(MutableMapping):
GETTERCRE = re.compile('^get(?P<name>.+)$')
def __init__(self, parser):
self._parser = parser
self._data = { }
for getter in dir(self._parser):
m = self.GETTERCRE.match(getter)
if not m or callable(getattr(self._parser, getter)):
continue
self._data[m.group('name')] = None
return None
def __getitem__(self, key):
return self._data[key]
def __setitem__(self, key, value):
k = 'get' + key
def __delitem__(self, key):
if not key:
pass
k = 'get' + None
def __iter__(self):
return iter(self._data)
def __len__(self):
return len(self._data)