From 3be5f2a99a00d79fa68276f4b3307dca4025f4f1 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Mon, 17 Apr 2017 05:26:40 +0300 Subject: [PATCH] flake 8 --- pysollib/configobj/configobj.py | 197 ++++++++++++++++++-------------- pysollib/configobj/validate.py | 67 ++++++++--- tests/style/py-flake8.t | 2 +- 3 files changed, 163 insertions(+), 103 deletions(-) diff --git a/pysollib/configobj/configobj.py b/pysollib/configobj/configobj.py index e5bc096d..16e7da87 100644 --- a/pysollib/configobj/configobj.py +++ b/pysollib/configobj/configobj.py @@ -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""" diff --git a/pysollib/configobj/validate.py b/pysollib/configobj/validate.py index 1509c609..14369b5c 100644 --- a/pysollib/configobj/validate.py +++ b/pysollib/configobj/validate.py @@ -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 """ - diff --git a/tests/style/py-flake8.t b/tests/style/py-flake8.t index 193cacd1..72871c29 100644 --- a/tests/style/py-flake8.t +++ b/tests/style/py-flake8.t @@ -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." );