"""Configuration file parser.A setup file consists of sections, lead by a "[section]" header,and followed by "name: value" entries, with continuations and such inthe style of RFC 822.The option values can contain format strings which refer to other values inthe same section, or values in a special [DEFAULT] section.For example:something: %(dir)s/whateverwould resolve the "%(dir)s" to the value of dir. All referenceexpansions are done late, on demand.Intrinsic defaults can be specified by passing them into theConfigParser constructor as a dictionary.class:ConfigParser -- responsible for parsing a list ofconfiguration files, and managing the parsed database.methods:__init__(defaults=None)create the parser and specify a dictionary of intrinsic defaults. Thekeys must be strings, the values must be appropriate for %()s stringinterpolation. Note that `__name__' is always an intrinsic default;its value is the section's name.sections()return all the configuration section names, sans DEFAULThas_section(section)return whether the given section existshas_option(section, option)return whether the given option exists in the given sectionoptions(section)return list of configuration options for the named sectionread(filenames)read and parse the list of named configuration files, given byname. A single filename is also allowed. Non-existing filesare ignored. Return list of successfully read files.readfp(fp, filename=None)read and parse one configuration file, given as a file object.The filename defaults to fp.name; it is only used in errormessages (if fp has no `name' attribute, the string `<???>' is used).get(section, option, raw=False, vars=None)return a string value for the named option. All % interpolations areexpanded in the return values, based on the defaults passed into theconstructor and the DEFAULT section. Additional substitutions may beprovided using the `vars' argument, which must be a dictionary whosecontents override any pre-existing defaults.getint(section, options)like get(), but convert value to an integergetfloat(section, options)like get(), but convert value to a floatgetboolean(section, options)like get(), but convert value to a boolean (currently caseinsensitively defined as 0, false, no, off for False, and 1, true,yes, on for True). Returns False or True.items(section, raw=False, vars=None)return a list of tuples with (name, value) for each optionin the section.remove_section(section)remove the given file section and all its optionsremove_option(section, option)remove the given option from the given sectionset(section, option, value)set the given optionwrite(fp)write the configuration state in .ini format"""import re__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError","InterpolationError", "InterpolationDepthError","InterpolationSyntaxError", "ParsingError","MissingSectionHeaderError","ConfigParser", "SafeConfigParser", "RawConfigParser","DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]DEFAULTSECT = "DEFAULT"MAX_INTERPOLATION_DEPTH = 10# exception classesclass Error(Exception):"""Base class for ConfigParser exceptions."""def _get_message(self):"""Getter for 'message'; needed only to override deprecation inBaseException."""return self.__messagedef _set_message(self, value):"""Setter for 'message'; needed only to override deprecation inBaseException."""self.__message = value# BaseException.message has been deprecated since Python 2.6. To prevent# DeprecationWarning from popping up over this pre-existing attribute, use# a new property that takes lookup precedence.message = property(_get_message, _set_message)def __init__(self, msg=''):self.message = msgException.__init__(self, msg)def __repr__(self):return self.message__str__ = __repr__class NoSectionError(Error):"""Raised when no section matches a requested option."""def __init__(self, section):Error.__init__(self, 'No section: %r' % (section,))self.section = sectionclass DuplicateSectionError(Error):"""Raised when a section is multiply-created."""def __init__(self, section):Error.__init__(self, "Section %r already exists" % section)self.section = sectionclass NoOptionError(Error):"""A requested option was not found."""def __init__(self, option, section):Error.__init__(self, "No option %r in section: %r" %(option, section))self.option = optionself.section = sectionclass InterpolationError(Error):"""Base class for interpolation-related exceptions."""def __init__(self, option, section, msg):Error.__init__(self, msg)self.option = optionself.section = sectionclass InterpolationMissingOptionError(InterpolationError):"""A string substitution required a setting which was not available."""def __init__(self, option, section, rawval, reference):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 = referenceclass InterpolationSyntaxError(InterpolationError):"""Raised when the source text into which substitutions are madedoes not conform to the required syntax."""class InterpolationDepthError(InterpolationError):"""Raised when substitutions are nested too deeply."""def __init__(self, option, section, rawval):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)class ParsingError(Error):"""Raised when a configuration file does not follow legal syntax."""def __init__(self, filename):Error.__init__(self, 'File contains parsing errors: %s' % filename)self.filename = filenameself.errors = []def append(self, lineno, line):self.errors.append((lineno, line))self.message += '\n\t[line %2d]: %s' % (lineno, line)class MissingSectionHeaderError(ParsingError):"""Raised when a key-value pair is found before any section header."""def __init__(self, filename, lineno, line):Error.__init__(self,'File contains no section headers.\nfile: %s, line: %d\n%r' %(filename, lineno, line))self.filename = filenameself.lineno = linenoself.line = lineclass RawConfigParser:def __init__(self, defaults=None, dict_type=dict):self._dict = dict_typeself._sections = self._dict()self._defaults = self._dict()if defaults:for key, value in defaults.items():self._defaults[self.optionxform(key)] = valuedef defaults(self):return self._defaultsdef sections(self):"""Return a list of section names, excluding [DEFAULT]"""# self._sections will never have [DEFAULT] in itreturn self._sections.keys()def add_section(self, section):"""Create a new section in the configuration.Raise DuplicateSectionError if a section by the specified namealready exists. Raise ValueError if name is DEFAULT or any of it'scase-insensitive variants."""if section.lower() == "default":raise ValueError, 'Invalid section name: %s' % sectionif section in self._sections:raise DuplicateSectionError(section)self._sections[section] = self._dict()def has_section(self, section):"""Indicate whether the named section is present in the configuration.The DEFAULT section is not acknowledged."""return section in self._sectionsdef options(self, section):"""Return a list of option names for the given section name."""try:opts = self._sections[section].copy()except KeyError:raise NoSectionError(section)opts.update(self._defaults)if '__name__' in opts:del opts['__name__']return opts.keys()def read(self, filenames):"""Read and parse a filename or a list of filenames.Files that cannot be opened are silently ignored; this isdesigned so that you can specify a list of potentialconfiguration file locations (e.g. current directory, user'shome directory, systemwide directory), and all existingconfiguration files in the list will be read. A singlefilename may also be given.Return list of successfully read files."""if isinstance(filenames, basestring):filenames = [filenames]read_ok = []for filename in filenames:try:fp = open(filename)except IOError:continueself._read(fp, filename)fp.close()read_ok.append(filename)return read_okdef readfp(self, fp, filename=None):"""Like read() but the argument must be a file-like object.The `fp' argument must have a `readline' method. Optionalsecond argument is the `filename', which if not given, istaken from fp.name. If fp has no `name' attribute, `<???>' isused."""if filename is None:try:filename = fp.nameexcept AttributeError:filename = '<???>'self._read(fp, filename)def get(self, section, option):opt = self.optionxform(option)if section not in self._sections:if section != DEFAULTSECT:raise NoSectionError(section)if opt in self._defaults:return self._defaults[opt]else:raise NoOptionError(option, section)elif opt in self._sections[section]:return self._sections[section][opt]elif opt in self._defaults:return self._defaults[opt]else:raise NoOptionError(option, section)def items(self, section):try:d2 = self._sections[section]except KeyError:if section != DEFAULTSECT:raise NoSectionError(section)d2 = self._dict()d = self._defaults.copy()d.update(d2)if "__name__" in d:del d["__name__"]return d.items()def _get(self, section, conv, option):return conv(self.get(section, option))def getint(self, section, option):return self._get(section, int, option)def getfloat(self, section, option):return self._get(section, float, option)_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,'0': False, 'no': False, 'false': False, 'off': False}def getboolean(self, section, option):v = self.get(section, option)if v.lower() not in self._boolean_states:raise ValueError, 'Not a boolean: %s' % vreturn self._boolean_states[v.lower()]def optionxform(self, optionstr):return optionstr.lower()def has_option(self, section, option):"""Check for the existence of a given option in a given section."""if not section or section == DEFAULTSECT:option = self.optionxform(option)return option in self._defaultselif section not in self._sections:return Falseelse:option = self.optionxform(option)return (option in self._sections[section]or option in self._defaults)def set(self, section, option, value):"""Set an option."""if not section or section == DEFAULTSECT:sectdict = self._defaultselse:try:sectdict = self._sections[section]except KeyError:raise NoSectionError(section)sectdict[self.optionxform(option)] = valuedef write(self, fp):"""Write an .ini-format representation of the configuration state."""if self._defaults:fp.write("[%s]\n" % DEFAULTSECT)for (key, value) in self._defaults.items():fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))fp.write("\n")for section in self._sections:fp.write("[%s]\n" % section)for (key, value) in self._sections[section].items():if key != "__name__":fp.write("%s = %s\n" %(key, str(value).replace('\n', '\n\t')))fp.write("\n")def remove_option(self, section, option):"""Remove an option."""if not section or section == DEFAULTSECT:sectdict = self._defaultselse:try:sectdict = self._sections[section]except KeyError:raise NoSectionError(section)option = self.optionxform(option)existed = option in sectdictif existed:del sectdict[option]return existeddef remove_section(self, section):"""Remove a file section."""existed = section in self._sectionsif existed:del self._sections[section]return existed## Regular expressions for parsing section headers and options.#SECTCRE = re.compile(r'\[' # [r'(?P<header>[^]]+)' # very permissive!r'\]' # ])OPTCRE = re.compile(r'(?P<option>[^:=\s][^:=]*)' # very permissive!r'\s*(?P<vi>[:=])\s*' # any number of space/tab,# followed by separator# (either : or =), followed# by any # space/tabr'(?P<value>.*)$' # everything up to eol)def _read(self, fp, fpname):"""Parse a sectioned setup file.The sections in setup file contains a title line at the top,indicated by a name in square brackets (`[]'), plus key/valueoptions lines, indicated by `name: value' format lines.Continuations are represented by an embedded newline thenleading whitespace. Blank lines, lines beginning with a '#',and just about everything else are ignored."""cursect = None # None, or a dictionaryoptname = Nonelineno = 0e = None # None, or an exceptionwhile True:line = fp.readline()if not line:breaklineno = lineno + 1# comment or blank line?if line.strip() == '' or line[0] in '#;':continueif line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":# no leading whitespacecontinue# continuation line?if line[0].isspace() and cursect is not None and optname:value = line.strip()if value:cursect[optname] = "%s\n%s" % (cursect[optname], value)# a section header or option header?else:# is it a section header?mo = self.SECTCRE.match(line)if mo:sectname = mo.group('header')if sectname in self._sections:cursect = self._sections[sectname]elif sectname == DEFAULTSECT:cursect = self._defaultselse:cursect = self._dict()cursect['__name__'] = sectnameself._sections[sectname] = cursect# So sections can't start with a continuation lineoptname = None# no section header in the file?elif cursect is None:raise MissingSectionHeaderError(fpname, lineno, line)# an option line?else:mo = self.OPTCRE.match(line)if mo:optname, vi, optval = mo.group('option', 'vi', 'value')if vi in ('=', ':') and ';' in optval:# ';' is a comment delimiter only if it follows# a spacing characterpos = optval.find(';')if pos != -1 and optval[pos-1].isspace():optval = optval[:pos]optval = optval.strip()# allow empty valuesif optval == '""':optval = ''optname = self.optionxform(optname.rstrip())cursect[optname] = optvalelse:# a non-fatal parsing error occurred. set up the# exception but keep going. the exception will be# raised at the end of the file and will contain a# list of all bogus linesif not e:e = ParsingError(fpname)e.append(lineno, repr(line))# if any parsing errors occurred, raise an exceptionif e:raise eclass ConfigParser(RawConfigParser):def get(self, section, option, raw=False, vars=None):"""Get an option value for a given section.All % interpolations are expanded in the return values, based on thedefaults passed into the constructor, unless the optional argument`raw' is true. Additional substitutions may be provided using the`vars' argument, which must be a dictionary whose contents overridesany pre-existing defaults.The section DEFAULT is special."""d = self._defaults.copy()try:d.update(self._sections[section])except KeyError:if section != DEFAULTSECT:raise NoSectionError(section)# Update with the entry specific variablesif vars:for key, value in vars.items():d[self.optionxform(key)] = valueoption = self.optionxform(option)try:value = d[option]except KeyError:raise NoOptionError(option, section)if raw:return valueelse:return self._interpolate(section, option, value, d)def items(self, section, raw=False, vars=None):"""Return a list of tuples with (name, value) for each optionin the section.All % interpolations are expanded in the return values, based on thedefaults passed into the constructor, unless the optional argument`raw' is true. Additional substitutions may be provided using the`vars' argument, which must be a dictionary whose contents overridesany pre-existing defaults.The section DEFAULT is special."""d = self._defaults.copy()try:d.update(self._sections[section])except KeyError:if section != DEFAULTSECT:raise NoSectionError(section)# Update with the entry specific variablesif vars:for key, value in vars.items():d[self.optionxform(key)] = valueoptions = d.keys()if "__name__" in options:options.remove("__name__")if raw:return [(option, d[option])for option in options]else:return [(option, self._interpolate(section, option, d[option], d))for option in options]def _interpolate(self, section, option, rawval, vars):# do the string interpolationvalue = rawvaldepth = MAX_INTERPOLATION_DEPTHwhile depth: # Loop through this until it's donedepth -= 1if "%(" in value:value = self._KEYCRE.sub(self._interpolation_replace, value)try:value = value % varsexcept KeyError, e:raise InterpolationMissingOptionError(option, section, rawval, e.args[0])else:breakif "%(" in value:raise InterpolationDepthError(option, section, rawval)return value_KEYCRE = re.compile(r"%\(([^)]*)\)s|.")def _interpolation_replace(self, match):s = match.group(1)if s is None:return match.group()else:return "%%(%s)s" % self.optionxform(s)class SafeConfigParser(ConfigParser):def _interpolate(self, section, option, rawval, vars):# do the string interpolationL = []self._interpolate_some(option, L, rawval, section, vars, 1)return ''.join(L)_interpvar_re = re.compile(r"%\(([^)]+)\)s")_badpercent_re = re.compile(r"%[^%]|%$")def _interpolate_some(self, option, accum, rest, section, map, depth):if depth > MAX_INTERPOLATION_DEPTH:raise InterpolationDepthError(option, section, rest)while rest:p = rest.find("%")if p < 0:accum.append(rest)returnif p > 0:accum.append(rest[:p])rest = rest[p:]# p is no longer usedc = rest[1:2]if c == "%":accum.append("%")rest = rest[2:]elif c == "(":m = self._interpvar_re.match(rest)if m is None:raise InterpolationSyntaxError(option, section,"bad interpolation variable reference %r" % rest)var = self.optionxform(m.group(1))rest = rest[m.end():]try:v = map[var]except KeyError:raise InterpolationMissingOptionError(option, section, rest, var)if "%" in v:self._interpolate_some(option, accum, v,section, map, depth + 1)else:accum.append(v)else:raise InterpolationSyntaxError(option, section,"'%%' must be followed by '%%' or '(', found: %r" % (rest,))def set(self, section, option, value):"""Set an option. Extend ConfigParser.set: check for string values."""if not isinstance(value, basestring):raise TypeError("option values must be strings")# check for bad percent signs:# first, replace all "good" interpolationstmp_value = self._interpvar_re.sub('', value)# then, check if there's a lone percent sign leftm = self._badpercent_re.search(tmp_value)if m:raise ValueError("invalid interpolation syntax in %r at ""position %d" % (value, m.start()))ConfigParser.set(self, section, option, value)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。