mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
flake 8
This commit is contained in:
parent
ebeec6b751
commit
3be5f2a99a
3 changed files with 163 additions and 103 deletions
|
@ -19,19 +19,24 @@
|
|||
from __future__ import generators
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
from types import StringTypes
|
||||
from warnings import warn
|
||||
INTP_VER = sys.version_info[:2]
|
||||
if INTP_VER < (2, 2):
|
||||
raise RuntimeError("Python v.2.2 or later needed")
|
||||
|
||||
import os, re
|
||||
if sys.version_info > (3,):
|
||||
unicode = str
|
||||
|
||||
compiler = None
|
||||
try:
|
||||
import compiler
|
||||
except ImportError:
|
||||
# for IronPython
|
||||
pass
|
||||
from types import StringTypes
|
||||
from warnings import warn
|
||||
try:
|
||||
from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
|
||||
except ImportError:
|
||||
|
@ -103,12 +108,6 @@ except NameError:
|
|||
i += 1
|
||||
yield i, item
|
||||
|
||||
try:
|
||||
True, False
|
||||
except NameError:
|
||||
True, False = 1, 0
|
||||
|
||||
|
||||
__version__ = '4.4.0'
|
||||
|
||||
__revision__ = '$Id: configobj.py 156 2006-01-31 14:57:08Z fuzzyman $'
|
||||
|
@ -164,9 +163,11 @@ def getObj(s):
|
|||
p = compiler.parse(s)
|
||||
return p.getChildren()[1].getChildren()[0].getChildren()[1]
|
||||
|
||||
|
||||
class UnknownType(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Builder:
|
||||
|
||||
def build(self, o):
|
||||
|
@ -222,11 +223,13 @@ class Builder:
|
|||
def build_UnaryAdd(self, o):
|
||||
return self.build_Const(o.getChildren()[0])
|
||||
|
||||
|
||||
def unrepr(s):
|
||||
if not s:
|
||||
return s
|
||||
return Builder().build(getObj(s))
|
||||
|
||||
|
||||
def _splitlines(instring):
|
||||
"""Split a string on lines, without losing line endings or truncating."""
|
||||
|
||||
|
@ -242,11 +245,13 @@ class ConfigObjError(SyntaxError):
|
|||
self.message = message
|
||||
SyntaxError.__init__(self, message)
|
||||
|
||||
|
||||
class NestingError(ConfigObjError):
|
||||
"""
|
||||
This error indicates a level of nesting that doesn't match.
|
||||
"""
|
||||
|
||||
|
||||
class ParseError(ConfigObjError):
|
||||
"""
|
||||
This error indicates that a line is badly written.
|
||||
|
@ -254,19 +259,23 @@ class ParseError(ConfigObjError):
|
|||
nor a valid section marker line.
|
||||
"""
|
||||
|
||||
|
||||
class DuplicateError(ConfigObjError):
|
||||
"""
|
||||
The keyword or section specified already exists.
|
||||
"""
|
||||
|
||||
|
||||
class ConfigspecError(ConfigObjError):
|
||||
"""
|
||||
An error occurred whilst parsing a configspec.
|
||||
"""
|
||||
|
||||
|
||||
class InterpolationError(ConfigObjError):
|
||||
"""Base class for the two interpolation errors."""
|
||||
|
||||
|
||||
class InterpolationLoopError(InterpolationError):
|
||||
"""Maximum interpolation depth exceeded in string interpolation."""
|
||||
|
||||
|
@ -275,12 +284,14 @@ class InterpolationLoopError(InterpolationError):
|
|||
self,
|
||||
'interpolation loop detected in value "%s".' % option)
|
||||
|
||||
|
||||
class RepeatSectionError(ConfigObjError):
|
||||
"""
|
||||
This error indicates additional sections in a section with a
|
||||
``__many__`` (repeated) section.
|
||||
"""
|
||||
|
||||
|
||||
class MissingInterpolationOption(InterpolationError):
|
||||
"""A value specified for interpolation was missing."""
|
||||
|
||||
|
@ -289,6 +300,7 @@ class MissingInterpolationOption(InterpolationError):
|
|||
self,
|
||||
'missing option "%s" in interpolation.' % option)
|
||||
|
||||
|
||||
class UnreprError(ConfigObjError):
|
||||
"""An error parsing in unrepr mode."""
|
||||
|
||||
|
@ -320,7 +332,7 @@ class InterpolationEngine(object):
|
|||
This is similar to a depth-first-search algorithm.
|
||||
"""
|
||||
# Have we been here already?
|
||||
if backtrail.has_key((key, section.name)):
|
||||
if ((key, section.name) in backtrail):
|
||||
# Yes - infinite loop detected
|
||||
raise InterpolationLoopError(key)
|
||||
# Place a marker on our backtrail so we won't come back here again
|
||||
|
@ -442,11 +454,13 @@ class TemplateInterpolation(InterpolationEngine):
|
|||
# Anything else: ignore completely, just return it unchanged
|
||||
return None, match.group(), None
|
||||
|
||||
|
||||
interpolation_engines = {
|
||||
'configparser': ConfigParserInterpolation,
|
||||
'template': TemplateInterpolation,
|
||||
}
|
||||
|
||||
|
||||
class Section(dict):
|
||||
"""
|
||||
A dictionary-like object that represents a section in a config file.
|
||||
|
@ -512,10 +526,11 @@ class Section(dict):
|
|||
except AttributeError:
|
||||
# not yet: first time running _interpolate(), so pick the engine
|
||||
name = self.main.interpolation
|
||||
if name == True: # note that "if name:" would be incorrect here
|
||||
if name: # note that "if name:" would be incorrect here
|
||||
# backwards-compatibility: interpolation=True means use default
|
||||
name = DEFAULT_INTERPOLATION
|
||||
name = name.lower() # so that "Template", "template", etc. all work
|
||||
# so that "Template", "template", etc. all work
|
||||
name = name.lower()
|
||||
class_ = interpolation_engines.get(name, None)
|
||||
if class_ is None:
|
||||
# invalid value for self.main.interpolation
|
||||
|
@ -549,9 +564,9 @@ class Section(dict):
|
|||
creating a new sub-section.
|
||||
"""
|
||||
if not isinstance(key, StringTypes):
|
||||
raise ValueError, 'The key "%s" is not a string.' % key
|
||||
raise ValueError('The key "%s" is not a string.' % key)
|
||||
# add the comment
|
||||
if not self.comments.has_key(key):
|
||||
if key not in self.comments:
|
||||
self.comments[key] = []
|
||||
self.inline_comments[key] = ''
|
||||
# remove the entry from defaults
|
||||
|
@ -559,13 +574,13 @@ class Section(dict):
|
|||
self.defaults.remove(key)
|
||||
#
|
||||
if isinstance(value, Section):
|
||||
if not self.has_key(key):
|
||||
if key not in self:
|
||||
self.sections.append(key)
|
||||
dict.__setitem__(self, key, value)
|
||||
elif isinstance(value, dict) and not unrepr:
|
||||
# First create the new depth level,
|
||||
# then create the section
|
||||
if not self.has_key(key):
|
||||
if key not in self:
|
||||
self.sections.append(key)
|
||||
new_depth = self.depth + 1
|
||||
dict.__setitem__(
|
||||
|
@ -578,7 +593,7 @@ class Section(dict):
|
|||
indict=value,
|
||||
name=key))
|
||||
else:
|
||||
if not self.has_key(key):
|
||||
if key not in self:
|
||||
self.scalars.append(key)
|
||||
if not self.main.stringify:
|
||||
if isinstance(value, StringTypes):
|
||||
|
@ -586,10 +601,10 @@ class Section(dict):
|
|||
elif isinstance(value, (list, tuple)):
|
||||
for entry in value:
|
||||
if not isinstance(entry, StringTypes):
|
||||
raise TypeError, (
|
||||
raise TypeError(
|
||||
'Value is not a string "%s".' % entry)
|
||||
else:
|
||||
raise TypeError, 'Value is not a string "%s".' % value
|
||||
raise TypeError('Value is not a string "%s".' % value)
|
||||
dict.__setitem__(self, key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
|
@ -635,9 +650,9 @@ class Section(dict):
|
|||
"""Pops the first (key,val)"""
|
||||
sequence = (self.scalars + self.sections)
|
||||
if not sequence:
|
||||
raise KeyError, ": 'popitem(): dictionary is empty'"
|
||||
raise KeyError(": 'popitem(): dictionary is empty'")
|
||||
key = sequence[0]
|
||||
val = self[key]
|
||||
val = self[key]
|
||||
del self[key]
|
||||
return key, val
|
||||
|
||||
|
@ -692,7 +707,7 @@ class Section(dict):
|
|||
|
||||
def __repr__(self):
|
||||
return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(self[key])))
|
||||
for key in (self.scalars + self.sections)])
|
||||
for key in (self.scalars + self.sections)])
|
||||
|
||||
__str__ = __repr__
|
||||
|
||||
|
@ -742,11 +757,12 @@ class Section(dict):
|
|||
>>> c2 = ConfigObj(a)
|
||||
>>> c2.merge(c1)
|
||||
>>> c2
|
||||
{'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}
|
||||
{'section1': {'option1': 'False', 'subsection': \
|
||||
{'more_options': 'False'}}}
|
||||
"""
|
||||
for key, val in indict.items():
|
||||
if (key in self and isinstance(self[key], dict) and
|
||||
isinstance(val, dict)):
|
||||
isinstance(val, dict)):
|
||||
self[key].merge(val)
|
||||
else:
|
||||
self[key] = val
|
||||
|
@ -765,7 +781,7 @@ class Section(dict):
|
|||
elif oldkey in self.sections:
|
||||
the_list = self.sections
|
||||
else:
|
||||
raise KeyError, 'Key "%s" not found.' % oldkey
|
||||
raise KeyError('Key "%s" not found.' % oldkey)
|
||||
pos = the_list.index(oldkey)
|
||||
#
|
||||
val = self[oldkey]
|
||||
|
@ -781,7 +797,7 @@ class Section(dict):
|
|||
self.inline_comments[newkey] = inline_comment
|
||||
|
||||
def walk(self, function, raise_errors=True,
|
||||
call_on_sections=False, **keywargs):
|
||||
call_on_sections=False, **keywargs):
|
||||
"""
|
||||
Walk every member and call a function on the keyword and value.
|
||||
|
||||
|
@ -890,6 +906,7 @@ class Section(dict):
|
|||
1
|
||||
"""
|
||||
warn('use of ``decode`` is deprecated.', DeprecationWarning)
|
||||
|
||||
def decode(section, key, encoding=encoding, warn=True):
|
||||
""" """
|
||||
val = section[key]
|
||||
|
@ -916,6 +933,7 @@ class Section(dict):
|
|||
Uses the ``walk`` method.
|
||||
"""
|
||||
warn('use of ``encode`` is deprecated.', DeprecationWarning)
|
||||
|
||||
def encode(section, key, encoding=encoding):
|
||||
""" """
|
||||
val = section[key]
|
||||
|
@ -935,7 +953,7 @@ class Section(dict):
|
|||
def istrue(self, key):
|
||||
"""A deprecated version of ``as_bool``."""
|
||||
warn('use of ``istrue`` is deprecated. Use ``as_bool`` method '
|
||||
'instead.', DeprecationWarning)
|
||||
'instead.', DeprecationWarning)
|
||||
return self.as_bool(key)
|
||||
|
||||
def as_bool(self, key):
|
||||
|
@ -947,8 +965,8 @@ class Section(dict):
|
|||
If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns
|
||||
``True``.
|
||||
|
||||
If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns
|
||||
``False``.
|
||||
If the string is one of ``False``, ``Off``, ``No``, or ``0`` it
|
||||
returns ``False``.
|
||||
|
||||
``as_bool`` is not case sensitive.
|
||||
|
||||
|
@ -967,9 +985,9 @@ class Section(dict):
|
|||
0
|
||||
"""
|
||||
val = self[key]
|
||||
if val == True:
|
||||
if val is True:
|
||||
return True
|
||||
elif val == False:
|
||||
elif val is False:
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
|
@ -1038,7 +1056,7 @@ class ConfigObj(Section):
|
|||
(.*) # value (including list values and comments)
|
||||
$ # line end
|
||||
''',
|
||||
re.VERBOSE)
|
||||
re.VERBOSE)
|
||||
|
||||
_sectionmarker = re.compile(r'''^
|
||||
(\s*) # 1: indentation
|
||||
|
@ -1051,7 +1069,7 @@ class ConfigObj(Section):
|
|||
((?:\s*\])+) # 4: section marker close
|
||||
\s*(\#.*)? # 5: optional comment
|
||||
$''',
|
||||
re.VERBOSE)
|
||||
re.VERBOSE)
|
||||
|
||||
# this regexp pulls list values out as a single string
|
||||
# or single values and comments
|
||||
|
@ -1081,7 +1099,7 @@ class ConfigObj(Section):
|
|||
)
|
||||
\s*(\#.*)? # optional comment
|
||||
$''',
|
||||
re.VERBOSE)
|
||||
re.VERBOSE)
|
||||
|
||||
# use findall to get the members of a list value
|
||||
_listvalueexp = re.compile(r'''
|
||||
|
@ -1092,7 +1110,7 @@ class ConfigObj(Section):
|
|||
)
|
||||
\s*,\s* # comma
|
||||
''',
|
||||
re.VERBOSE)
|
||||
re.VERBOSE)
|
||||
|
||||
# this regexp is used for the value
|
||||
# when lists are switched off
|
||||
|
@ -1105,7 +1123,7 @@ class ConfigObj(Section):
|
|||
)
|
||||
\s*(\#.*)? # optional comment
|
||||
$''',
|
||||
re.VERBOSE)
|
||||
re.VERBOSE)
|
||||
|
||||
# regexes for finding triple quoted values on one line
|
||||
_single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")
|
||||
|
@ -1146,7 +1164,7 @@ class ConfigObj(Section):
|
|||
defaults = OPTION_DEFAULTS.copy()
|
||||
for entry in options.keys():
|
||||
if entry not in defaults.keys():
|
||||
raise TypeError, 'Unrecognised option "%s".' % entry
|
||||
raise TypeError('Unrecognised option "%s".' % entry)
|
||||
# TODO: check the values too.
|
||||
#
|
||||
# Add any explicit options to the defaults
|
||||
|
@ -1180,7 +1198,7 @@ class ConfigObj(Section):
|
|||
infile = open(infile).read() or []
|
||||
elif self.file_error:
|
||||
# raise an error if the file doesn't exist
|
||||
raise IOError, 'Config file not found: "%s".' % self.filename
|
||||
raise IOError('Config file not found: "%s".' % self.filename)
|
||||
else:
|
||||
# file doesn't already exist
|
||||
if self.create_empty:
|
||||
|
@ -1212,8 +1230,8 @@ class ConfigObj(Section):
|
|||
# needs splitting into lines - but needs doing *after* decoding
|
||||
# in case it's not an 8 bit encoding
|
||||
else:
|
||||
raise TypeError, ('infile must be a filename,'
|
||||
' file like object, or list of lines.')
|
||||
raise TypeError('infile must be a filename,'
|
||||
' file like object, or list of lines.')
|
||||
#
|
||||
if infile:
|
||||
# don't do it for the empty ConfigObj
|
||||
|
@ -1240,7 +1258,7 @@ class ConfigObj(Section):
|
|||
info = "at line %s." % self._errors[0].line_number
|
||||
if len(self._errors) > 1:
|
||||
msg = ("Parsing failed with several errors.\nFirst error %s" %
|
||||
info)
|
||||
info)
|
||||
error = ConfigObjError(msg)
|
||||
else:
|
||||
error = self._errors[0]
|
||||
|
@ -1261,7 +1279,7 @@ class ConfigObj(Section):
|
|||
def __repr__(self):
|
||||
return 'ConfigObj({%s})' % ', '.join(
|
||||
[('%s: %s' % (repr(key), repr(self[key]))) for key in
|
||||
(self.scalars + self.sections)])
|
||||
(self.scalars + self.sections)])
|
||||
|
||||
def _handle_bom(self, infile):
|
||||
"""
|
||||
|
@ -1286,7 +1304,7 @@ class ConfigObj(Section):
|
|||
passed in as a single string.
|
||||
"""
|
||||
if ((self.encoding is not None) and
|
||||
(self.encoding.lower() not in BOM_LIST)):
|
||||
(self.encoding.lower() not in BOM_LIST)):
|
||||
# No need to check for a BOM
|
||||
# the encoding specified doesn't have one
|
||||
# just decode
|
||||
|
@ -1309,8 +1327,8 @@ class ConfigObj(Section):
|
|||
# skip UTF8
|
||||
continue
|
||||
if infile.startswith(BOM):
|
||||
### BOM discovered
|
||||
##self.BOM = True
|
||||
# BOM discovered
|
||||
# self.BOM = True
|
||||
# Don't need to remove BOM
|
||||
return self._decode(infile, encoding)
|
||||
#
|
||||
|
@ -1383,7 +1401,8 @@ class ConfigObj(Section):
|
|||
return infile.decode(encoding).splitlines(True)
|
||||
for i, line in enumerate(infile):
|
||||
if not isinstance(line, unicode):
|
||||
# NOTE: The isinstance test here handles mixed lists of unicode/string
|
||||
# NOTE: The isinstance test here handles mixed
|
||||
# lists of unicode/string
|
||||
# NOTE: But the decode will break on any non-string values
|
||||
# NOTE: Or could raise a ``UnicodeDecodeError``
|
||||
infile[i] = line.decode(encoding)
|
||||
|
@ -1473,7 +1492,7 @@ class ConfigObj(Section):
|
|||
NestingError, infile, cur_index)
|
||||
#
|
||||
sect_name = self._unquote(sect_name)
|
||||
if parent.has_key(sect_name):
|
||||
if sect_name in parent:
|
||||
self._handle_error(
|
||||
'Duplicate section name at line %s.',
|
||||
DuplicateError, infile, cur_index)
|
||||
|
@ -1519,12 +1538,14 @@ class ConfigObj(Section):
|
|||
comment = ''
|
||||
try:
|
||||
value = unrepr(value)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
if type(e) == UnknownType:
|
||||
msg = 'Unknown name or type in value at line %s.'
|
||||
msg = 'Unknown name or type ' + \
|
||||
'in value at line %s.'
|
||||
else:
|
||||
msg = 'Parse error in value at line %s.'
|
||||
self._handle_error(msg, UnreprError, infile,
|
||||
self._handle_error(
|
||||
msg, UnreprError, infile,
|
||||
cur_index)
|
||||
continue
|
||||
else:
|
||||
|
@ -1532,12 +1553,14 @@ class ConfigObj(Section):
|
|||
comment = ''
|
||||
try:
|
||||
value = unrepr(value)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
if isinstance(e, UnknownType):
|
||||
msg = 'Unknown name or type in value at line %s.'
|
||||
msg = 'Unknown name or type ' + \
|
||||
'in value at line %s.'
|
||||
else:
|
||||
msg = 'Parse error in value at line %s.'
|
||||
self._handle_error(msg, UnreprError, infile,
|
||||
self._handle_error(
|
||||
msg, UnreprError, infile,
|
||||
cur_index)
|
||||
continue
|
||||
else:
|
||||
|
@ -1551,7 +1574,7 @@ class ConfigObj(Section):
|
|||
continue
|
||||
#
|
||||
key = self._unquote(key)
|
||||
if this_section.has_key(key):
|
||||
if key in this_section:
|
||||
self._handle_error(
|
||||
'Duplicate keyword name at line %s.',
|
||||
DuplicateError, infile, cur_index)
|
||||
|
@ -1648,12 +1671,12 @@ class ConfigObj(Section):
|
|||
elif len(value) == 1:
|
||||
return self._quote(value[0], multiline=False) + ','
|
||||
return ', '.join([self._quote(val, multiline=False)
|
||||
for val in value])
|
||||
for val in value])
|
||||
if not isinstance(value, StringTypes):
|
||||
if self.stringify:
|
||||
value = str(value)
|
||||
else:
|
||||
raise TypeError, 'Value "%s" is not a string.' % value
|
||||
raise TypeError('Value "%s" is not a string.' % value)
|
||||
squot = "'%s'"
|
||||
dquot = '"%s"'
|
||||
noquot = "%s"
|
||||
|
@ -1662,23 +1685,24 @@ class ConfigObj(Section):
|
|||
tdquot = "'''%s'''"
|
||||
if not value:
|
||||
return '""'
|
||||
if (not self.list_values and '\n' not in value) or not (multiline and
|
||||
((("'" in value) and ('"' in value)) or ('\n' in value))):
|
||||
if ((not self.list_values and '\n' not in value) or not
|
||||
(multiline and
|
||||
((("'" in value) and ('"' in value)) or ('\n' in value)))):
|
||||
if not self.list_values:
|
||||
# we don't quote if ``list_values=False``
|
||||
quot = noquot
|
||||
# for normal values either single or double quotes will do
|
||||
elif '\n' in value:
|
||||
# will only happen if multiline is off - e.g. '\n' in key
|
||||
raise ConfigObjError, ('Value "%s" cannot be safely quoted.' %
|
||||
value)
|
||||
raise ConfigObjError('Value "%s" cannot be safely quoted.' %
|
||||
value)
|
||||
elif ((value[0] not in wspace_plus) and
|
||||
(value[-1] not in wspace_plus) and
|
||||
(',' not in value)):
|
||||
quot = noquot
|
||||
else:
|
||||
if ("'" in value) and ('"' in value):
|
||||
raise ConfigObjError, (
|
||||
raise ConfigObjError(
|
||||
'Value "%s" cannot be safely quoted.' % value)
|
||||
elif '"' in value:
|
||||
quot = squot
|
||||
|
@ -1689,7 +1713,7 @@ class ConfigObj(Section):
|
|||
else:
|
||||
# if value has '\n' or "'" *and* '"', it will need triple quotes
|
||||
if (value.find('"""') != -1) and (value.find("'''") != -1):
|
||||
raise ConfigObjError, (
|
||||
raise ConfigObjError(
|
||||
'Value "%s" cannot be safely quoted.' % value)
|
||||
if value.find('"""') == -1:
|
||||
quot = tdquot
|
||||
|
@ -1787,11 +1811,11 @@ class ConfigObj(Section):
|
|||
raise_errors=True,
|
||||
file_error=True,
|
||||
list_values=False)
|
||||
except ConfigObjError, e:
|
||||
except ConfigObjError as e:
|
||||
# FIXME: Should these errors have a reference
|
||||
# to the already parsed ConfigObj ?
|
||||
raise ConfigspecError('Parsing configspec failed: %s' % e)
|
||||
except IOError, e:
|
||||
except IOError as e:
|
||||
raise IOError('Reading configspec failed: %s' % e)
|
||||
self._set_configspec_value(configspec, self)
|
||||
|
||||
|
@ -1821,7 +1845,7 @@ class ConfigObj(Section):
|
|||
section._cs_section_comments[entry] = configspec.comments[entry]
|
||||
section._cs_section_inline_comments[entry] = (
|
||||
configspec.inline_comments[entry])
|
||||
if not section.has_key(entry):
|
||||
if entry not in section:
|
||||
section[entry] = {}
|
||||
self._set_configspec_value(configspec[entry], section[entry])
|
||||
|
||||
|
@ -1832,9 +1856,9 @@ class ConfigObj(Section):
|
|||
scalar_keys = configspec.scalars
|
||||
except AttributeError:
|
||||
section_keys = [entry for entry in configspec
|
||||
if isinstance(configspec[entry], dict)]
|
||||
if isinstance(configspec[entry], dict)]
|
||||
scalar_keys = [entry for entry in configspec
|
||||
if not isinstance(configspec[entry], dict)]
|
||||
if not isinstance(configspec[entry], dict)]
|
||||
if '__many__' in section_keys and len(section_keys) > 1:
|
||||
# FIXME: can we supply any useful information here ?
|
||||
raise RepeatSectionError
|
||||
|
@ -1852,7 +1876,7 @@ class ConfigObj(Section):
|
|||
#
|
||||
section.configspec = scalars
|
||||
for entry in sections:
|
||||
if not section.has_key(entry):
|
||||
if entry not in section:
|
||||
section[entry] = {}
|
||||
self._handle_repeat(section[entry], sections[entry])
|
||||
|
||||
|
@ -1967,8 +1991,9 @@ class ConfigObj(Section):
|
|||
# NOTE: This will *screw* UTF16, each line will start with the BOM
|
||||
if self.encoding:
|
||||
out = [l.encode(self.encoding) for l in out]
|
||||
if (self.BOM and ((self.encoding is None) or
|
||||
(BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
|
||||
if (self.BOM and
|
||||
((self.encoding is None) or
|
||||
(BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
|
||||
# Add the UTF8 BOM
|
||||
if not out:
|
||||
out.append('')
|
||||
|
@ -1976,12 +2001,12 @@ class ConfigObj(Section):
|
|||
return out
|
||||
#
|
||||
# Turn the list to a string, joined with correct newlines
|
||||
output = (self._a_to_u(self.newlines or os.linesep)
|
||||
).join(out)
|
||||
output = (self._a_to_u(self.newlines or os.linesep)).join(out)
|
||||
if self.encoding:
|
||||
output = output.encode(self.encoding)
|
||||
if (self.BOM and ((self.encoding is None) or
|
||||
(BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
|
||||
if (self.BOM and
|
||||
((self.encoding is None) or
|
||||
(BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):
|
||||
# Add the UTF8 BOM
|
||||
output = BOM_UTF8 + output
|
||||
if outfile is not None:
|
||||
|
@ -1992,7 +2017,7 @@ class ConfigObj(Section):
|
|||
h.close()
|
||||
|
||||
def validate(self, validator, preserve_errors=False, copy=False,
|
||||
section=None):
|
||||
section=None):
|
||||
"""
|
||||
Test the ConfigObj against a configspec.
|
||||
|
||||
|
@ -2029,7 +2054,7 @@ class ConfigObj(Section):
|
|||
"""
|
||||
if section is None:
|
||||
if self.configspec is None:
|
||||
raise ValueError, 'No configspec supplied.'
|
||||
raise ValueError('No configspec supplied.')
|
||||
if preserve_errors:
|
||||
if VdtMissingValue is None:
|
||||
raise ImportError('Missing validate module.')
|
||||
|
@ -2058,12 +2083,12 @@ class ConfigObj(Section):
|
|||
for entry in order:
|
||||
if entry == '__many__':
|
||||
continue
|
||||
if (not entry in section.scalars) or (entry in section.defaults):
|
||||
if (entry not in section.scalars) or (entry in section.defaults):
|
||||
# missing entries
|
||||
# or entries from defaults
|
||||
missing = True
|
||||
val = None
|
||||
if copy and not entry in section.scalars:
|
||||
if copy and entry not in section.scalars:
|
||||
# copy comments
|
||||
section.comments[entry] = (
|
||||
section._configspec_comments.get(entry, []))
|
||||
|
@ -2078,7 +2103,7 @@ class ConfigObj(Section):
|
|||
val,
|
||||
missing=missing
|
||||
)
|
||||
except validator.baseErrorClass, e:
|
||||
except validator.baseErrorClass as e:
|
||||
if not preserve_errors or isinstance(e, VdtMissingValue):
|
||||
out[entry] = False
|
||||
else:
|
||||
|
@ -2117,11 +2142,11 @@ class ConfigObj(Section):
|
|||
section.inline_comments[entry] = (
|
||||
section._cs_section_inline_comments[entry])
|
||||
check = self.validate(validator, preserve_errors=preserve_errors,
|
||||
copy=copy, section=section[entry])
|
||||
copy=copy, section=section[entry])
|
||||
out[entry] = check
|
||||
if check == False:
|
||||
if check is False:
|
||||
ret_true = False
|
||||
elif check == True:
|
||||
elif check is True:
|
||||
ret_false = False
|
||||
else:
|
||||
ret_true = False
|
||||
|
@ -2134,6 +2159,7 @@ class ConfigObj(Section):
|
|||
else:
|
||||
return out
|
||||
|
||||
|
||||
class SimpleVal(object):
|
||||
"""
|
||||
A simple validator.
|
||||
|
@ -2155,6 +2181,7 @@ class SimpleVal(object):
|
|||
raise self.baseErrorClass
|
||||
return member
|
||||
|
||||
|
||||
# Check / processing functions for options
|
||||
def flatten_errors(cfg, res, levels=None, results=None):
|
||||
"""
|
||||
|
@ -2245,7 +2272,8 @@ def flatten_errors(cfg, res, levels=None, results=None):
|
|||
[root], option3 = the value "Bad_value" is of the wrong type.
|
||||
[root], section1, option2 = 0
|
||||
[root], section1, option3 = the value "Bad_value" is of the wrong type.
|
||||
[root], section2, another_option = the value "Probably" is of the wrong type.
|
||||
[root], section2, another_option = the value "Probably" is of
|
||||
the wrong type.
|
||||
[root], section3, section3b, section3b-sub, [missing] = 0
|
||||
[root], section3, section3b, value2 = the value "a" is of the wrong type.
|
||||
[root], section3, section3b, value3 = the value "11" is too big.
|
||||
|
@ -2263,7 +2291,7 @@ def flatten_errors(cfg, res, levels=None, results=None):
|
|||
levels.pop()
|
||||
return results
|
||||
for (key, val) in res.items():
|
||||
if val == True:
|
||||
if val is True:
|
||||
continue
|
||||
if isinstance(cfg.get(key), dict):
|
||||
# Go down one level
|
||||
|
@ -2278,4 +2306,5 @@ def flatten_errors(cfg, res, levels=None, results=None):
|
|||
#
|
||||
return results
|
||||
|
||||
|
||||
"""*A programming language is a medium of expression.* - Paul Graham"""
|
||||
|
|
|
@ -162,11 +162,15 @@ __all__ = (
|
|||
)
|
||||
|
||||
import sys
|
||||
import re
|
||||
INTP_VER = sys.version_info[:2]
|
||||
if INTP_VER < (2, 2):
|
||||
raise RuntimeError("Python v.2.2 or later needed")
|
||||
|
||||
import re
|
||||
if sys.version_info > (3,):
|
||||
long = int
|
||||
unicode = str
|
||||
|
||||
StringTypes = (str, unicode)
|
||||
|
||||
|
||||
|
@ -258,6 +262,7 @@ except NameError:
|
|||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def dottedQuadToNum(ip):
|
||||
"""
|
||||
Convert decimal dotted quad string to long integer
|
||||
|
@ -281,19 +286,21 @@ def dottedQuadToNum(ip):
|
|||
"""
|
||||
|
||||
# import here to avoid it when ip_addr values are not used
|
||||
import socket, struct
|
||||
import socket
|
||||
import struct
|
||||
|
||||
try:
|
||||
return struct.unpack('!L',
|
||||
socket.inet_aton(ip.strip()))[0]
|
||||
socket.inet_aton(ip.strip()))[0]
|
||||
except socket.error:
|
||||
# bug in inet_aton, corrected in Python 2.3
|
||||
if ip.strip() == '255.255.255.255':
|
||||
return 0xFFFFFFFFL
|
||||
return long('0xFFFFFFFF', 0)
|
||||
else:
|
||||
raise ValueError('Not a good dotted-quad IP: %s' % ip)
|
||||
return
|
||||
|
||||
|
||||
def numToDottedQuad(num):
|
||||
"""
|
||||
Convert long int to dotted quad string
|
||||
|
@ -317,7 +324,8 @@ def numToDottedQuad(num):
|
|||
"""
|
||||
|
||||
# import here to avoid it when ip_addr values are not used
|
||||
import socket, struct
|
||||
import socket
|
||||
import struct
|
||||
|
||||
# no need to intercept here, 4294967295L is fine
|
||||
try:
|
||||
|
@ -326,6 +334,7 @@ def numToDottedQuad(num):
|
|||
except (socket.error, struct.error, OverflowError):
|
||||
raise ValueError('Not a good numeric IP: %s' % num)
|
||||
|
||||
|
||||
class ValidateError(Exception):
|
||||
"""
|
||||
This error indicates that the check failed.
|
||||
|
@ -339,9 +348,11 @@ class ValidateError(Exception):
|
|||
ValidateError
|
||||
"""
|
||||
|
||||
|
||||
class VdtMissingValue(ValidateError):
|
||||
"""No value was supplied to a check that needed one."""
|
||||
|
||||
|
||||
class VdtUnknownCheckError(ValidateError):
|
||||
"""An unknown check function was requested"""
|
||||
|
||||
|
@ -355,6 +366,7 @@ class VdtUnknownCheckError(ValidateError):
|
|||
self,
|
||||
'the check "%s" is unknown.' % value)
|
||||
|
||||
|
||||
class VdtParamError(SyntaxError):
|
||||
"""An incorrect parameter was passed"""
|
||||
|
||||
|
@ -369,6 +381,7 @@ class VdtParamError(SyntaxError):
|
|||
'passed an incorrect value "%s" for parameter "%s".' % (
|
||||
value, name))
|
||||
|
||||
|
||||
class VdtTypeError(ValidateError):
|
||||
"""The value supplied was of the wrong type"""
|
||||
|
||||
|
@ -382,6 +395,7 @@ class VdtTypeError(ValidateError):
|
|||
self,
|
||||
'the value "%s" is of the wrong type.' % value)
|
||||
|
||||
|
||||
class VdtValueError(ValidateError):
|
||||
"""
|
||||
The value supplied was of the correct type, but was not an allowed value.
|
||||
|
@ -397,6 +411,7 @@ class VdtValueError(ValidateError):
|
|||
self,
|
||||
'the value "%s" is unacceptable.' % value)
|
||||
|
||||
|
||||
class VdtValueTooSmallError(VdtValueError):
|
||||
"""The value supplied was of the correct type, but was too small."""
|
||||
|
||||
|
@ -410,6 +425,7 @@ class VdtValueTooSmallError(VdtValueError):
|
|||
self,
|
||||
'the value "%s" is too small.' % value)
|
||||
|
||||
|
||||
class VdtValueTooBigError(VdtValueError):
|
||||
"""The value supplied was of the correct type, but was too big."""
|
||||
|
||||
|
@ -423,6 +439,7 @@ class VdtValueTooBigError(VdtValueError):
|
|||
self,
|
||||
'the value "%s" is too big.' % value)
|
||||
|
||||
|
||||
class VdtValueTooShortError(VdtValueError):
|
||||
"""The value supplied was of the correct type, but was too short."""
|
||||
|
||||
|
@ -436,6 +453,7 @@ class VdtValueTooShortError(VdtValueError):
|
|||
self,
|
||||
'the value "%s" is too short.' % (value,))
|
||||
|
||||
|
||||
class VdtValueTooLongError(VdtValueError):
|
||||
"""The value supplied was of the correct type, but was too long."""
|
||||
|
||||
|
@ -447,7 +465,8 @@ class VdtValueTooLongError(VdtValueError):
|
|||
"""
|
||||
ValidateError.__init__(
|
||||
self,
|
||||
'the value "%s" is too long.' % (value,))
|
||||
'the value "%s" is too long.' % (value,))
|
||||
|
||||
|
||||
class Validator(object):
|
||||
"""
|
||||
|
@ -527,7 +546,6 @@ class Validator(object):
|
|||
# this regex takes apart keyword arguments
|
||||
_key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$')
|
||||
|
||||
|
||||
# this regex finds keyword=list(....) type values
|
||||
_list_arg = _list_arg
|
||||
|
||||
|
@ -539,7 +557,6 @@ class Validator(object):
|
|||
_paramfinder = re.compile(_paramstring, re.VERBOSE)
|
||||
_matchfinder = re.compile(_matchstring, re.VERBOSE)
|
||||
|
||||
|
||||
def __init__(self, functions=None):
|
||||
"""
|
||||
>>> vtri = Validator()
|
||||
|
@ -634,8 +651,6 @@ class Validator(object):
|
|||
except KeyError:
|
||||
raise VdtUnknownCheckError(fun_name)
|
||||
else:
|
||||
## print fun_args
|
||||
## print fun_kwargs
|
||||
return fun(value, *fun_args, **fun_kwargs)
|
||||
|
||||
def _unquote(self, val):
|
||||
|
@ -689,7 +704,7 @@ def _is_num_param(names, values, to_float=False):
|
|||
elif isinstance(val, (int, long, float, StringTypes)):
|
||||
try:
|
||||
out_params.append(fun(val))
|
||||
except ValueError, e:
|
||||
except ValueError as e:
|
||||
raise VdtParamError(name, val)
|
||||
else:
|
||||
raise VdtParamError(name, val)
|
||||
|
@ -701,6 +716,7 @@ def _is_num_param(names, values, to_float=False):
|
|||
# note: if the params are specified wrongly in your input string,
|
||||
# you will also raise errors.
|
||||
|
||||
|
||||
def is_integer(value, min=None, max=None):
|
||||
"""
|
||||
A check that tests that a given value is an integer (int, or long)
|
||||
|
@ -757,6 +773,7 @@ def is_integer(value, min=None, max=None):
|
|||
raise VdtValueTooBigError(value)
|
||||
return value
|
||||
|
||||
|
||||
def is_float(value, min=None, max=None):
|
||||
"""
|
||||
A check that tests that a given value is a float
|
||||
|
@ -808,11 +825,13 @@ def is_float(value, min=None, max=None):
|
|||
raise VdtValueTooBigError(value)
|
||||
return value
|
||||
|
||||
|
||||
bool_dict = {
|
||||
True: True, 'on': True, '1': True, 'true': True, 'yes': True,
|
||||
False: False, 'off': False, '0': False, 'false': False, 'no': False,
|
||||
}
|
||||
|
||||
|
||||
def is_boolean(value):
|
||||
"""
|
||||
Check if the value represents a boolean.
|
||||
|
@ -865,9 +884,9 @@ def is_boolean(value):
|
|||
# we do an equality test rather than an identity test
|
||||
# this ensures Python 2.2 compatibility
|
||||
# and allows 0 and 1 to represent True and False
|
||||
if value == False:
|
||||
if value is False:
|
||||
return False
|
||||
elif value == True:
|
||||
elif value is True:
|
||||
return True
|
||||
else:
|
||||
raise VdtTypeError(value)
|
||||
|
@ -912,6 +931,7 @@ def is_ip_addr(value):
|
|||
raise VdtValueError(value)
|
||||
return value
|
||||
|
||||
|
||||
def is_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of values.
|
||||
|
@ -953,6 +973,7 @@ def is_list(value, min=None, max=None):
|
|||
raise VdtValueTooLongError(value)
|
||||
return value
|
||||
|
||||
|
||||
def is_string(value, min=None, max=None):
|
||||
"""
|
||||
Check that the supplied value is a string.
|
||||
|
@ -988,6 +1009,7 @@ def is_string(value, min=None, max=None):
|
|||
raise VdtValueTooLongError(value)
|
||||
return value
|
||||
|
||||
|
||||
def is_int_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of integers.
|
||||
|
@ -1010,6 +1032,7 @@ def is_int_list(value, min=None, max=None):
|
|||
"""
|
||||
return [is_integer(mem) for mem in is_list(value, min, max)]
|
||||
|
||||
|
||||
def is_bool_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of booleans.
|
||||
|
@ -1034,6 +1057,7 @@ def is_bool_list(value, min=None, max=None):
|
|||
"""
|
||||
return [is_boolean(mem) for mem in is_list(value, min, max)]
|
||||
|
||||
|
||||
def is_float_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of floats.
|
||||
|
@ -1056,6 +1080,7 @@ def is_float_list(value, min=None, max=None):
|
|||
"""
|
||||
return [is_float(mem) for mem in is_list(value, min, max)]
|
||||
|
||||
|
||||
def is_string_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of strings.
|
||||
|
@ -1081,6 +1106,7 @@ def is_string_list(value, min=None, max=None):
|
|||
raise VdtTypeError(value)
|
||||
return [is_string(mem) for mem in is_list(value, min, max)]
|
||||
|
||||
|
||||
def is_ip_addr_list(value, min=None, max=None):
|
||||
"""
|
||||
Check that the value is a list of IP addresses.
|
||||
|
@ -1101,6 +1127,7 @@ def is_ip_addr_list(value, min=None, max=None):
|
|||
"""
|
||||
return [is_ip_addr(mem) for mem in is_list(value, min, max)]
|
||||
|
||||
|
||||
fun_dict = {
|
||||
'integer': is_integer,
|
||||
'float': is_float,
|
||||
|
@ -1109,6 +1136,7 @@ fun_dict = {
|
|||
'boolean': is_boolean,
|
||||
}
|
||||
|
||||
|
||||
def is_mixed_list(value, *args):
|
||||
"""
|
||||
Check that the value is a list.
|
||||
|
@ -1128,7 +1156,8 @@ def is_mixed_list(value, *args):
|
|||
The length of the list must match the number of positional
|
||||
arguments you supply.
|
||||
|
||||
>>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
|
||||
>>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string',
|
||||
'boolean')"
|
||||
>>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
|
||||
>>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
|
||||
1
|
||||
|
@ -1143,7 +1172,8 @@ def is_mixed_list(value, *args):
|
|||
VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short.
|
||||
>>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b'))
|
||||
Traceback (most recent call last):
|
||||
VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long.
|
||||
VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')"
|
||||
is too long.
|
||||
>>> vtor.check(mix_str, 0)
|
||||
Traceback (most recent call last):
|
||||
VdtTypeError: the value "0" is of the wrong type.
|
||||
|
@ -1176,9 +1206,10 @@ def is_mixed_list(value, *args):
|
|||
raise VdtValueTooLongError(value)
|
||||
try:
|
||||
return [fun_dict[arg](val) for arg, val in zip(args, value)]
|
||||
except KeyError, e:
|
||||
except KeyError as e:
|
||||
raise VdtParamError('mixed_list', e)
|
||||
|
||||
|
||||
def is_option(value, *options):
|
||||
"""
|
||||
This check matches the value to any of a set of options.
|
||||
|
@ -1194,10 +1225,11 @@ def is_option(value, *options):
|
|||
"""
|
||||
if not isinstance(value, StringTypes):
|
||||
raise VdtTypeError(value)
|
||||
if not value in options:
|
||||
if value not in options:
|
||||
raise VdtValueError(value)
|
||||
return value
|
||||
|
||||
|
||||
def _test(value, *args, **keywargs):
|
||||
"""
|
||||
A function that exists for test purposes.
|
||||
|
@ -1470,4 +1502,3 @@ if __name__ == '__main__':
|
|||
|
||||
Code cleanup
|
||||
"""
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use String::ShellQuote qw/ shell_quote /;
|
|||
|
||||
# my $cmd = shell_quote( 'flake8', '.' );
|
||||
my $cmd = shell_quote( 'flake8',
|
||||
grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py') );
|
||||
grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py ./pysollib/configobj/*.py') );
|
||||
|
||||
# TEST
|
||||
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );
|
||||
|
|
Loading…
Add table
Reference in a new issue