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