Feature: Enforce PEP8 standard specified in .flake8 for toml.py
With the exception that the `loads()` function triggers: ```toml.py:107:1: C901 'loads' is too complex (87) def loads(s, _dict=dict): ``` This commit is based off PR #99.
This commit is contained in:
42
.flake8
Normal file
42
.flake8
Normal file
@@ -0,0 +1,42 @@
|
||||
[flake8]
|
||||
exclude =
|
||||
# Do not track .git dir
|
||||
.git,
|
||||
# Do not track virtualenv dir
|
||||
venv,
|
||||
# Do not track pycache dirs
|
||||
__pycache__,
|
||||
|
||||
# A nested complexity of more than 5 is a sign that we should perhaps
|
||||
# flatten out the code's cyclomatic complexity...
|
||||
max-complexity = 5
|
||||
|
||||
# All modern monitors should at least handle 120 chars in a row without wrapping
|
||||
max-line-length = 120
|
||||
|
||||
# Default errors ++: http://pep8.readthedocs.io/en/release-1.7.x/intro.html
|
||||
# (Contains E/W error codes, at least some)
|
||||
# DXYZ error codes listed here: http://pep257.readthedocs.io/en/latest/error_codes.html
|
||||
ignore =
|
||||
D204, # Not Default
|
||||
E121,
|
||||
E126,
|
||||
E133,
|
||||
E226,
|
||||
W503,
|
||||
|
||||
# Which errors to enable (display)
|
||||
#select-errors =
|
||||
E,
|
||||
F,
|
||||
W,
|
||||
C
|
||||
|
||||
# Ignore '#noqa' pragmas
|
||||
disable-noqa = True
|
||||
|
||||
# Output config:
|
||||
show-source = True
|
||||
statistics = True
|
||||
tee = True
|
||||
output-file = .flake8.log
|
||||
115
toml.py
115
toml.py
@@ -1,5 +1,7 @@
|
||||
# This software is released under the MIT license
|
||||
"""Python module which parses and emits TOML.
|
||||
|
||||
Released under the MIT license.
|
||||
"""
|
||||
import re
|
||||
import io
|
||||
import datetime
|
||||
@@ -9,11 +11,13 @@ from os import linesep
|
||||
__version__ = "0.9.2"
|
||||
__spec__ = "0.4.0"
|
||||
|
||||
|
||||
class TomlDecodeError(Exception):
|
||||
"""Base toml Exception / Error."""
|
||||
pass
|
||||
|
||||
class TomlTz(datetime.tzinfo):
|
||||
|
||||
class TomlTz(datetime.tzinfo):
|
||||
def __init__(self, toml_offset):
|
||||
if toml_offset == "Z":
|
||||
self._raw_offset = "+00:00"
|
||||
@@ -24,7 +28,7 @@ class TomlTz(datetime.tzinfo):
|
||||
self._minutes = int(self._raw_offset[4:6])
|
||||
|
||||
def tzname(self, dt):
|
||||
return "UTC"+self._raw_offset
|
||||
return "UTC" + self._raw_offset
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return self._sign * datetime.timedelta(hours=self._hours, minutes=self._minutes)
|
||||
@@ -32,9 +36,11 @@ class TomlTz(datetime.tzinfo):
|
||||
def dst(self, dt):
|
||||
return datetime.timedelta(0)
|
||||
|
||||
|
||||
class InlineTableDict(object):
|
||||
"""Sentinel subclass of dict for inline tables."""
|
||||
|
||||
|
||||
def _get_empty_inline_table(_dict):
|
||||
class DynamicInlineTableDict(_dict, InlineTableDict):
|
||||
"""Concrete sentinel subclass for inline tables.
|
||||
@@ -44,6 +50,7 @@ def _get_empty_inline_table(_dict):
|
||||
|
||||
return DynamicInlineTableDict()
|
||||
|
||||
|
||||
try:
|
||||
_range = xrange
|
||||
except NameError:
|
||||
@@ -52,6 +59,7 @@ except NameError:
|
||||
basestring = str
|
||||
unichr = chr
|
||||
|
||||
|
||||
def load(f, _dict=dict):
|
||||
"""Parses named file or files as toml and returns a dictionary
|
||||
|
||||
@@ -94,8 +102,10 @@ def load(f, _dict=dict):
|
||||
else:
|
||||
raise TypeError("You can only load a file descriptor, filename or list")
|
||||
|
||||
|
||||
_groupname_re = re.compile(r'^[A-Za-z0-9_-]+$')
|
||||
|
||||
|
||||
def loads(s, _dict=dict):
|
||||
"""Parses string as toml
|
||||
|
||||
@@ -130,7 +140,7 @@ def loads(s, _dict=dict):
|
||||
keygroup = False
|
||||
keyname = 0
|
||||
for i, item in enumerate(sl):
|
||||
if item == '\r' and sl[i+1] == '\n':
|
||||
if item == '\r' and sl[i + 1] == '\n':
|
||||
sl[i] = ' '
|
||||
continue
|
||||
if keyname:
|
||||
@@ -153,11 +163,11 @@ def loads(s, _dict=dict):
|
||||
if item == '=':
|
||||
keyname = 0
|
||||
else:
|
||||
raise TomlDecodeError("Found invalid character in key name: '"+item+"'. Try quoting the key name.")
|
||||
raise TomlDecodeError("Found invalid character in key name: '" + item + "'. Try quoting the key name.")
|
||||
if item == "'" and openstrchar != '"':
|
||||
k = 1
|
||||
try:
|
||||
while sl[i-k] == "'":
|
||||
while sl[i - k] == "'":
|
||||
k += 1
|
||||
if k == 3:
|
||||
break
|
||||
@@ -177,12 +187,12 @@ def loads(s, _dict=dict):
|
||||
k = 1
|
||||
tripquote = False
|
||||
try:
|
||||
while sl[i-k] == '"':
|
||||
while sl[i - k] == '"':
|
||||
k += 1
|
||||
if k == 3:
|
||||
tripquote = True
|
||||
break
|
||||
while sl[i-k] == '\\':
|
||||
while sl[i - k] == '\\':
|
||||
oddbackslash = not oddbackslash
|
||||
k += 1
|
||||
except IndexError:
|
||||
@@ -209,7 +219,7 @@ def loads(s, _dict=dict):
|
||||
if item == '[' and not openstring and not keygroup and \
|
||||
not arrayoftables:
|
||||
if beginline:
|
||||
if sl[i+1] == '[':
|
||||
if sl[i + 1] == '[':
|
||||
arrayoftables = True
|
||||
else:
|
||||
keygroup = True
|
||||
@@ -219,7 +229,7 @@ def loads(s, _dict=dict):
|
||||
if keygroup:
|
||||
keygroup = False
|
||||
elif arrayoftables:
|
||||
if sl[i-1] == ']':
|
||||
if sl[i - 1] == ']':
|
||||
arrayoftables = False
|
||||
else:
|
||||
openarr -= 1
|
||||
@@ -227,10 +237,10 @@ def loads(s, _dict=dict):
|
||||
if openstring or multilinestr:
|
||||
if not multilinestr:
|
||||
raise TomlDecodeError("Unbalanced quotes")
|
||||
if (sl[i-1] == "'" or sl[i-1] == '"') and sl[i-2] == sl[i-1]:
|
||||
sl[i] = sl[i-1]
|
||||
if sl[i-3] == sl[i-1]:
|
||||
sl[i-3] = ' '
|
||||
if (sl[i - 1] == "'" or sl[i - 1] == '"') and sl[i - 2] == sl[i - 1]:
|
||||
sl[i] = sl[i - 1]
|
||||
if sl[i - 3] == sl[i - 1]:
|
||||
sl[i - 3] = ' '
|
||||
elif openarr:
|
||||
sl[i] = ' '
|
||||
else:
|
||||
@@ -264,7 +274,7 @@ def loads(s, _dict=dict):
|
||||
multikey = None
|
||||
multilinestr = ""
|
||||
else:
|
||||
k = len(multilinestr) -1
|
||||
k = len(multilinestr) - 1
|
||||
while k > -1 and multilinestr[k] == '\\':
|
||||
multibackslash = not multibackslash
|
||||
k -= 1
|
||||
@@ -288,15 +298,15 @@ def loads(s, _dict=dict):
|
||||
groups[i] = groups[i].strip()
|
||||
if groups[i][0] == '"' or groups[i][0] == "'":
|
||||
groupstr = groups[i]
|
||||
j = i+1
|
||||
j = i + 1
|
||||
while not groupstr[0] == groupstr[-1]:
|
||||
j += 1
|
||||
groupstr = '.'.join(groups[i:j])
|
||||
groups[i] = groupstr[1:-1]
|
||||
groups[i+1:j] = []
|
||||
groups[i + 1:j] = []
|
||||
else:
|
||||
if not _groupname_re.match(groups[i]):
|
||||
raise TomlDecodeError("Invalid group name '"+groups[i]+"'. Try quoting it.")
|
||||
raise TomlDecodeError("Invalid group name '" + groups[i] + "'. Try quoting it.")
|
||||
i += 1
|
||||
currentlevel = retval
|
||||
for i in _range(len(groups)):
|
||||
@@ -313,7 +323,7 @@ def loads(s, _dict=dict):
|
||||
elif arrayoftables:
|
||||
currentlevel[group].append(_dict())
|
||||
else:
|
||||
raise TomlDecodeError("What? "+group+" already exists?"+str(currentlevel))
|
||||
raise TomlDecodeError("What? " + group + " already exists?" + str(currentlevel))
|
||||
except TypeError:
|
||||
if i != len(groups) - 1:
|
||||
implicitgroups.append(group)
|
||||
@@ -346,6 +356,7 @@ def loads(s, _dict=dict):
|
||||
multikey, multilinestr, multibackslash = ret
|
||||
return retval
|
||||
|
||||
|
||||
def _load_inline_object(line, currentlevel, _dict, multikey=False, multibackslash=False):
|
||||
candidate_groups = line[1:-1].split(",")
|
||||
groups = []
|
||||
@@ -370,9 +381,11 @@ def _load_inline_object(line, currentlevel, _dict, multikey=False, multibackslas
|
||||
if status is not None:
|
||||
break
|
||||
|
||||
|
||||
# Matches a TOML number, which allows underscores for readability
|
||||
_number_with_underscores = re.compile('([0-9])(_([0-9]))*')
|
||||
|
||||
|
||||
def _strictly_valid_num(n):
|
||||
n = n.strip()
|
||||
if not n:
|
||||
@@ -395,6 +408,7 @@ def _strictly_valid_num(n):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _load_line(line, currentlevel, _dict, multikey, multibackslash):
|
||||
i = 1
|
||||
pair = line.split('=', i)
|
||||
@@ -425,10 +439,10 @@ def _load_line(line, currentlevel, _dict, multikey, multibackslash):
|
||||
pair[0] = pair[0][1:-1]
|
||||
if len(pair[1]) > 2 and (pair[1][0] == '"' or pair[1][0] == "'") \
|
||||
and pair[1][1] == pair[1][0] and pair[1][2] == pair[1][0] \
|
||||
and not (len(pair[1]) > 5 and pair[1][-1] == pair[1][0] and \
|
||||
pair[1][-2] == pair[1][0] and \
|
||||
pair[1][-3] == pair[1][0]):
|
||||
k = len(pair[1]) -1
|
||||
and not (len(pair[1]) > 5 and pair[1][-1] == pair[1][0] and
|
||||
pair[1][-2] == pair[1][0] and
|
||||
pair[1][-3] == pair[1][0]):
|
||||
k = len(pair[1]) - 1
|
||||
while k > -1 and pair[1][k] == '\\':
|
||||
multibackslash = not multibackslash
|
||||
k -= 1
|
||||
@@ -450,6 +464,7 @@ def _load_line(line, currentlevel, _dict, multikey, multibackslash):
|
||||
except:
|
||||
raise TomlDecodeError("Duplicate keys!")
|
||||
|
||||
|
||||
def _load_date(val):
|
||||
microsecond = 0
|
||||
tz = None
|
||||
@@ -464,11 +479,15 @@ def _load_date(val):
|
||||
except ValueError:
|
||||
tz = None
|
||||
try:
|
||||
d = datetime.datetime(int(val[:4]), int(val[5:7]), int(val[8:10]), int(val[11:13]), int(val[14:16]), int(val[17:19]), microsecond, tz)
|
||||
d = datetime.datetime(
|
||||
int(val[:4]), int(val[5:7]),
|
||||
int(val[8:10]), int(val[11:13]),
|
||||
int(val[14:16]), int(val[17:19]), microsecond, tz)
|
||||
except ValueError:
|
||||
return None
|
||||
return d
|
||||
|
||||
|
||||
def _load_unicode_escapes(v, hexbytes, prefix):
|
||||
hexchars = ['0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
|
||||
@@ -504,10 +523,12 @@ def _load_unicode_escapes(v, hexbytes, prefix):
|
||||
v += unicode(hx[len(hxb):])
|
||||
return v
|
||||
|
||||
|
||||
# Unescape TOML string values.
|
||||
_escapes = ['0', 'b', 'f', 'n', 'r', 't', '"'] # content after the \
|
||||
_escapedchars = ['\0', '\b', '\f', '\n', '\r', '\t', '\"'] # What it should be replaced by
|
||||
_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) # Used for substitution
|
||||
_escapes = ['0', 'b', 'f', 'n', 'r', 't', '"'] # content after the \
|
||||
_escapedchars = ['\0', '\b', '\f', '\n', '\r', '\t', '\"'] # What it should be replaced by
|
||||
_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) # Used for substitution
|
||||
|
||||
|
||||
def _unescape(v):
|
||||
"""Unescape characters in a TOML string."""
|
||||
@@ -517,9 +538,9 @@ def _unescape(v):
|
||||
if backslash:
|
||||
backslash = False
|
||||
if v[i] in _escapes:
|
||||
v = v[:i-1] + _escape_to_escapedchars[v[i]] + v[i+1:]
|
||||
v = v[:i - 1] + _escape_to_escapedchars[v[i]] + v[i + 1:]
|
||||
elif v[i] == '\\':
|
||||
v = v[:i-1] + v[i:]
|
||||
v = v[:i - 1] + v[i:]
|
||||
elif v[i] == 'u' or v[i] == 'U':
|
||||
i += 1
|
||||
else:
|
||||
@@ -530,6 +551,7 @@ def _unescape(v):
|
||||
i += 1
|
||||
return v
|
||||
|
||||
|
||||
def _load_value(v, _dict, strictly_valid=True):
|
||||
if not v:
|
||||
raise TomlDecodeError("Empty value is invalid")
|
||||
@@ -618,6 +640,7 @@ def _load_value(v, _dict, strictly_valid=True):
|
||||
return (0 - v, itype)
|
||||
return (v, itype)
|
||||
|
||||
|
||||
def _load_array(a, _dict):
|
||||
atype = None
|
||||
retval = []
|
||||
@@ -657,12 +680,12 @@ def _load_array(a, _dict):
|
||||
ab = a[b].strip()
|
||||
while ab[-1] != ab[0] or (ab[0] == ab[1] == ab[2] and
|
||||
ab[-2] != ab[0] and ab[-3] != ab[0]):
|
||||
a[b] = a[b] + ',' + a[b+1]
|
||||
a[b] = a[b] + ',' + a[b + 1]
|
||||
ab = a[b].strip()
|
||||
if b < len(a) - 2:
|
||||
a = a[:b+1] + a[b+2:]
|
||||
a = a[:b + 1] + a[b + 2:]
|
||||
else:
|
||||
a = a[:b+1]
|
||||
a = a[:b + 1]
|
||||
b += 1
|
||||
else:
|
||||
al = list(a[1:-1])
|
||||
@@ -676,7 +699,7 @@ def _load_array(a, _dict):
|
||||
openarr -= 1
|
||||
elif al[i] == ',' and not openarr:
|
||||
a.append(''.join(al[j:i]))
|
||||
j = i+1
|
||||
j = i + 1
|
||||
a.append(''.join(al[j:]))
|
||||
for i in _range(len(a)):
|
||||
a[i] = a[i].strip()
|
||||
@@ -690,6 +713,7 @@ def _load_array(a, _dict):
|
||||
retval.append(nval)
|
||||
return retval
|
||||
|
||||
|
||||
def dump(o, f):
|
||||
"""Writes out dict as toml to a file
|
||||
|
||||
@@ -710,6 +734,7 @@ def dump(o, f):
|
||||
f.write(d)
|
||||
return d
|
||||
|
||||
|
||||
def dumps(o, preserve=False):
|
||||
"""Stringifies input dict as toml
|
||||
|
||||
@@ -733,14 +758,15 @@ def dumps(o, preserve=False):
|
||||
if addtoretval or (not addtoretval and not addtosections):
|
||||
if retval and retval[-2:] != "\n\n":
|
||||
retval += "\n"
|
||||
retval += "["+section+"]\n"
|
||||
retval += "[" + section + "]\n"
|
||||
if addtoretval:
|
||||
retval += addtoretval
|
||||
for s in addtosections:
|
||||
newsections[section+"."+s] = addtosections[s]
|
||||
newsections[section + "." + s] = addtosections[s]
|
||||
sections = newsections
|
||||
return retval
|
||||
|
||||
|
||||
def _dump_sections(o, sup, preserve=False):
|
||||
retstr = ""
|
||||
if sup != "" and sup[-1] != ".":
|
||||
@@ -763,8 +789,8 @@ def _dump_sections(o, sup, preserve=False):
|
||||
if arrayoftables:
|
||||
for a in o[section]:
|
||||
arraytabstr = "\n"
|
||||
arraystr += "[["+sup+qsection+"]]\n"
|
||||
s, d = _dump_sections(a, sup+qsection)
|
||||
arraystr += "[[" + sup + qsection + "]]\n"
|
||||
s, d = _dump_sections(a, sup + qsection)
|
||||
if s:
|
||||
if s[0] == "[":
|
||||
arraytabstr += s
|
||||
@@ -773,12 +799,12 @@ def _dump_sections(o, sup, preserve=False):
|
||||
while d != {}:
|
||||
newd = {}
|
||||
for dsec in d:
|
||||
s1, d1 = _dump_sections(d[dsec], sup+qsection+"."+dsec)
|
||||
s1, d1 = _dump_sections(d[dsec], sup + qsection + "." + dsec)
|
||||
if s1:
|
||||
arraytabstr += "["+sup+qsection+"."+dsec+"]\n"
|
||||
arraytabstr += "[" + sup + qsection + "." + dsec + "]\n"
|
||||
arraytabstr += s1
|
||||
for s1 in d1:
|
||||
newd[dsec+"."+s1] = d1[s1]
|
||||
newd[dsec + "." + s1] = d1[s1]
|
||||
d = newd
|
||||
arraystr += arraytabstr
|
||||
else:
|
||||
@@ -792,6 +818,7 @@ def _dump_sections(o, sup, preserve=False):
|
||||
retstr += arraystr
|
||||
return (retstr, retdict)
|
||||
|
||||
|
||||
def _dump_inline_table(section):
|
||||
"""Preserve inline table in its compact syntax instead of expanding
|
||||
into subsection.
|
||||
@@ -809,6 +836,7 @@ def _dump_inline_table(section):
|
||||
else:
|
||||
return str(_dump_value(section))
|
||||
|
||||
|
||||
def _dump_value(v):
|
||||
dump_funcs = {
|
||||
str: lambda: _dump_str(v),
|
||||
@@ -816,13 +844,14 @@ def _dump_value(v):
|
||||
list: lambda: _dump_list(v),
|
||||
bool: lambda: str(v).lower(),
|
||||
float: lambda: _dump_float(v),
|
||||
datetime.datetime: lambda: v.isoformat()[:19]+'Z',
|
||||
datetime.datetime: lambda: v.isoformat()[:19] + 'Z',
|
||||
}
|
||||
# Lookup function corresponding to v's type
|
||||
dump_fn = dump_funcs.get(type(v))
|
||||
# Evaluate function (if it exists) else return v
|
||||
return dump_fn() if dump_fn is not None else v
|
||||
|
||||
|
||||
def _dump_str(v):
|
||||
v = "%r" % v
|
||||
if v[0] == 'u':
|
||||
@@ -833,7 +862,8 @@ def _dump_str(v):
|
||||
v = v.replace("\\'", "'")
|
||||
v = v.replace('"', '\\"')
|
||||
v = v.replace("\\x", "\\u00")
|
||||
return str('"'+v+'"')
|
||||
return str('"' + v + '"')
|
||||
|
||||
|
||||
def _dump_list(v):
|
||||
t = []
|
||||
@@ -852,5 +882,6 @@ def _dump_list(v):
|
||||
retval += "]"
|
||||
return retval
|
||||
|
||||
|
||||
def _dump_float(v):
|
||||
return "{0:.16g}".format(v).replace("e+0", "e+").replace("e-0", "e-")
|
||||
|
||||
Reference in New Issue
Block a user