From a43330872877060aaccf8df1bf4125f6bb0874e5 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Wed, 28 Jul 2021 23:42:40 -0700 Subject: [PATCH 01/54] Update acknowledgements --- docs/contributing/4.-acknowledgements.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/contributing/4.-acknowledgements.md b/docs/contributing/4.-acknowledgements.md index aac861c64..7bc89145b 100644 --- a/docs/contributing/4.-acknowledgements.md +++ b/docs/contributing/4.-acknowledgements.md @@ -230,6 +230,7 @@ Code Contributors - Bob (@bobwalker99) - Martijn Pieters (@mjpieters) - Asiel Díaz Benítez (@adbenitez) +- Almaz (@monosans) Documenters =================== From acf43fccb22b33a7a0ef9eff5cd4b50a7fe3027b Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Thu, 29 Jul 2021 23:06:18 -0700 Subject: [PATCH 02/54] Revert "Revert "Fixed #1785: module incorrectly excluded from stdlib definition."" This reverts commit 8ae8d5045bcc4b80850d22fc4191dc36552d4e5b. --- CHANGELOG.md | 5 +++++ isort/stdlibs/py27.py | 1 + isort/stdlibs/py35.py | 1 + isort/stdlibs/py36.py | 1 + isort/stdlibs/py37.py | 1 + isort/stdlibs/py38.py | 1 + isort/stdlibs/py39.py | 1 + scripts/mkstdlibs.py | 2 +- tests/integration/test_projects_using_isort.py | 4 +++- 9 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efbe83705..505a1605a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ Changelog NOTE: isort follows the [semver](https://semver.org/) versioning standard. Find out more about isort's release policy [here](https://pycqa.github.io/isort/docs/major_releases/release_policy). +### 5.10.0 TBD + +#### Potentially breaking changes: + - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. + ### 5.9.3 July 28 2021 - Improved text of skipped file message to mention gitignore feature. - Made all exceptions pickleable. diff --git a/isort/stdlibs/py27.py b/isort/stdlibs/py27.py index 87aa67f1f..a9bc99d0c 100644 --- a/isort/stdlibs/py27.py +++ b/isort/stdlibs/py27.py @@ -40,6 +40,7 @@ "UserString", "W", "__builtin__", + "_ast", "_winreg", "abc", "aepack", diff --git a/isort/stdlibs/py35.py b/isort/stdlibs/py35.py index 274d8a7d1..29ab9aeba 100644 --- a/isort/stdlibs/py35.py +++ b/isort/stdlibs/py35.py @@ -6,6 +6,7 @@ """ stdlib = { + "_ast", "_dummy_thread", "_thread", "abc", diff --git a/isort/stdlibs/py36.py b/isort/stdlibs/py36.py index 8ae02a150..59ebd24cb 100644 --- a/isort/stdlibs/py36.py +++ b/isort/stdlibs/py36.py @@ -6,6 +6,7 @@ """ stdlib = { + "_ast", "_dummy_thread", "_thread", "abc", diff --git a/isort/stdlibs/py37.py b/isort/stdlibs/py37.py index 0eb1dd6fa..e0ad1228a 100644 --- a/isort/stdlibs/py37.py +++ b/isort/stdlibs/py37.py @@ -6,6 +6,7 @@ """ stdlib = { + "_ast", "_dummy_thread", "_thread", "abc", diff --git a/isort/stdlibs/py38.py b/isort/stdlibs/py38.py index 9bcea9a16..3d89fd26b 100644 --- a/isort/stdlibs/py38.py +++ b/isort/stdlibs/py38.py @@ -6,6 +6,7 @@ """ stdlib = { + "_ast", "_dummy_thread", "_thread", "abc", diff --git a/isort/stdlibs/py39.py b/isort/stdlibs/py39.py index 7bcb8f2b7..4b7dd5954 100644 --- a/isort/stdlibs/py39.py +++ b/isort/stdlibs/py39.py @@ -6,6 +6,7 @@ """ stdlib = { + "_ast", "_thread", "abc", "aifc", diff --git a/scripts/mkstdlibs.py b/scripts/mkstdlibs.py index ee08ba1d0..cf5237987 100755 --- a/scripts/mkstdlibs.py +++ b/scripts/mkstdlibs.py @@ -31,7 +31,7 @@ class FakeApp: invdata = fetch_inventory(FakeApp(), "", url) # Any modules we want to enforce across Python versions stdlib can be included in set init - modules = {"posixpath", "ntpath", "sre_constants", "sre_parse", "sre_compile", "sre"} + modules = {"_ast", "posixpath", "ntpath", "sre_constants", "sre_parse", "sre_compile", "sre"} for module in invdata["py:module"]: root, *_ = module.split(".") if root not in ["__future__", "__main__"]: diff --git a/tests/integration/test_projects_using_isort.py b/tests/integration/test_projects_using_isort.py index 207f38c40..2787fb835 100644 --- a/tests/integration/test_projects_using_isort.py +++ b/tests/integration/test_projects_using_isort.py @@ -83,7 +83,7 @@ def test_websockets(tmpdir): def test_airflow(tmpdir): git_clone("https://github.com/apache/airflow.git", tmpdir) - run_isort([str(tmpdir), "--skip-glob", "*/_vendor/*"]) + run_isort([str(tmpdir), "--skip-glob", "*/_vendor/*", "--skip", "tests"]) def test_typeshed(tmpdir): @@ -97,6 +97,8 @@ def test_typeshed(tmpdir): "scripts", "--skip", f"{tmpdir}/third_party/2and3/yaml/__init__.pyi", + "--skip", + f"{tmpdir}/stdlib/ast.pyi", ) ) From e5bfb28b079d942b8d5b0ce5aa7a231a0292d14a Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Thu, 29 Jul 2021 23:47:33 -0700 Subject: [PATCH 03/54] Fix skip --- tests/integration/test_projects_using_isort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_projects_using_isort.py b/tests/integration/test_projects_using_isort.py index 2787fb835..39558863e 100644 --- a/tests/integration/test_projects_using_isort.py +++ b/tests/integration/test_projects_using_isort.py @@ -98,7 +98,7 @@ def test_typeshed(tmpdir): "--skip", f"{tmpdir}/third_party/2and3/yaml/__init__.pyi", "--skip", - f"{tmpdir}/stdlib/ast.pyi", + "ast.pyi", ) ) From 380c03b1c40415c806d2244f73793e0c9182ca26 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Sun, 1 Aug 2021 23:10:43 -0700 Subject: [PATCH 04/54] Implemented #1796: Switch to for pyproject.toml configuration loader. --- CHANGELOG.md | 1 + isort/_vendored/toml/__init__.py | 23 - isort/_vendored/toml/decoder.py | 1053 ----------------------- isort/_vendored/toml/encoder.py | 295 ------- isort/_vendored/toml/ordered.py | 13 - isort/_vendored/toml/tz.py | 21 - isort/_vendored/{toml => tomli}/LICENSE | 18 +- isort/_vendored/tomli/__init__.py | 6 + isort/_vendored/tomli/_parser.py | 650 ++++++++++++++ isort/_vendored/tomli/_re.py | 100 +++ isort/_vendored/tomli/py.typed | 1 + isort/settings.py | 6 +- poetry.lock | 255 +++--- pyproject.toml | 1 + 14 files changed, 916 insertions(+), 1527 deletions(-) delete mode 100644 isort/_vendored/toml/__init__.py delete mode 100644 isort/_vendored/toml/decoder.py delete mode 100644 isort/_vendored/toml/encoder.py delete mode 100644 isort/_vendored/toml/ordered.py delete mode 100644 isort/_vendored/toml/tz.py rename isort/_vendored/{toml => tomli}/LICENSE (74%) create mode 100644 isort/_vendored/tomli/__init__.py create mode 100644 isort/_vendored/tomli/_parser.py create mode 100644 isort/_vendored/tomli/_re.py create mode 100644 isort/_vendored/tomli/py.typed diff --git a/CHANGELOG.md b/CHANGELOG.md index 505a1605a..e3096ae0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ NOTE: isort follows the [semver](https://semver.org/) versioning standard. Find out more about isort's release policy [here](https://pycqa.github.io/isort/docs/major_releases/release_policy). ### 5.10.0 TBD + - Implemented #1796: Switch to `tomli` for pyproject.toml configuration loader. #### Potentially breaking changes: - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. diff --git a/isort/_vendored/toml/__init__.py b/isort/_vendored/toml/__init__.py deleted file mode 100644 index 8cefeffad..000000000 --- a/isort/_vendored/toml/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Python module which parses and emits TOML. - -Released under the MIT license. -""" -from . import decoder, encoder - -__version__ = "0.10.1" -_spec_ = "0.5.0" - -load = decoder.load -loads = decoder.loads -TomlDecoder = decoder.TomlDecoder -TomlDecodeError = decoder.TomlDecodeError -TomlPreserveCommentDecoder = decoder.TomlPreserveCommentDecoder - -dump = encoder.dump -dumps = encoder.dumps -TomlEncoder = encoder.TomlEncoder -TomlArraySeparatorEncoder = encoder.TomlArraySeparatorEncoder -TomlPreserveInlineDictEncoder = encoder.TomlPreserveInlineDictEncoder -TomlNumpyEncoder = encoder.TomlNumpyEncoder -TomlPreserveCommentEncoder = encoder.TomlPreserveCommentEncoder -TomlPathlibEncoder = encoder.TomlPathlibEncoder diff --git a/isort/_vendored/toml/decoder.py b/isort/_vendored/toml/decoder.py deleted file mode 100644 index b90b6933e..000000000 --- a/isort/_vendored/toml/decoder.py +++ /dev/null @@ -1,1053 +0,0 @@ -import datetime -import io -import re -import sys -from os import linesep - -from .tz import TomlTz - -if sys.version_info < (3,): - _range = xrange # noqa: F821 -else: - unicode = str - _range = range - basestring = str - unichr = chr - - -def _detect_pathlib_path(p): - if (3, 4) <= sys.version_info: - import pathlib - - if isinstance(p, pathlib.PurePath): - return True - return False - - -def _ispath(p): - if isinstance(p, (bytes, basestring)): - return True - return _detect_pathlib_path(p) - - -def _getpath(p): - if (3, 6) <= sys.version_info: - import os - - return os.fspath(p) - if _detect_pathlib_path(p): - return str(p) - return p - - -try: - FNFError = FileNotFoundError -except NameError: - FNFError = IOError - - -TIME_RE = re.compile(r"([0-9]{2}):([0-9]{2}):([0-9]{2})(\.([0-9]{3,6}))?") - - -class TomlDecodeError(ValueError): - """Base toml Exception / Error.""" - - def __init__(self, msg, doc, pos): - lineno = doc.count("\n", 0, pos) + 1 - colno = pos - doc.rfind("\n", 0, pos) - emsg = "{} (line {} column {} char {})".format(msg, lineno, colno, pos) - ValueError.__init__(self, emsg) - self.msg = msg - self.doc = doc - self.pos = pos - self.lineno = lineno - self.colno = colno - - -# Matches a TOML number, which allows underscores for readability -_number_with_underscores = re.compile("([0-9])(_([0-9]))*") - - -class CommentValue(object): - def __init__(self, val, comment, beginline, _dict): - self.val = val - separator = "\n" if beginline else " " - self.comment = separator + comment - self._dict = _dict - - def __getitem__(self, key): - return self.val[key] - - def __setitem__(self, key, value): - self.val[key] = value - - def dump(self, dump_value_func): - retstr = dump_value_func(self.val) - if isinstance(self.val, self._dict): - return self.comment + "\n" + unicode(retstr) - else: - return unicode(retstr) + self.comment - - -def _strictly_valid_num(n): - n = n.strip() - if not n: - return False - if n[0] == "_": - return False - if n[-1] == "_": - return False - if "_." in n or "._" in n: - return False - if len(n) == 1: - return True - if n[0] == "0" and n[1] not in [".", "o", "b", "x"]: - return False - if n[0] == "+" or n[0] == "-": - n = n[1:] - if len(n) > 1 and n[0] == "0" and n[1] != ".": - return False - if "__" in n: - return False - return True - - -def load(f, _dict=dict, decoder=None): - """Parses named file or files as toml and returns a dictionary - - Args: - f: Path to the file to open, array of files to read into single dict - or a file descriptor - _dict: (optional) Specifies the class of the returned toml dictionary - decoder: The decoder to use - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError -- When f is invalid type - TomlDecodeError: Error while decoding toml - IOError / FileNotFoundError -- When an array with no valid (existing) - (Python 2 / Python 3) file paths is passed - """ - - if _ispath(f): - with io.open(_getpath(f), encoding="utf-8") as ffile: - return loads(ffile.read(), _dict, decoder) - elif isinstance(f, list): - from os import path as op - from warnings import warn - - if not [path for path in f if op.exists(path)]: - error_msg = "Load expects a list to contain filenames only." - error_msg += linesep - error_msg += "The list needs to contain the path of at least one " "existing file." - raise FNFError(error_msg) - if decoder is None: - decoder = TomlDecoder(_dict) - d = decoder.get_empty_table() - for l in f: # noqa: E741 - if op.exists(l): - d.update(load(l, _dict, decoder)) - else: - warn("Non-existent filename in list with at least one valid " "filename") - return d - else: - try: - return loads(f.read(), _dict, decoder) - except AttributeError: - 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, decoder=None): - """Parses string as toml - - Args: - s: String to be parsed - _dict: (optional) Specifies the class of the returned toml dictionary - - Returns: - Parsed toml file represented as a dictionary - - Raises: - TypeError: When a non-string is passed - TomlDecodeError: Error while decoding toml - """ - - implicitgroups = [] - if decoder is None: - decoder = TomlDecoder(_dict) - retval = decoder.get_empty_table() - currentlevel = retval - if not isinstance(s, basestring): - raise TypeError("Expecting something like a string") - - if not isinstance(s, unicode): - s = s.decode("utf8") - - original = s - sl = list(s) - openarr = 0 - openstring = False - openstrchar = "" - multilinestr = False - arrayoftables = False - beginline = True - keygroup = False - dottedkey = False - keyname = 0 - key = "" - prev_key = "" - line_no = 1 - - for i, item in enumerate(sl): - if item == "\r" and sl[i + 1] == "\n": - sl[i] = " " - continue - if keyname: - key += item - if item == "\n": - raise TomlDecodeError( - "Key name found without value." " Reached end of line.", original, i - ) - if openstring: - if item == openstrchar: - oddbackslash = False - k = 1 - while i >= k and sl[i - k] == "\\": - oddbackslash = not oddbackslash - k += 1 - if not oddbackslash: - keyname = 2 - openstring = False - openstrchar = "" - continue - elif keyname == 1: - if item.isspace(): - keyname = 2 - continue - elif item == ".": - dottedkey = True - continue - elif item.isalnum() or item == "_" or item == "-": - continue - elif dottedkey and sl[i - 1] == "." and (item == '"' or item == "'"): - openstring = True - openstrchar = item - continue - elif keyname == 2: - if item.isspace(): - if dottedkey: - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != ".": - keyname = 1 - continue - if item == ".": - dottedkey = True - nextitem = sl[i + 1] - if not nextitem.isspace() and nextitem != ".": - keyname = 1 - continue - if item == "=": - keyname = 0 - prev_key = key[:-1].rstrip() - key = "" - dottedkey = False - else: - raise TomlDecodeError( - "Found invalid character in key name: '" - + item - + "'. Try quoting the key name.", - original, - i, - ) - if item == "'" and openstrchar != '"': - k = 1 - try: - while sl[i - k] == "'": - k += 1 - if k == 3: - break - except IndexError: - pass - if k == 3: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = "'" - else: - openstrchar = "" - if item == '"' and openstrchar != "'": - oddbackslash = False - k = 1 - tripquote = False - try: - while sl[i - k] == '"': - k += 1 - if k == 3: - tripquote = True - break - if k == 1 or (k == 3 and tripquote): - while sl[i - k] == "\\": - oddbackslash = not oddbackslash - k += 1 - except IndexError: - pass - if not oddbackslash: - if tripquote: - multilinestr = not multilinestr - openstring = multilinestr - else: - openstring = not openstring - if openstring: - openstrchar = '"' - else: - openstrchar = "" - if item == "#" and (not openstring and not keygroup and not arrayoftables): - j = i - comment = "" - try: - while sl[j] != "\n": - comment += s[j] - sl[j] = " " - j += 1 - except IndexError: - break - if not openarr: - decoder.preserve_comment(line_no, prev_key, comment, beginline) - if item == "[" and (not openstring and not keygroup and not arrayoftables): - if beginline: - if len(sl) > i + 1 and sl[i + 1] == "[": - arrayoftables = True - else: - keygroup = True - else: - openarr += 1 - if item == "]" and not openstring: - if keygroup: - keygroup = False - elif arrayoftables: - if sl[i - 1] == "]": - arrayoftables = False - else: - openarr -= 1 - if item == "\n": - if openstring or multilinestr: - if not multilinestr: - raise TomlDecodeError("Unbalanced quotes", original, i) - 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: - beginline = True - line_no += 1 - elif beginline and sl[i] != " " and sl[i] != "\t": - beginline = False - if not keygroup and not arrayoftables: - if sl[i] == "=": - raise TomlDecodeError("Found empty keyname. ", original, i) - keyname = 1 - key += item - if keyname: - raise TomlDecodeError( - "Key name found without value." " Reached end of file.", original, len(s) - ) - if openstring: # reached EOF and have an unterminated string - raise TomlDecodeError( - "Unterminated string found." " Reached end of file.", original, len(s) - ) - s = "".join(sl) - s = s.split("\n") - multikey = None - multilinestr = "" - multibackslash = False - pos = 0 - for idx, line in enumerate(s): - if idx > 0: - pos += len(s[idx - 1]) + 1 - - decoder.embed_comments(idx, currentlevel) - - if not multilinestr or multibackslash or "\n" not in multilinestr: - line = line.strip() - if line == "" and (not multikey or multibackslash): - continue - if multikey: - if multibackslash: - multilinestr += line - else: - multilinestr += line - multibackslash = False - closed = False - if multilinestr[0] == "[": - closed = line[-1] == "]" - elif len(line) > 2: - closed = ( - line[-1] == multilinestr[0] - and line[-2] == multilinestr[0] - and line[-3] == multilinestr[0] - ) - if closed: - try: - value, vtype = decoder.load_value(multilinestr) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - currentlevel[multikey] = value - multikey = None - multilinestr = "" - else: - k = len(multilinestr) - 1 - while k > -1 and multilinestr[k] == "\\": - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = multilinestr[:-1] - else: - multilinestr += "\n" - continue - if line[0] == "[": - arrayoftables = False - if len(line) == 1: - raise TomlDecodeError( - "Opening key group bracket on line by " "itself.", original, pos - ) - if line[1] == "[": - arrayoftables = True - line = line[2:] - splitstr = "]]" - else: - line = line[1:] - splitstr = "]" - i = 1 - quotesplits = decoder._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and splitstr in quotesplit: - break - i += quotesplit.count(splitstr) - quoted = not quoted - line = line.split(splitstr, i) - if len(line) < i + 1 or line[-1].strip() != "": - raise TomlDecodeError("Key group not on a line by itself.", original, pos) - groups = splitstr.join(line[:-1]).split(".") - i = 0 - while i < len(groups): - groups[i] = groups[i].strip() - if len(groups[i]) > 0 and (groups[i][0] == '"' or groups[i][0] == "'"): - groupstr = groups[i] - j = i + 1 - while not groupstr[0] == groupstr[-1]: - j += 1 - if j > len(groups) + 2: - raise TomlDecodeError( - "Invalid group name '" + groupstr + "' Something " + "went wrong.", - original, - pos, - ) - groupstr = ".".join(groups[i:j]).strip() - groups[i] = groupstr[1:-1] - groups[i + 1 : j] = [] - else: - if not _groupname_re.match(groups[i]): - raise TomlDecodeError( - "Invalid group name '" + groups[i] + "'. Try quoting it.", original, pos - ) - i += 1 - currentlevel = retval - for i in _range(len(groups)): - group = groups[i] - if group == "": - raise TomlDecodeError( - "Can't have a keygroup with an empty " "name", original, pos - ) - try: - currentlevel[group] - if i == len(groups) - 1: - if group in implicitgroups: - implicitgroups.remove(group) - if arrayoftables: - raise TomlDecodeError( - "An implicitly defined " "table can't be an array", - original, - pos, - ) - elif arrayoftables: - currentlevel[group].append(decoder.get_empty_table()) - else: - raise TomlDecodeError( - "What? " + group + " already exists?" + str(currentlevel), - original, - pos, - ) - except TypeError: - currentlevel = currentlevel[-1] - if group not in currentlevel: - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - except KeyError: - if i != len(groups) - 1: - implicitgroups.append(group) - currentlevel[group] = decoder.get_empty_table() - if i == len(groups) - 1 and arrayoftables: - currentlevel[group] = [decoder.get_empty_table()] - currentlevel = currentlevel[group] - if arrayoftables: - try: - currentlevel = currentlevel[-1] - except KeyError: - pass - elif line[0] == "{": - if line[-1] != "}": - raise TomlDecodeError( - "Line breaks are not allowed in inline" "objects", original, pos - ) - try: - decoder.load_inline_object(line, currentlevel, multikey, multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - elif "=" in line: - try: - ret = decoder.load_line(line, currentlevel, multikey, multibackslash) - except ValueError as err: - raise TomlDecodeError(str(err), original, pos) - if ret is not None: - multikey, multilinestr, multibackslash = ret - return retval - - -def _load_date(val): - microsecond = 0 - tz = None - try: - if len(val) > 19: - if val[19] == ".": - if val[-1].upper() == "Z": - subsecondval = val[20:-1] - tzval = "Z" - else: - subsecondvalandtz = val[20:] - if "+" in subsecondvalandtz: - splitpoint = subsecondvalandtz.index("+") - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - elif "-" in subsecondvalandtz: - splitpoint = subsecondvalandtz.index("-") - subsecondval = subsecondvalandtz[:splitpoint] - tzval = subsecondvalandtz[splitpoint:] - else: - tzval = None - subsecondval = subsecondvalandtz - if tzval is not None: - tz = TomlTz(tzval) - microsecond = int(int(subsecondval) * (10 ** (6 - len(subsecondval)))) - else: - tz = TomlTz(val[19:]) - except ValueError: - tz = None - if "-" not in val[1:]: - return None - try: - if len(val) == 10: - d = datetime.date(int(val[:4]), int(val[5:7]), int(val[8:10])) - else: - 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): - skip = False - i = len(v) - 1 - while i > -1 and v[i] == "\\": - skip = not skip - i -= 1 - for hx in hexbytes: - if skip: - skip = False - i = len(hx) - 1 - while i > -1 and hx[i] == "\\": - skip = not skip - i -= 1 - v += prefix - v += hx - continue - hxb = "" - i = 0 - hxblen = 4 - if prefix == "\\U": - hxblen = 8 - hxb = "".join(hx[i : i + hxblen]).lower() - if hxb.strip("0123456789abcdef"): - raise ValueError("Invalid escape sequence: " + hxb) - if hxb[0] == "d" and hxb[1].strip("01234567"): - raise ValueError( - "Invalid escape sequence: " + hxb + ". Only scalar unicode points are allowed." - ) - v += unichr(int(hxb, 16)) - v += unicode(hx[len(hxb) :]) - return v - - -# Unescape TOML string values. - -# content after the \ -_escapes = ["0", "b", "f", "n", "r", "t", '"'] -# What it should be replaced by -_escapedchars = ["\0", "\b", "\f", "\n", "\r", "\t", '"'] -# Used for substitution -_escape_to_escapedchars = dict(zip(_escapes, _escapedchars)) - - -def _unescape(v): - """Unescape characters in a TOML string.""" - i = 0 - backslash = False - while i < len(v): - if backslash: - backslash = False - if v[i] in _escapes: - v = v[: i - 1] + _escape_to_escapedchars[v[i]] + v[i + 1 :] - elif v[i] == "\\": - v = v[: i - 1] + v[i:] - elif v[i] == "u" or v[i] == "U": - i += 1 - else: - raise ValueError("Reserved escape sequence used") - continue - elif v[i] == "\\": - backslash = True - i += 1 - return v - - -class InlineTableDict(object): - """Sentinel subclass of dict for inline tables.""" - - -class TomlDecoder(object): - def __init__(self, _dict=dict): - self._dict = _dict - - def get_empty_table(self): - return self._dict() - - def get_empty_inline_table(self): - class DynamicInlineTableDict(self._dict, InlineTableDict): - """Concrete sentinel subclass for inline tables. - It is a subclass of _dict which is passed in dynamically at load - time - - It is also a subclass of InlineTableDict - """ - - return DynamicInlineTableDict() - - def load_inline_object(self, line, currentlevel, multikey=False, multibackslash=False): - candidate_groups = line[1:-1].split(",") - groups = [] - if len(candidate_groups) == 1 and not candidate_groups[0].strip(): - candidate_groups.pop() - while len(candidate_groups) > 0: - candidate_group = candidate_groups.pop(0) - try: - _, value = candidate_group.split("=", 1) - except ValueError: - raise ValueError("Invalid inline table encountered") - value = value.strip() - if (value[0] == value[-1] and value[0] in ('"', "'")) or ( - value[0] in "-0123456789" - or value in ("true", "false") - or (value[0] == "[" and value[-1] == "]") - or (value[0] == "{" and value[-1] == "}") - ): - groups.append(candidate_group) - elif len(candidate_groups) > 0: - candidate_groups[0] = candidate_group + "," + candidate_groups[0] - else: - raise ValueError("Invalid inline table value encountered") - for group in groups: - status = self.load_line(group, currentlevel, multikey, multibackslash) - if status is not None: - break - - def _get_split_on_quotes(self, line): - doublequotesplits = line.split('"') - quoted = False - quotesplits = [] - if len(doublequotesplits) > 1 and "'" in doublequotesplits[0]: - singlequotesplits = doublequotesplits[0].split("'") - doublequotesplits = doublequotesplits[1:] - while len(singlequotesplits) % 2 == 0 and len(doublequotesplits): - singlequotesplits[-1] += '"' + doublequotesplits[0] - doublequotesplits = doublequotesplits[1:] - if "'" in singlequotesplits[-1]: - singlequotesplits = singlequotesplits[:-1] + singlequotesplits[-1].split("'") - quotesplits += singlequotesplits - for doublequotesplit in doublequotesplits: - if quoted: - quotesplits.append(doublequotesplit) - else: - quotesplits += doublequotesplit.split("'") - quoted = not quoted - return quotesplits - - def load_line(self, line, currentlevel, multikey, multibackslash): - i = 1 - quotesplits = self._get_split_on_quotes(line) - quoted = False - for quotesplit in quotesplits: - if not quoted and "=" in quotesplit: - break - i += quotesplit.count("=") - quoted = not quoted - pair = line.split("=", i) - strictly_valid = _strictly_valid_num(pair[-1]) - if _number_with_underscores.match(pair[-1]): - pair[-1] = pair[-1].replace("_", "") - while len(pair[-1]) and ( - pair[-1][0] != " " - and pair[-1][0] != "\t" - and pair[-1][0] != "'" - and pair[-1][0] != '"' - and pair[-1][0] != "[" - and pair[-1][0] != "{" - and pair[-1].strip() != "true" - and pair[-1].strip() != "false" - ): - try: - float(pair[-1]) - break - except ValueError: - pass - if _load_date(pair[-1]) is not None: - break - if TIME_RE.match(pair[-1]): - break - i += 1 - prev_val = pair[-1] - pair = line.split("=", i) - if prev_val == pair[-1]: - raise ValueError("Invalid date or number") - if strictly_valid: - strictly_valid = _strictly_valid_num(pair[-1]) - pair = ["=".join(pair[:-1]).strip(), pair[-1].strip()] - if "." in pair[0]: - if '"' in pair[0] or "'" in pair[0]: - quotesplits = self._get_split_on_quotes(pair[0]) - quoted = False - levels = [] - for quotesplit in quotesplits: - if quoted: - levels.append(quotesplit) - else: - levels += [level.strip() for level in quotesplit.split(".")] - quoted = not quoted - else: - levels = pair[0].split(".") - while levels[-1] == "": - levels = levels[:-1] - for level in levels[:-1]: - if level == "": - continue - if level not in currentlevel: - currentlevel[level] = self.get_empty_table() - currentlevel = currentlevel[level] - pair[0] = levels[-1].strip() - elif (pair[0][0] == '"' or pair[0][0] == "'") and (pair[0][-1] == pair[0][0]): - pair[0] = _unescape(pair[0][1:-1]) - k, koffset = self._load_line_multiline_str(pair[1]) - if k > -1: - while k > -1 and pair[1][k + koffset] == "\\": - multibackslash = not multibackslash - k -= 1 - if multibackslash: - multilinestr = pair[1][:-1] - else: - multilinestr = pair[1] + "\n" - multikey = pair[0] - else: - value, vtype = self.load_value(pair[1], strictly_valid) - try: - currentlevel[pair[0]] - raise ValueError("Duplicate keys!") - except TypeError: - raise ValueError("Duplicate keys!") - except KeyError: - if multikey: - return multikey, multilinestr, multibackslash - else: - currentlevel[pair[0]] = value - - def _load_line_multiline_str(self, p): - poffset = 0 - if len(p) < 3: - return -1, poffset - if p[0] == "[" and (p.strip()[-1] != "]" and self._load_array_isstrarray(p)): - newp = p[1:].strip().split(",") - while len(newp) > 1 and newp[-1][0] != '"' and newp[-1][0] != "'": - newp = newp[:-2] + [newp[-2] + "," + newp[-1]] - newp = newp[-1] - poffset = len(p) - len(newp) - p = newp - if p[0] != '"' and p[0] != "'": - return -1, poffset - if p[1] != p[0] or p[2] != p[0]: - return -1, poffset - if len(p) > 5 and p[-1] == p[0] and p[-2] == p[0] and p[-3] == p[0]: - return -1, poffset - return len(p) - 1, poffset - - def load_value(self, v, strictly_valid=True): - if not v: - raise ValueError("Empty value is invalid") - if v == "true": - return (True, "bool") - elif v == "false": - return (False, "bool") - elif v[0] == '"' or v[0] == "'": - quotechar = v[0] - testv = v[1:].split(quotechar) - triplequote = False - triplequotecount = 0 - if len(testv) > 1 and testv[0] == "" and testv[1] == "": - testv = testv[2:] - triplequote = True - closed = False - for tv in testv: - if tv == "": - if triplequote: - triplequotecount += 1 - else: - closed = True - else: - oddbackslash = False - try: - i = -1 - j = tv[i] - while j == "\\": - oddbackslash = not oddbackslash - i -= 1 - j = tv[i] - except IndexError: - pass - if not oddbackslash: - if closed: - raise ValueError( - "Found tokens after a closed " + "string. Invalid TOML." - ) - else: - if not triplequote or triplequotecount > 1: - closed = True - else: - triplequotecount = 0 - if quotechar == '"': - escapeseqs = v.split("\\")[1:] - backslash = False - for i in escapeseqs: - if i == "": - backslash = not backslash - else: - if i[0] not in _escapes and (i[0] != "u" and i[0] != "U" and not backslash): - raise ValueError("Reserved escape sequence used") - if backslash: - backslash = False - for prefix in ["\\u", "\\U"]: - if prefix in v: - hexbytes = v.split(prefix) - v = _load_unicode_escapes(hexbytes[0], hexbytes[1:], prefix) - v = _unescape(v) - if len(v) > 1 and v[1] == quotechar and (len(v) < 3 or v[1] == v[2]): - v = v[2:-2] - return (v[1:-1], "str") - elif v[0] == "[": - return (self.load_array(v), "array") - elif v[0] == "{": - inline_object = self.get_empty_inline_table() - self.load_inline_object(v, inline_object) - return (inline_object, "inline_object") - elif TIME_RE.match(v): - h, m, s, _, ms = TIME_RE.match(v).groups() - time = datetime.time(int(h), int(m), int(s), int(ms) if ms else 0) - return (time, "time") - else: - parsed_date = _load_date(v) - if parsed_date is not None: - return (parsed_date, "date") - if not strictly_valid: - raise ValueError("Weirdness with leading zeroes or " "underscores in your number.") - itype = "int" - neg = False - if v[0] == "-": - neg = True - v = v[1:] - elif v[0] == "+": - v = v[1:] - v = v.replace("_", "") - lowerv = v.lower() - if "." in v or ("x" not in v and ("e" in v or "E" in v)): - if "." in v and v.split(".", 1)[1] == "": - raise ValueError("This float is missing digits after " "the point") - if v[0] not in "0123456789": - raise ValueError("This float doesn't have a leading " "digit") - v = float(v) - itype = "float" - elif len(lowerv) == 3 and (lowerv == "inf" or lowerv == "nan"): - v = float(v) - itype = "float" - if itype == "int": - v = int(v, 0) - if neg: - return (0 - v, itype) - return (v, itype) - - def bounded_string(self, s): - if len(s) == 0: - return True - if s[-1] != s[0]: - return False - i = -2 - backslash = False - while len(s) + i > 0: - if s[i] == "\\": - backslash = not backslash - i -= 1 - else: - break - return not backslash - - def _load_array_isstrarray(self, a): - a = a[1:-1].strip() - if a != "" and (a[0] == '"' or a[0] == "'"): - return True - return False - - def load_array(self, a): - atype = None - retval = [] - a = a.strip() - if "[" not in a[1:-1] or "" != a[1:-1].split("[")[0].strip(): - strarray = self._load_array_isstrarray(a) - if not a[1:-1].strip().startswith("{"): - a = a[1:-1].split(",") - else: - # a is an inline object, we must find the matching parenthesis - # to define groups - new_a = [] - start_group_index = 1 - end_group_index = 2 - open_bracket_count = 1 if a[start_group_index] == "{" else 0 - in_str = False - while end_group_index < len(a[1:]): - if a[end_group_index] == '"' or a[end_group_index] == "'": - if in_str: - backslash_index = end_group_index - 1 - while backslash_index > -1 and a[backslash_index] == "\\": - in_str = not in_str - backslash_index -= 1 - in_str = not in_str - if not in_str and a[end_group_index] == "{": - open_bracket_count += 1 - if in_str or a[end_group_index] != "}": - end_group_index += 1 - continue - elif a[end_group_index] == "}" and open_bracket_count > 1: - open_bracket_count -= 1 - end_group_index += 1 - continue - - # Increase end_group_index by 1 to get the closing bracket - end_group_index += 1 - - new_a.append(a[start_group_index:end_group_index]) - - # The next start index is at least after the closing - # bracket, a closing bracket can be followed by a comma - # since we are in an array. - start_group_index = end_group_index + 1 - while start_group_index < len(a[1:]) and a[start_group_index] != "{": - start_group_index += 1 - end_group_index = start_group_index + 1 - a = new_a - b = 0 - if strarray: - while b < len(a) - 1: - ab = a[b].strip() - while not self.bounded_string(ab) or ( - len(ab) > 2 - and ab[0] == ab[1] == ab[2] - and ab[-2] != ab[0] - and ab[-3] != ab[0] - ): - a[b] = a[b] + "," + a[b + 1] - ab = a[b].strip() - if b < len(a) - 2: - a = a[: b + 1] + a[b + 2 :] - else: - a = a[: b + 1] - b += 1 - else: - al = list(a[1:-1]) - a = [] - openarr = 0 - j = 0 - for i in _range(len(al)): - if al[i] == "[": - openarr += 1 - elif al[i] == "]": - openarr -= 1 - elif al[i] == "," and not openarr: - a.append("".join(al[j:i])) - j = i + 1 - a.append("".join(al[j:])) - for i in _range(len(a)): - a[i] = a[i].strip() - if a[i] != "": - nval, ntype = self.load_value(a[i]) - if atype: - if ntype != atype: - raise ValueError("Not a homogeneous array") - else: - atype = ntype - retval.append(nval) - return retval - - def preserve_comment(self, line_no, key, comment, beginline): - pass - - def embed_comments(self, idx, currentlevel): - pass - - -class TomlPreserveCommentDecoder(TomlDecoder): - def __init__(self, _dict=dict): - self.saved_comments = {} - super(TomlPreserveCommentDecoder, self).__init__(_dict) - - def preserve_comment(self, line_no, key, comment, beginline): - self.saved_comments[line_no] = (key, comment, beginline) - - def embed_comments(self, idx, currentlevel): - if idx not in self.saved_comments: - return - - key, comment, beginline = self.saved_comments[idx] - currentlevel[key] = CommentValue(currentlevel[key], comment, beginline, self._dict) diff --git a/isort/_vendored/toml/encoder.py b/isort/_vendored/toml/encoder.py deleted file mode 100644 index c601afdde..000000000 --- a/isort/_vendored/toml/encoder.py +++ /dev/null @@ -1,295 +0,0 @@ -import datetime -import re -import sys -from decimal import Decimal - -from .decoder import InlineTableDict - -if sys.version_info >= (3,): - unicode = str - - -def dump(o, f, encoder=None): - """Writes out dict as toml to a file - - Args: - o: Object to dump into toml - f: File descriptor where the toml should be stored - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dictionary - - Raises: - TypeError: When anything other than file descriptor is passed - """ - - if not f.write: - raise TypeError("You can only dump an object to a file descriptor") - d = dumps(o, encoder=encoder) - f.write(d) - return d - - -def dumps(o, encoder=None): - """Stringifies input dict as toml - - Args: - o: Object to dump into toml - encoder: The ``TomlEncoder`` to use for constructing the output string - - Returns: - String containing the toml corresponding to dict - - Examples: - ```python - >>> import toml - >>> output = { - ... 'a': "I'm a string", - ... 'b': ["I'm", "a", "list"], - ... 'c': 2400 - ... } - >>> toml.dumps(output) - 'a = "I\'m a string"\nb = [ "I\'m", "a", "list",]\nc = 2400\n' - ``` - """ - - retval = "" - if encoder is None: - encoder = TomlEncoder(o.__class__) - addtoretval, sections = encoder.dump_sections(o, "") - retval += addtoretval - outer_objs = [id(o)] - while sections: - section_ids = [id(section) for section in sections] - for outer_obj in outer_objs: - if outer_obj in section_ids: - raise ValueError("Circular reference detected") - outer_objs += section_ids - newsections = encoder.get_empty_table() - for section in sections: - addtoretval, addtosections = encoder.dump_sections(sections[section], section) - - if addtoretval or (not addtoretval and not addtosections): - if retval and retval[-2:] != "\n\n": - retval += "\n" - retval += "[" + section + "]\n" - if addtoretval: - retval += addtoretval - for s in addtosections: - newsections[section + "." + s] = addtosections[s] - sections = newsections - return retval - - -def _dump_str(v): - if sys.version_info < (3,) and hasattr(v, "decode") and isinstance(v, str): - v = v.decode("utf-8") - v = "%r" % v - if v[0] == "u": - v = v[1:] - singlequote = v.startswith("'") - if singlequote or v.startswith('"'): - v = v[1:-1] - if singlequote: - v = v.replace("\\'", "'") - v = v.replace('"', '\\"') - v = v.split("\\x") - while len(v) > 1: - i = -1 - if not v[0]: - v = v[1:] - v[0] = v[0].replace("\\\\", "\\") - # No, I don't know why != works and == breaks - joinx = v[0][i] != "\\" - while v[0][:i] and v[0][i] == "\\": - joinx = not joinx - i -= 1 - if joinx: - joiner = "x" - else: - joiner = "u00" - v = [v[0] + joiner + v[1]] + v[2:] - return unicode('"' + v[0] + '"') - - -def _dump_float(v): - return "{}".format(v).replace("e+0", "e+").replace("e-0", "e-") - - -def _dump_time(v): - utcoffset = v.utcoffset() - if utcoffset is None: - return v.isoformat() - # The TOML norm specifies that it's local time thus we drop the offset - return v.isoformat()[:-6] - - -class TomlEncoder(object): - def __init__(self, _dict=dict, preserve=False): - self._dict = _dict - self.preserve = preserve - self.dump_funcs = { - str: _dump_str, - unicode: _dump_str, - list: self.dump_list, - bool: lambda v: unicode(v).lower(), - int: lambda v: v, - float: _dump_float, - Decimal: _dump_float, - datetime.datetime: lambda v: v.isoformat().replace("+00:00", "Z"), - datetime.time: _dump_time, - datetime.date: lambda v: v.isoformat(), - } - - def get_empty_table(self): - return self._dict() - - def dump_list(self, v): - retval = "[" - for u in v: - retval += " " + unicode(self.dump_value(u)) + "," - retval += "]" - return retval - - def dump_inline_table(self, section): - """Preserve inline table in its compact syntax instead of expanding - into subsection. - - https://github.com/toml-lang/toml#user-content-inline-table - """ - retval = "" - if isinstance(section, dict): - val_list = [] - for k, v in section.items(): - val = self.dump_inline_table(v) - val_list.append(k + " = " + val) - retval += "{ " + ", ".join(val_list) + " }\n" - return retval - else: - return unicode(self.dump_value(section)) - - def dump_value(self, v): - # Lookup function corresponding to v's type - dump_fn = self.dump_funcs.get(type(v)) - if dump_fn is None and hasattr(v, "__iter__"): - dump_fn = self.dump_funcs[list] - # Evaluate function (if it exists) else return v - return dump_fn(v) if dump_fn is not None else self.dump_funcs[str](v) - - def dump_sections(self, o, sup): - retstr = "" - if sup != "" and sup[-1] != ".": - sup += "." - retdict = self._dict() - arraystr = "" - for section in o: - section = unicode(section) - qsection = section - if not re.match(r"^[A-Za-z0-9_-]+$", section): - qsection = _dump_str(section) - if not isinstance(o[section], dict): - arrayoftables = False - if isinstance(o[section], list): - for a in o[section]: - if isinstance(a, dict): - arrayoftables = True - if arrayoftables: - for a in o[section]: - arraytabstr = "\n" - arraystr += "[[" + sup + qsection + "]]\n" - s, d = self.dump_sections(a, sup + qsection) - if s: - if s[0] == "[": - arraytabstr += s - else: - arraystr += s - while d: - newd = self._dict() - for dsec in d: - s1, d1 = self.dump_sections(d[dsec], sup + qsection + "." + dsec) - if s1: - arraytabstr += "[" + sup + qsection + "." + dsec + "]\n" - arraytabstr += s1 - for s1 in d1: - newd[dsec + "." + s1] = d1[s1] - d = newd - arraystr += arraytabstr - else: - if o[section] is not None: - retstr += qsection + " = " + unicode(self.dump_value(o[section])) + "\n" - elif self.preserve and isinstance(o[section], InlineTableDict): - retstr += qsection + " = " + self.dump_inline_table(o[section]) - else: - retdict[qsection] = o[section] - retstr += arraystr - return (retstr, retdict) - - -class TomlPreserveInlineDictEncoder(TomlEncoder): - def __init__(self, _dict=dict): - super(TomlPreserveInlineDictEncoder, self).__init__(_dict, True) - - -class TomlArraySeparatorEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False, separator=","): - super(TomlArraySeparatorEncoder, self).__init__(_dict, preserve) - if separator.strip() == "": - separator = "," + separator - elif separator.strip(" \t\n\r,"): - raise ValueError("Invalid separator for arrays") - self.separator = separator - - def dump_list(self, v): - t = [] - retval = "[" - for u in v: - t.append(self.dump_value(u)) - while t != []: - s = [] - for u in t: - if isinstance(u, list): - for r in u: - s.append(r) - else: - retval += " " + unicode(u) + self.separator - t = s - retval += "]" - return retval - - -class TomlNumpyEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False): - import numpy as np - - super(TomlNumpyEncoder, self).__init__(_dict, preserve) - self.dump_funcs[np.float16] = _dump_float - self.dump_funcs[np.float32] = _dump_float - self.dump_funcs[np.float64] = _dump_float - self.dump_funcs[np.int16] = self._dump_int - self.dump_funcs[np.int32] = self._dump_int - self.dump_funcs[np.int64] = self._dump_int - - def _dump_int(self, v): - return "{}".format(int(v)) - - -class TomlPreserveCommentEncoder(TomlEncoder): - def __init__(self, _dict=dict, preserve=False): - from .decoder import CommentValue - - super(TomlPreserveCommentEncoder, self).__init__(_dict, preserve) - self.dump_funcs[CommentValue] = lambda v: v.dump(self.dump_value) - - -class TomlPathlibEncoder(TomlEncoder): - def _dump_pathlib_path(self, v): - return _dump_str(str(v)) - - def dump_value(self, v): - if (3, 4) <= sys.version_info: - import pathlib - - if isinstance(v, pathlib.PurePath): - v = str(v) - return super(TomlPathlibEncoder, self).dump_value(v) diff --git a/isort/_vendored/toml/ordered.py b/isort/_vendored/toml/ordered.py deleted file mode 100644 index 013b31e5c..000000000 --- a/isort/_vendored/toml/ordered.py +++ /dev/null @@ -1,13 +0,0 @@ -from collections import OrderedDict - -from . import TomlDecoder, TomlEncoder - - -class TomlOrderedDecoder(TomlDecoder): - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) - - -class TomlOrderedEncoder(TomlEncoder): - def __init__(self): - super(self.__class__, self).__init__(_dict=OrderedDict) diff --git a/isort/_vendored/toml/tz.py b/isort/_vendored/toml/tz.py deleted file mode 100644 index 46214bd4d..000000000 --- a/isort/_vendored/toml/tz.py +++ /dev/null @@ -1,21 +0,0 @@ -from datetime import timedelta, tzinfo - - -class TomlTz(tzinfo): - def __init__(self, toml_offset): - if toml_offset == "Z": - self._raw_offset = "+00:00" - else: - self._raw_offset = toml_offset - self._sign = -1 if self._raw_offset[0] == "-" else 1 - self._hours = int(self._raw_offset[1:3]) - self._minutes = int(self._raw_offset[4:6]) - - def tzname(self, dt): - return "UTC" + self._raw_offset - - def utcoffset(self, dt): - return self._sign * timedelta(hours=self._hours, minutes=self._minutes) - - def dst(self, dt): - return timedelta(0) diff --git a/isort/_vendored/toml/LICENSE b/isort/_vendored/tomli/LICENSE similarity index 74% rename from isort/_vendored/toml/LICENSE rename to isort/_vendored/tomli/LICENSE index 5010e3075..e859590f8 100644 --- a/isort/_vendored/toml/LICENSE +++ b/isort/_vendored/tomli/LICENSE @@ -1,12 +1,6 @@ -The MIT License +MIT License -Copyright 2013-2019 William Pearson -Copyright 2015-2016 Julien Enselme -Copyright 2016 Google Inc. -Copyright 2017 Samuel Vasko -Copyright 2017 Nate Prewitt -Copyright 2017 Jack Evans -Copyright 2019 Filippo Broggini +Copyright (c) 2021 Taneli Hukkinen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -15,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/isort/_vendored/tomli/__init__.py b/isort/_vendored/tomli/__init__.py new file mode 100644 index 000000000..5b9f2478d --- /dev/null +++ b/isort/_vendored/tomli/__init__.py @@ -0,0 +1,6 @@ +"""A lil' TOML parser.""" + +__all__ = ("loads", "load", "TOMLDecodeError") +__version__ = "1.2.0" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT + +from ._parser import TOMLDecodeError, load, loads diff --git a/isort/_vendored/tomli/_parser.py b/isort/_vendored/tomli/_parser.py new file mode 100644 index 000000000..156848fc4 --- /dev/null +++ b/isort/_vendored/tomli/_parser.py @@ -0,0 +1,650 @@ +import string +import warnings +from types import MappingProxyType +from typing import IO, Any, Callable, Dict, FrozenSet, Iterable, NamedTuple, Optional, Tuple + +from ._re import ( + RE_DATETIME, + RE_LOCALTIME, + RE_NUMBER, + match_to_datetime, + match_to_localtime, + match_to_number, +) + +ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) + +# Neither of these sets include quotation mark or backslash. They are +# currently handled as separate cases in the parser functions. +ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") +ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n\r") + +ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS +ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ASCII_CTRL - frozenset("\t\n") + +ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS + +TOML_WS = frozenset(" \t") +TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n") +BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_") +KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'") +HEXDIGIT_CHARS = frozenset(string.hexdigits) + +BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( + { + "\\b": "\u0008", # backspace + "\\t": "\u0009", # tab + "\\n": "\u000A", # linefeed + "\\f": "\u000C", # form feed + "\\r": "\u000D", # carriage return + '\\"': "\u0022", # quote + "\\\\": "\u005C", # backslash + } +) + +# Type annotations +ParseFloat = Callable[[str], Any] +Key = Tuple[str, ...] +Pos = int + + +class TOMLDecodeError(ValueError): + """An error raised if a document is not valid TOML.""" + + +def load(fp: IO, *, parse_float: ParseFloat = float) -> Dict[str, Any]: + """Parse TOML from a file object.""" + s = fp.read() + if isinstance(s, bytes): + s = s.decode() + else: + warnings.warn( + "Text file object support is deprecated in favor of binary file objects." + ' Use `open("foo.toml", "rb")` to open the file in binary mode.', + DeprecationWarning, + ) + return loads(s, parse_float=parse_float) + + +def loads(s: str, *, parse_float: ParseFloat = float) -> Dict[str, Any]: # noqa: C901 + """Parse TOML from a string.""" + + # The spec allows converting "\r\n" to "\n", even in string + # literals. Let's do so to simplify parsing. + src = s.replace("\r\n", "\n") + pos = 0 + out = Output(NestedDict(), Flags()) + header: Key = () + + # Parse one statement at a time + # (typically means one line in TOML source) + while True: + # 1. Skip line leading whitespace + pos = skip_chars(src, pos, TOML_WS) + + # 2. Parse rules. Expect one of the following: + # - end of file + # - end of line + # - comment + # - key/value pair + # - append dict to list (and move to its namespace) + # - create dict (and move to its namespace) + # Skip trailing whitespace when applicable. + try: + char = src[pos] + except IndexError: + break + if char == "\n": + pos += 1 + continue + if char in KEY_INITIAL_CHARS: + pos = key_value_rule(src, pos, out, header, parse_float) + pos = skip_chars(src, pos, TOML_WS) + elif char == "[": + try: + second_char: Optional[str] = src[pos + 1] + except IndexError: + second_char = None + if second_char == "[": + pos, header = create_list_rule(src, pos, out) + else: + pos, header = create_dict_rule(src, pos, out) + pos = skip_chars(src, pos, TOML_WS) + elif char != "#": + raise suffixed_err(src, pos, "Invalid statement") + + # 3. Skip comment + pos = skip_comment(src, pos) + + # 4. Expect end of line or end of file + try: + char = src[pos] + except IndexError: + break + if char != "\n": + raise suffixed_err(src, pos, "Expected newline or end of document after a statement") + pos += 1 + + return out.data.dict + + +class Flags: + """Flags that map to parsed keys/namespaces.""" + + # Marks an immutable namespace (inline array or inline table). + FROZEN = 0 + # Marks a nest that has been explicitly created and can no longer + # be opened using the "[table]" syntax. + EXPLICIT_NEST = 1 + + def __init__(self) -> None: + self._flags: Dict[str, dict] = {} + + def unset_all(self, key: Key) -> None: + cont = self._flags + for k in key[:-1]: + if k not in cont: + return + cont = cont[k]["nested"] + cont.pop(key[-1], None) + + def set_for_relative_key(self, head_key: Key, rel_key: Key, flag: int) -> None: + cont = self._flags + for k in head_key: + if k not in cont: + cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + for k in rel_key: + if k in cont: + cont[k]["flags"].add(flag) + else: + cont[k] = {"flags": {flag}, "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + + def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003 + cont = self._flags + key_parent, key_stem = key[:-1], key[-1] + for k in key_parent: + if k not in cont: + cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + if key_stem not in cont: + cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag) + + def is_(self, key: Key, flag: int) -> bool: + if not key: + return False # document root has no flags + cont = self._flags + for k in key[:-1]: + if k not in cont: + return False + inner_cont = cont[k] + if flag in inner_cont["recursive_flags"]: + return True + cont = inner_cont["nested"] + key_stem = key[-1] + if key_stem in cont: + cont = cont[key_stem] + return flag in cont["flags"] or flag in cont["recursive_flags"] + return False + + +class NestedDict: + def __init__(self) -> None: + # The parsed content of the TOML document + self.dict: Dict[str, Any] = {} + + def get_or_create_nest( + self, + key: Key, + *, + access_lists: bool = True, + ) -> dict: + cont: Any = self.dict + for k in key: + if k not in cont: + cont[k] = {} + cont = cont[k] + if access_lists and isinstance(cont, list): + cont = cont[-1] + if not isinstance(cont, dict): + raise KeyError("There is no nest behind this key") + return cont + + def append_nest_to_list(self, key: Key) -> None: + cont = self.get_or_create_nest(key[:-1]) + last_key = key[-1] + if last_key in cont: + list_ = cont[last_key] + if not isinstance(list_, list): + raise KeyError("An object other than list found behind this key") + list_.append({}) + else: + cont[last_key] = [{}] + + +class Output(NamedTuple): + data: NestedDict + flags: Flags + + +def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos: + try: + while src[pos] in chars: + pos += 1 + except IndexError: + pass + return pos + + +def skip_until( + src: str, + pos: Pos, + expect: str, + *, + error_on: FrozenSet[str], + error_on_eof: bool, +) -> Pos: + try: + new_pos = src.index(expect, pos) + except ValueError: + new_pos = len(src) + if error_on_eof: + raise suffixed_err(src, new_pos, f'Expected "{expect!r}"') + + if not error_on.isdisjoint(src[pos:new_pos]): + while src[pos] not in error_on: + pos += 1 + raise suffixed_err(src, pos, f'Found invalid character "{src[pos]!r}"') + return new_pos + + +def skip_comment(src: str, pos: Pos) -> Pos: + try: + char: Optional[str] = src[pos] + except IndexError: + char = None + if char == "#": + return skip_until(src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False) + return pos + + +def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos: + while True: + pos_before_skip = pos + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + pos = skip_comment(src, pos) + if pos == pos_before_skip: + return pos + + +def create_dict_rule(src: str, pos: Pos, out: Output) -> Tuple[Pos, Key]: + pos += 1 # Skip "[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.EXPLICIT_NEST) or out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Can not declare {key} twice") + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.get_or_create_nest(key) + except KeyError: + raise suffixed_err(src, pos, "Can not overwrite a value") + + if not src.startswith("]", pos): + raise suffixed_err(src, pos, 'Expected "]" at the end of a table declaration') + return pos + 1, key + + +def create_list_rule(src: str, pos: Pos, out: Output) -> Tuple[Pos, Key]: + pos += 2 # Skip "[[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}") + # Free the namespace now that it points to another empty list item... + out.flags.unset_all(key) + # ...but this key precisely is still prohibited from table declaration + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.append_nest_to_list(key) + except KeyError: + raise suffixed_err(src, pos, "Can not overwrite a value") + + if not src.startswith("]]", pos): + raise suffixed_err(src, pos, 'Expected "]]" at the end of an array declaration') + return pos + 2, key + + +def key_value_rule(src: str, pos: Pos, out: Output, header: Key, parse_float: ParseFloat) -> Pos: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + abs_key_parent = header + key_parent + + if out.flags.is_(abs_key_parent, Flags.FROZEN): + raise suffixed_err(src, pos, f"Can not mutate immutable namespace {abs_key_parent}") + # Containers in the relative path can't be opened with the table syntax after this + out.flags.set_for_relative_key(header, key, Flags.EXPLICIT_NEST) + try: + nest = out.data.get_or_create_nest(abs_key_parent) + except KeyError: + raise suffixed_err(src, pos, "Can not overwrite a value") + if key_stem in nest: + raise suffixed_err(src, pos, "Can not overwrite a value") + # Mark inline table and array namespaces recursively immutable + if isinstance(value, (dict, list)): + out.flags.set(header + key, Flags.FROZEN, recursive=True) + nest[key_stem] = value + return pos + + +def parse_key_value_pair(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, Key, Any]: + pos, key = parse_key(src, pos) + try: + char: Optional[str] = src[pos] + except IndexError: + char = None + if char != "=": + raise suffixed_err(src, pos, 'Expected "=" after a key in a key/value pair') + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, value = parse_value(src, pos, parse_float) + return pos, key, value + + +def parse_key(src: str, pos: Pos) -> Tuple[Pos, Key]: + pos, key_part = parse_key_part(src, pos) + key: Key = (key_part,) + pos = skip_chars(src, pos, TOML_WS) + while True: + try: + char: Optional[str] = src[pos] + except IndexError: + char = None + if char != ".": + return pos, key + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, key_part = parse_key_part(src, pos) + key += (key_part,) + pos = skip_chars(src, pos, TOML_WS) + + +def parse_key_part(src: str, pos: Pos) -> Tuple[Pos, str]: + try: + char: Optional[str] = src[pos] + except IndexError: + char = None + if char in BARE_KEY_CHARS: + start_pos = pos + pos = skip_chars(src, pos, BARE_KEY_CHARS) + return pos, src[start_pos:pos] + if char == "'": + return parse_literal_str(src, pos) + if char == '"': + return parse_one_line_basic_str(src, pos) + raise suffixed_err(src, pos, "Invalid initial character for a key part") + + +def parse_one_line_basic_str(src: str, pos: Pos) -> Tuple[Pos, str]: + pos += 1 + return parse_basic_str(src, pos, multiline=False) + + +def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, list]: + pos += 1 + array: list = [] + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + while True: + pos, val = parse_value(src, pos, parse_float) + array.append(val) + pos = skip_comments_and_array_ws(src, pos) + + c = src[pos : pos + 1] + if c == "]": + return pos + 1, array + if c != ",": + raise suffixed_err(src, pos, "Unclosed array") + pos += 1 + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + + +def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, dict]: + pos += 1 + nested_dict = NestedDict() + flags = Flags() + + pos = skip_chars(src, pos, TOML_WS) + if src.startswith("}", pos): + return pos + 1, nested_dict.dict + while True: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + if flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}") + try: + nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) + except KeyError: + raise suffixed_err(src, pos, "Can not overwrite a value") + if key_stem in nest: + raise suffixed_err(src, pos, f'Duplicate inline table key "{key_stem}"') + nest[key_stem] = value + pos = skip_chars(src, pos, TOML_WS) + c = src[pos : pos + 1] + if c == "}": + return pos + 1, nested_dict.dict + if c != ",": + raise suffixed_err(src, pos, "Unclosed inline table") + if isinstance(value, (dict, list)): + flags.set(key, Flags.FROZEN, recursive=True) + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + + +def parse_basic_str_escape( # noqa: C901 + src: str, pos: Pos, *, multiline: bool = False +) -> Tuple[Pos, str]: + escape_id = src[pos : pos + 2] + pos += 2 + if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}: + # Skip whitespace until next non-whitespace character or end of + # the doc. Error if non-whitespace is found before newline. + if escape_id != "\\\n": + pos = skip_chars(src, pos, TOML_WS) + try: + char = src[pos] + except IndexError: + return pos, "" + if char != "\n": + raise suffixed_err(src, pos, 'Unescaped "\\" in a string') + pos += 1 + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + return pos, "" + if escape_id == "\\u": + return parse_hex_char(src, pos, 4) + if escape_id == "\\U": + return parse_hex_char(src, pos, 8) + try: + return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] + except KeyError: + if len(escape_id) != 2: + raise suffixed_err(src, pos, "Unterminated string") + raise suffixed_err(src, pos, 'Unescaped "\\" in a string') + + +def parse_basic_str_escape_multiline(src: str, pos: Pos) -> Tuple[Pos, str]: + return parse_basic_str_escape(src, pos, multiline=True) + + +def parse_hex_char(src: str, pos: Pos, hex_len: int) -> Tuple[Pos, str]: + hex_str = src[pos : pos + hex_len] + if len(hex_str) != hex_len or not HEXDIGIT_CHARS.issuperset(hex_str): + raise suffixed_err(src, pos, "Invalid hex value") + pos += hex_len + hex_int = int(hex_str, 16) + if not is_unicode_scalar_value(hex_int): + raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") + return pos, chr(hex_int) + + +def parse_literal_str(src: str, pos: Pos) -> Tuple[Pos, str]: + pos += 1 # Skip starting apostrophe + start_pos = pos + pos = skip_until(src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True) + return pos + 1, src[start_pos:pos] # Skip ending apostrophe + + +def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> Tuple[Pos, str]: + pos += 3 + if src.startswith("\n", pos): + pos += 1 + + if literal: + delim = "'" + end_pos = skip_until( + src, + pos, + "'''", + error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS, + error_on_eof=True, + ) + result = src[pos:end_pos] + pos = end_pos + 3 + else: + delim = '"' + pos, result = parse_basic_str(src, pos, multiline=True) + + # Add at maximum two extra apostrophes/quotes if the end sequence + # is 4 or 5 chars long instead of just 3. + if not src.startswith(delim, pos): + return pos, result + pos += 1 + if not src.startswith(delim, pos): + return pos, result + delim + pos += 1 + return pos, result + (delim * 2) + + +def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> Tuple[Pos, str]: + if multiline: + error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape_multiline + else: + error_on = ILLEGAL_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape + result = "" + start_pos = pos + while True: + try: + char = src[pos] + except IndexError: + raise suffixed_err(src, pos, "Unterminated string") + if char == '"': + if not multiline: + return pos + 1, result + src[start_pos:pos] + if src.startswith('"""', pos): + return pos + 3, result + src[start_pos:pos] + pos += 1 + continue + if char == "\\": + result += src[start_pos:pos] + pos, parsed_escape = parse_escapes(src, pos) + result += parsed_escape + start_pos = pos + continue + if char in error_on: + raise suffixed_err(src, pos, f'Illegal character "{char!r}"') + pos += 1 + + +def parse_value(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, Any]: # noqa: C901 + try: + char: Optional[str] = src[pos] + except IndexError: + char = None + + # Basic strings + if char == '"': + if src.startswith('"""', pos): + return parse_multiline_str(src, pos, literal=False) + return parse_one_line_basic_str(src, pos) + + # Literal strings + if char == "'": + if src.startswith("'''", pos): + return parse_multiline_str(src, pos, literal=True) + return parse_literal_str(src, pos) + + # Booleans + if char == "t": + if src.startswith("true", pos): + return pos + 4, True + if char == "f": + if src.startswith("false", pos): + return pos + 5, False + + # Dates and times + datetime_match = RE_DATETIME.match(src, pos) + if datetime_match: + try: + datetime_obj = match_to_datetime(datetime_match) + except ValueError: + raise suffixed_err(src, pos, "Invalid date or datetime") + return datetime_match.end(), datetime_obj + localtime_match = RE_LOCALTIME.match(src, pos) + if localtime_match: + return localtime_match.end(), match_to_localtime(localtime_match) + + # Integers and "normal" floats. + # The regex will greedily match any type starting with a decimal + # char, so needs to be located after handling of dates and times. + number_match = RE_NUMBER.match(src, pos) + if number_match: + return number_match.end(), match_to_number(number_match, parse_float) + + # Arrays + if char == "[": + return parse_array(src, pos, parse_float) + + # Inline tables + if char == "{": + return parse_inline_table(src, pos, parse_float) + + # Special floats + first_three = src[pos : pos + 3] + if first_three in {"inf", "nan"}: + return pos + 3, parse_float(first_three) + first_four = src[pos : pos + 4] + if first_four in {"-inf", "+inf", "-nan", "+nan"}: + return pos + 4, parse_float(first_four) + + raise suffixed_err(src, pos, "Invalid value") + + +def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: + """Return a `TOMLDecodeError` where error message is suffixed with + coordinates in source.""" + + def coord_repr(src: str, pos: Pos) -> str: + if pos >= len(src): + return "end of document" + line = src.count("\n", 0, pos) + 1 + if line == 1: + column = pos + 1 + else: + column = pos - src.rindex("\n", 0, pos) + return f"line {line}, column {column}" + + return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") + + +def is_unicode_scalar_value(codepoint: int) -> bool: + return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111) diff --git a/isort/_vendored/tomli/_re.py b/isort/_vendored/tomli/_re.py new file mode 100644 index 000000000..c8b06f0fe --- /dev/null +++ b/isort/_vendored/tomli/_re.py @@ -0,0 +1,100 @@ +import re +from datetime import date, datetime, time, timedelta, timezone, tzinfo +from functools import lru_cache +from typing import TYPE_CHECKING, Any, Optional, Union + +if TYPE_CHECKING: + from tomli._parser import ParseFloat + +# E.g. +# - 00:32:00.999999 +# - 00:32:00 +_TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.([0-9]{1,6})[0-9]*)?" + +RE_NUMBER = re.compile( + r""" +0 +(?: + x[0-9A-Fa-f](?:_?[0-9A-Fa-f])* # hex + | + b[01](?:_?[01])* # bin + | + o[0-7](?:_?[0-7])* # oct +) +| +[+-]?(?:0|[1-9](?:_?[0-9])*) # dec, integer part +(?P<floatpart> + (?:\.[0-9](?:_?[0-9])*)? # optional fractional part + (?:[eE][+-]?[0-9](?:_?[0-9])*)? # optional exponent part +) +""", + flags=re.VERBOSE, +) +RE_LOCALTIME = re.compile(_TIME_RE_STR) +RE_DATETIME = re.compile( + fr""" +([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) # date, e.g. 1988-10-27 +(?: + [T ] + {_TIME_RE_STR} + (?:(Z)|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))? # optional time offset +)? +""", + flags=re.VERBOSE, +) + + +def match_to_datetime(match: "re.Match") -> Union[datetime, date]: + """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. + + Raises ValueError if the match does not correspond to a valid date + or datetime. + """ + ( + year_str, + month_str, + day_str, + hour_str, + minute_str, + sec_str, + micros_str, + zulu_time, + offset_sign_str, + offset_hour_str, + offset_minute_str, + ) = match.groups() + year, month, day = int(year_str), int(month_str), int(day_str) + if hour_str is None: + return date(year, month, day) + hour, minute, sec = int(hour_str), int(minute_str), int(sec_str) + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + if offset_sign_str: + tz: Optional[tzinfo] = cached_tz(offset_hour_str, offset_minute_str, offset_sign_str) + elif zulu_time: + tz = timezone.utc + else: # local date-time + tz = None + return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz) + + +@lru_cache(maxsize=None) +def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone: + sign = 1 if sign_str == "+" else -1 + return timezone( + timedelta( + hours=sign * int(hour_str), + minutes=sign * int(minute_str), + ) + ) + + +def match_to_localtime(match: "re.Match") -> time: + hour_str, minute_str, sec_str, micros_str = match.groups() + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + return time(int(hour_str), int(minute_str), int(sec_str), micros) + + +def match_to_number(match: "re.Match", parse_float: "ParseFloat") -> Any: + if match.group("floatpart"): + return parse_float(match.group()) + return int(match.group(), 0) diff --git a/isort/_vendored/tomli/py.typed b/isort/_vendored/tomli/py.typed new file mode 100644 index 000000000..7632ecf77 --- /dev/null +++ b/isort/_vendored/tomli/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561 diff --git a/isort/settings.py b/isort/settings.py index 1acdb50d9..02006863f 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -45,9 +45,9 @@ from .wrap_modes import from_string as wrap_mode_from_string if TYPE_CHECKING: - toml: Any + tomli: Any else: - from ._vendored import toml + from ._vendored import tomli _SHEBANG_RE = re.compile(br"^#!.*\bpython[23w]?\b") CYTHON_EXTENSIONS = frozenset({"pyx", "pxd"}) @@ -771,7 +771,7 @@ def _get_config_data(file_path: str, sections: Tuple[str]) -> Dict[str, Any]: with open(file_path, encoding="utf-8") as config_file: if file_path.endswith(".toml"): - config = toml.load(config_file) + config = tomli.load(config_file) for section in sections: config_section = config for key in section.split("."): diff --git a/poetry.lock b/poetry.lock index b7844055a..d76a9b231 100644 --- a/poetry.lock +++ b/poetry.lock @@ -56,6 +56,21 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "backports.entry-points-selectable" +version = "1.1.0" +description = "Compatibility shim providing selectable entry points for older implementations" +category = "dev" +optional = false +python-versions = ">=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "pytest-black (>=0.3.7)", "pytest-mypy", "pytest-checkdocs (>=2.4)", "pytest-enabler (>=1.0.1)"] + [[package]] name = "bandit" version = "1.7.0" @@ -141,10 +156,21 @@ python-versions = ">=3.6.1" name = "chardet" version = "3.0.4" description = "Universal encoding detector for Python 2 and 3" -category = "main" +category = "dev" optional = false python-versions = "*" +[[package]] +name = "charset-normalizer" +version = "2.0.4" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "7.1.2" @@ -192,14 +218,14 @@ six = ">=1.10" [[package]] name = "coverage" -version = "5.5" +version = "6.0b1" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.6" [package.extras] -toml = ["toml"] +toml = ["tomli"] [[package]] name = "cruft" @@ -408,7 +434,7 @@ gitdb = ">=4.0.1" [[package]] name = "gitpython" -version = "3.1.18" +version = "3.1.20" description = "Python Git Library" category = "dev" optional = false @@ -416,7 +442,7 @@ python-versions = ">=3.6" [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.0", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} [[package]] name = "h11" @@ -448,7 +474,7 @@ python-versions = "*" [[package]] name = "hstspreload" -version = "2021.7.5" +version = "2021.8.1" description = "Chromium HSTS Preload list as a Python package" category = "dev" optional = false @@ -506,7 +532,7 @@ python-versions = "*" [[package]] name = "hypothesis" -version = "6.14.1" +version = "6.14.5" description = "A library for property-based testing" category = "dev" optional = false @@ -562,7 +588,7 @@ libcst = ">=0.3.8" [[package]] name = "identify" -version = "2.2.10" +version = "2.2.11" description = "File identification library for Python" category = "dev" optional = false @@ -592,7 +618,7 @@ test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)"] [[package]] name = "importlib-metadata" -version = "4.6.1" +version = "4.6.3" description = "Read metadata from Python packages" category = "main" optional = false @@ -609,7 +635,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [[package]] name = "importlib-resources" -version = "5.2.0" +version = "5.2.2" description = "Read resources from Python packages" category = "dev" optional = false @@ -807,7 +833,7 @@ python-versions = ">=3.6" [[package]] name = "mkdocs" -version = "1.2.1" +version = "1.2.2" description = "Project documentation with Markdown." category = "dev" optional = false @@ -830,7 +856,7 @@ i18n = ["babel (>=2.9.0)"] [[package]] name = "mkdocs-material" -version = "7.1.9" +version = "7.2.2" description = "A Material Design theme for MkDocs" category = "dev" optional = false @@ -944,11 +970,11 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.8.1" +version = "0.9.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "pbr" @@ -975,7 +1001,7 @@ Markdown = ">=3.0.0,<4.0.0" [[package]] name = "pep517" -version = "0.10.0" +version = "0.11.0" description = "Wrappers to build Python packages using PEP 517 hooks" category = "main" optional = false @@ -983,7 +1009,7 @@ python-versions = "*" [package.dependencies] importlib_metadata = {version = "*", markers = "python_version < \"3.8\""} -toml = "*" +tomli = {version = "*", markers = "python_version >= \"3.6\""} zipp = {version = "*", markers = "python_version < \"3.8\""} [[package]] @@ -1063,6 +1089,18 @@ python-versions = "*" docopt = "*" yarg = "*" +[[package]] +name = "platformdirs" +version = "2.2.0" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + [[package]] name = "plette" version = "0.2.3" @@ -1332,7 +1370,7 @@ dev = ["pre-commit", "tox"] [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" description = "Extensions to the standard Python datetime module" category = "main" optional = false @@ -1384,21 +1422,21 @@ python-versions = "*" [[package]] name = "requests" -version = "2.25.1" +version = "2.26.0" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<5" -idna = ">=2.5,<3" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} urllib3 = ">=1.21.1,<1.27" [package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] [[package]] name = "requirementslib" @@ -1532,10 +1570,18 @@ python-versions = "*" name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" +category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "1.2.0" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "tomlkit" version = "0.7.2" @@ -1652,23 +1698,24 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.4.7" +version = "20.7.0" description = "Virtual Python Environment builder" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -appdirs = ">=1.4.3,<2" +"backports.entry-points-selectable" = ">=1.0.4" distlib = ">=0.3.1,<1" filelock = ">=3.0.0,<4" importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} importlib-resources = {version = ">=1.0", markers = "python_version < \"3.7\""} +platformdirs = ">=2,<3" six = ">=1.9.0,<2" [package.extras] docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] -testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] [[package]] name = "vistir" @@ -1756,7 +1803,7 @@ requirements_deprecated_finder = ["pipreqs", "pip-api"] [metadata] lock-version = "1.1" python-versions = ">=3.6.1,<4.0" -content-hash = "c73791ac0cce25c94e949750728fbe4f48d4dfadacc874f781dcc4d8266531af" +content-hash = "982204115a3093f1615a240a7b46887dc273fb86e973d8029e75c1aefc15fa04" [metadata.files] appdirs = [ @@ -1783,6 +1830,10 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +"backports.entry-points-selectable" = [ + {file = "backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl", hash = "sha256:a6d9a871cde5e15b4c4a53e3d43ba890cc6861ec1332c9c2428c92f977192acc"}, + {file = "backports.entry_points_selectable-1.1.0.tar.gz", hash = "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a"}, +] bandit = [ {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"}, {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"}, @@ -1813,6 +1864,10 @@ chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"}, + {file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"}, +] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, @@ -1829,58 +1884,36 @@ cookiecutter = [ {file = "cookiecutter-1.7.3.tar.gz", hash = "sha256:6b9a4d72882e243be077a7397d0f1f76fe66cf3df91f3115dbb5330e214fa457"}, ] coverage = [ - {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, - {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, - {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, - {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, - {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, - {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, - {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, - {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, - {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, - {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, - {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, - {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, - {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, - {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, - {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, - {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, - {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, - {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, - {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, - {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, - {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, - {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, - {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, - {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, + {file = "coverage-6.0b1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:da7de6e4162c69cc03cc56b7d051ae11147ac30872ff57df4ba4cac6d70ce5d9"}, + {file = "coverage-6.0b1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:23c1611471cbfa2ac0e283862a76a333c13e5e7c4d499feb9919a5f52884610e"}, + {file = "coverage-6.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:ddb2287f66500ac57b24cce60341074b148977b74cd20eca755f95262928086f"}, + {file = "coverage-6.0b1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c8099c7033fb1ca73ac2246c3e52f45dd6a9c3826c59b3b5ad94e5be4e08d99b"}, + {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdaa96733c9cf85491ad406fd78aa16025a1ea468951545b3da7ee133c150c7a"}, + {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9981294b131023e63061ba88f4498fe27b9b15d908079d1866ee66a63d6e793f"}, + {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea784c96ca3b94912176d7adc9c4bb7d1988f36a0223a9ac128f4c834775202c"}, + {file = "coverage-6.0b1-cp36-cp36m-win32.whl", hash = "sha256:7beec4df7542cf681356ef243fee3bf948775fc0d125bdcad3508e834229e07d"}, + {file = "coverage-6.0b1-cp36-cp36m-win_amd64.whl", hash = "sha256:84a1000f622d1df8824cd1ac629aa8392679c5c4de3f0de9e6889373f99ff3a0"}, + {file = "coverage-6.0b1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c1630e847ae0a2a366f18ddc3e017b69f80d729e95830579c61b5f9e9b94b91e"}, + {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a585ba4087cc1fb5bfe34d1ecaaee183b854427992be2b42f1722ba8289fa82"}, + {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:16db4173575901db8f3e6cc05e50fe19c7849b0256f6dc2e0979485184053417"}, + {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a8826f6ecf079cb648534790ba59218a64e12a59bf2cd9ff00199abb39864a79"}, + {file = "coverage-6.0b1-cp37-cp37m-win32.whl", hash = "sha256:40e30139113b141c238620b700aa5bd5c1b3a7b29ae47398936ff1c9166109d9"}, + {file = "coverage-6.0b1-cp37-cp37m-win_amd64.whl", hash = "sha256:95d2293d6a60da8952c675050231c02c9f4f1c1b9cf916315173e921d137d683"}, + {file = "coverage-6.0b1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22888d3ce1b6fa1125f0be1602d8c634e00e7ec3a87bdb594ad87bde0b00b2b6"}, + {file = "coverage-6.0b1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6fbe69d52628b3e8a144265fd134f5da07cf287a00cf529730ae10380d315b2"}, + {file = "coverage-6.0b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f0b250a03891255feb3ae69ac29d05cf9a62f5869bb8bac0e7f4968e7274efac"}, + {file = "coverage-6.0b1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:951e8d7bc98bceb61fc4fb426966fae854160301c0f8cd0945c62f2504f68615"}, + {file = "coverage-6.0b1-cp38-cp38-win32.whl", hash = "sha256:e6a4260f0abf90c023b4f838905f645695b31666b76837152e2befad3d1ef5d6"}, + {file = "coverage-6.0b1-cp38-cp38-win_amd64.whl", hash = "sha256:ceb872b89c6461d4365be5f8fbf14f867be6b5217760980de7e014e54648f8ef"}, + {file = "coverage-6.0b1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2dcc6d62b69a82759e5dddd788e09dd329124e493e62d92cfd01c0b918d7e511"}, + {file = "coverage-6.0b1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97b387f2744762b9984639b59abd7abb46ea6ae2ea24cb7c07893612328559b"}, + {file = "coverage-6.0b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4528368196a90f11b70fb5668c13d92e88ba795eb4d37aab5855fd0479db417b"}, + {file = "coverage-6.0b1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18183948d5480e2ae30ad67edddf748149c778592b7e4ee649c058d5de2dcbb1"}, + {file = "coverage-6.0b1-cp39-cp39-win32.whl", hash = "sha256:91cd79f0f2996a4de737de89fdcbcd379a5bfd7b15129378ad1e5fc234e58d33"}, + {file = "coverage-6.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:4cbdc51fc8c00ec6e53b30221d5757034aecf9839761bf97eaec0db7f0ff4955"}, + {file = "coverage-6.0b1-pp36-none-any.whl", hash = "sha256:8394626a07e0a1b3695a16a4548d32e7259e00817d4bab1ef8172a1bd82a724e"}, + {file = "coverage-6.0b1-pp37-none-any.whl", hash = "sha256:79c136327e90ee46a2b3094263df94da5212890d6145678741eb805d79714971"}, + {file = "coverage-6.0b1.tar.gz", hash = "sha256:c6f46d5bbec8fe1ff25215356e819528a90d84b2801703514746b665742f1cd2"}, ] cruft = [ {file = "cruft-2.9.0-py3-none-any.whl", hash = "sha256:6e77ff2f59a2e2aee7c54ebf302b5a4dd231af44e5971d5ad60135c9e7f4c29d"}, @@ -1968,8 +2001,8 @@ gitdb2 = [ {file = "gitdb2-4.0.2.tar.gz", hash = "sha256:0986cb4003de743f2b3aba4c828edd1ab58ce98e1c4a8acf72ef02760d4beb4e"}, ] gitpython = [ - {file = "GitPython-3.1.18-py3-none-any.whl", hash = "sha256:fce760879cd2aebd2991b3542876dc5c4a909b30c9d69dfc488e504a8db37ee8"}, - {file = "GitPython-3.1.18.tar.gz", hash = "sha256:b838a895977b45ab6f0cc926a9045c8d1c44e2b653c1fcc39fe91f42c6e8f05b"}, + {file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"}, + {file = "GitPython-3.1.20.tar.gz", hash = "sha256:df0e072a200703a65387b0cfdf0466e3bab729c0458cf6b7349d0e9877636519"}, ] h11 = [ {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, @@ -1984,8 +2017,8 @@ hpack = [ {file = "hpack-3.0.0.tar.gz", hash = "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"}, ] hstspreload = [ - {file = "hstspreload-2021.7.5-py3-none-any.whl", hash = "sha256:59fcb43897c2d63666a7e7cac2b2cb423e2c97e39fcf565c7ed814920e02bd8e"}, - {file = "hstspreload-2021.7.5.tar.gz", hash = "sha256:ad5c82b2d6246dda4ca21d477fd9c009a88eb6bdf69456acf241f077d7e35d81"}, + {file = "hstspreload-2021.8.1-py3-none-any.whl", hash = "sha256:6c1bf74072f5bc01d688fe66835eca6e4bb1352368bf0c9c68292696455f457f"}, + {file = "hstspreload-2021.8.1.tar.gz", hash = "sha256:d51c2c2c183ec0001399b0473ffb200eb75451110b27897e65efd2fe1d70b9be"}, ] httpcore = [ {file = "httpcore-0.9.1-py3-none-any.whl", hash = "sha256:9850fe97a166a794d7e920590d5ec49a05488884c9fc8b5dba8561effab0c2a0"}, @@ -2004,8 +2037,8 @@ hyperframe = [ {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, ] hypothesis = [ - {file = "hypothesis-6.14.1-py3-none-any.whl", hash = "sha256:6dad44da8962cc7c13cdc28cf9b78c6779b5a0b0279a9baac427ae6d109f70e3"}, - {file = "hypothesis-6.14.1.tar.gz", hash = "sha256:88b0736a5691b68b8e16a4b7ee8e4c8596810c5a20989ea5b5f64870a7c25740"}, + {file = "hypothesis-6.14.5-py3-none-any.whl", hash = "sha256:cc4efbce2446fa6f04ce55bb20d53dcfef9cf2187ec51332aac2c30306f537e2"}, + {file = "hypothesis-6.14.5.tar.gz", hash = "sha256:0563b9711fd9bf478cb591580a575c369d2c396f283efa85d0f9a75b26db65b5"}, ] hypothesis-auto = [ {file = "hypothesis-auto-1.1.4.tar.gz", hash = "sha256:5e2c2fb09dc09842512d80630bb792359a1d33d2c0473ad47ee23da0be9e32b1"}, @@ -2016,8 +2049,8 @@ hypothesmith = [ {file = "hypothesmith-0.1.8.tar.gz", hash = "sha256:f9ff047b15c4ed312ce3da57ea27570f86d6b53ce12af9f25e59e6576a00410a"}, ] identify = [ - {file = "identify-2.2.10-py2.py3-none-any.whl", hash = "sha256:18d0c531ee3dbc112fa6181f34faa179de3f57ea57ae2899754f16a7e0ff6421"}, - {file = "identify-2.2.10.tar.gz", hash = "sha256:5b41f71471bc738e7b586308c3fca172f78940195cb3bf6734c1e66fdac49306"}, + {file = "identify-2.2.11-py2.py3-none-any.whl", hash = "sha256:7abaecbb414e385752e8ce02d8c494f4fbc780c975074b46172598a28f1ab839"}, + {file = "identify-2.2.11.tar.gz", hash = "sha256:a0e700637abcbd1caae58e0463861250095dfe330a8371733a471af706a4a29a"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -2041,12 +2074,12 @@ immutables = [ {file = "immutables-0.15.tar.gz", hash = "sha256:3713ab1ebbb6946b7ce1387bb9d1d7f5e09c45add58c2a2ee65f963c171e746b"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.6.1-py3-none-any.whl", hash = "sha256:9f55f560e116f8643ecf2922d9cd3e1c7e8d52e683178fecd9d08f6aa357e11e"}, - {file = "importlib_metadata-4.6.1.tar.gz", hash = "sha256:079ada16b7fc30dfbb5d13399a5113110dab1aa7c2bc62f66af75f0b717c8cac"}, + {file = "importlib_metadata-4.6.3-py3-none-any.whl", hash = "sha256:51c6635429c77cf1ae634c997ff9e53ca3438b495f10a55ba28594dd69764a8b"}, + {file = "importlib_metadata-4.6.3.tar.gz", hash = "sha256:0645585859e9a6689c523927a5032f2ba5919f1f7d0e84bd4533312320de1ff9"}, ] importlib-resources = [ - {file = "importlib_resources-5.2.0-py3-none-any.whl", hash = "sha256:a0143290bef3cbc99de9e40176e4987780939a955b8632f02ce6c935f42e9bfc"}, - {file = "importlib_resources-5.2.0.tar.gz", hash = "sha256:22a2c42d8c6a1d30aa8a0e1f57293725bfd5c013d562585e46aff469e0ff78b3"}, + {file = "importlib_resources-5.2.2-py3-none-any.whl", hash = "sha256:2480d8e07d1890056cb53c96e3de44fead9c62f2ba949b0f2e4c4345f4afa977"}, + {file = "importlib_resources-5.2.2.tar.gz", hash = "sha256:a65882a4d0fe5fbf702273456ba2ce74fe44892c25e42e057aca526b702a6d4b"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -2135,12 +2168,12 @@ mergedeep = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] mkdocs = [ - {file = "mkdocs-1.2.1-py3-none-any.whl", hash = "sha256:11141126e5896dd9d279b3e4814eb488e409a0990fb638856255020406a8e2e7"}, - {file = "mkdocs-1.2.1.tar.gz", hash = "sha256:6e0ea175366e3a50d334597b0bc042b8cebd512398cdd3f6f34842d0ef524905"}, + {file = "mkdocs-1.2.2-py3-none-any.whl", hash = "sha256:d019ff8e17ec746afeb54eb9eb4112b5e959597aebc971da46a5c9486137f0ff"}, + {file = "mkdocs-1.2.2.tar.gz", hash = "sha256:a334f5bd98ec960638511366eb8c5abc9c99b9083a0ed2401d8791b112d6b078"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.1.9.tar.gz", hash = "sha256:5a2fd487f769f382a7c979e869e4eab1372af58d7dec44c4365dd97ef5268cb5"}, - {file = "mkdocs_material-7.1.9-py2.py3-none-any.whl", hash = "sha256:92c8a2bd3bd44d5948eefc46ba138e2d3285cac658900112b6bf5722c7d067a5"}, + {file = "mkdocs-material-7.2.2.tar.gz", hash = "sha256:4f501e139e2f8546653e7d8777c9b97ca639d03d8c86345a60609864cc5bbb03"}, + {file = "mkdocs_material-7.2.2-py2.py3-none-any.whl", hash = "sha256:76de22213f0e0319b9bddf1bfa86530e93efb4a604e9ddf8f8419f0438572523"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.1.tar.gz", hash = "sha256:6947fb7f5e4291e3c61405bad3539d81e0b3cd62ae0d66ced018128af509c68f"}, @@ -2232,8 +2265,8 @@ parso = [ {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, ] pathspec = [ - {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, - {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] pbr = [ {file = "pbr-5.6.0-py2.py3-none-any.whl", hash = "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"}, @@ -2244,8 +2277,8 @@ pdocs = [ {file = "pdocs-1.1.1.tar.gz", hash = "sha256:f148034970220c9e05d2e04d8eb3fcec3575cf480af0966123ef9d6621b46e4f"}, ] pep517 = [ - {file = "pep517-0.10.0-py2.py3-none-any.whl", hash = "sha256:eba39d201ef937584ad3343df3581069085bacc95454c80188291d5b3ac7a249"}, - {file = "pep517-0.10.0.tar.gz", hash = "sha256:ac59f3f6b9726a49e15a649474539442cf76e0697e39df4869d25e68e880931b"}, + {file = "pep517-0.11.0-py2.py3-none-any.whl", hash = "sha256:3fa6b85b9def7ba4de99fb7f96fe3f02e2d630df8aa2720a5cf3b183f087a738"}, + {file = "pep517-0.11.0.tar.gz", hash = "sha256:e1ba5dffa3a131387979a68ff3e391ac7d645be409216b961bc2efe6468ab0b2"}, ] pep8-naming = [ {file = "pep8-naming-0.8.2.tar.gz", hash = "sha256:01cb1dab2f3ce9045133d08449f1b6b93531dceacb9ef04f67087c11c723cea9"}, @@ -2274,6 +2307,10 @@ pipreqs = [ {file = "pipreqs-0.4.10-py2.py3-none-any.whl", hash = "sha256:cafe42ab70628d408c147fb8944bc303355ea8f91fddca4a98d273e572e39905"}, {file = "pipreqs-0.4.10.tar.gz", hash = "sha256:9e351d644b28b98d7386b046a73806cbb3bb66b23a30e74feeb95ed9571db939"}, ] +platformdirs = [ + {file = "platformdirs-2.2.0-py3-none-any.whl", hash = "sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c"}, + {file = "platformdirs-2.2.0.tar.gz", hash = "sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e"}, +] plette = [ {file = "plette-0.2.3-py2.py3-none-any.whl", hash = "sha256:d6c9b96981b347bddd333910b753b6091a2c1eb2ef85bb373b4a67c9d91dca16"}, {file = "plette-0.2.3.tar.gz", hash = "sha256:46402c03e36d6eadddad2a5125990e322dd74f98160c8f2dcd832b2291858a26"}, @@ -2378,8 +2415,8 @@ pytest-mock = [ {file = "pytest_mock-1.13.0-py2.py3-none-any.whl", hash = "sha256:67e414b3caef7bff6fc6bd83b22b5bc39147e4493f483c2679bc9d4dc485a94d"}, ] python-dateutil = [ - {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] python-slugify = [ {file = "python-slugify-5.0.2.tar.gz", hash = "sha256:f13383a0b9fcbe649a1892b9c8eb4f8eab1d6d84b84bb7a624317afa98159cab"}, @@ -2464,8 +2501,8 @@ regex = [ {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, ] requests = [ - {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, - {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, + {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, + {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, ] requirementslib = [ {file = "requirementslib-1.5.16-py2.py3-none-any.whl", hash = "sha256:50d20f27e4515a2393695b0d886219598302163438ae054253147b2bad9b4a44"}, @@ -2515,6 +2552,10 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-1.2.0-py3-none-any.whl", hash = "sha256:056f0376bf5a6b182c513f9582c1e5b0487265eb6c48842b69aa9ca1cd5f640a"}, + {file = "tomli-1.2.0.tar.gz", hash = "sha256:d60e681734099207a6add7a10326bc2ddd1fdc36c1b0f547d00ef73ac63739c2"}, +] tomlkit = [ {file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, {file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, @@ -2629,8 +2670,8 @@ urllib3 = [ {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, ] virtualenv = [ - {file = "virtualenv-20.4.7-py2.py3-none-any.whl", hash = "sha256:2b0126166ea7c9c3661f5b8e06773d28f83322de7a3ff7d06f0aed18c9de6a76"}, - {file = "virtualenv-20.4.7.tar.gz", hash = "sha256:14fdf849f80dbb29a4eb6caa9875d476ee2a5cf76a5f5415fa2f1606010ab467"}, + {file = "virtualenv-20.7.0-py2.py3-none-any.whl", hash = "sha256:fdfdaaf0979ac03ae7f76d5224a05b58165f3c804f8aa633f3dd6f22fbd435d5"}, + {file = "virtualenv-20.7.0.tar.gz", hash = "sha256:97066a978431ec096d163e72771df5357c5c898ffdd587048f45e0aecc228094"}, ] vistir = [ {file = "vistir-0.5.2-py2.py3-none-any.whl", hash = "sha256:a37079cdbd85d31a41cdd18457fe521e15ec08b255811e81aa061fd5f48a20fb"}, diff --git a/pyproject.toml b/pyproject.toml index 625f75061..8976a99dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,7 @@ bandit = "^1.6" safety = "^1.8" flake8-bugbear = "^19.8" black = {version = "^20.08b1", allow-prereleases = true} +coverage = {version = "^6.0b1", allow-prereleases = true} mypy = "^0.902" ipython = "^7.7" pytest = "^6.0" From 5e136e65a03b3d5a0413df5402184454deead230 Mon Sep 17 00:00:00 2001 From: Taneli Hukkinen <3275109+hukkin@users.noreply.github.com> Date: Mon, 2 Aug 2021 10:28:43 +0300 Subject: [PATCH 05/54] Fix deprecation warning from tomli --- isort/settings.py | 51 ++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/isort/settings.py b/isort/settings.py index 02006863f..67c4b7932 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -769,15 +769,16 @@ def _find_config(path: str) -> Tuple[str, Dict[str, Any]]: def _get_config_data(file_path: str, sections: Tuple[str]) -> Dict[str, Any]: settings: Dict[str, Any] = {} - with open(file_path, encoding="utf-8") as config_file: - if file_path.endswith(".toml"): - config = tomli.load(config_file) - for section in sections: - config_section = config - for key in section.split("."): - config_section = config_section.get(key, {}) - settings.update(config_section) - else: + if file_path.endswith(".toml"): + with open(file_path, "rb") as bin_config_file: + config = tomli.load(bin_config_file) + for section in sections: + config_section = config + for key in section.split("."): + config_section = config_section.get(key, {}) + settings.update(config_section) + else: + with open(file_path, encoding="utf-8") as config_file: if file_path.endswith(".editorconfig"): line = "\n" last_position = config_file.tell() @@ -790,22 +791,22 @@ def _get_config_data(file_path: str, sections: Tuple[str]) -> Dict[str, Any]: config = configparser.ConfigParser(strict=False) config.read_file(config_file) - for section in sections: - if section.startswith("*.{") and section.endswith("}"): - extension = section[len("*.{") : -1] - for config_key in config.keys(): - if ( - config_key.startswith("*.{") - and config_key.endswith("}") - and extension - in map( - lambda text: text.strip(), config_key[len("*.{") : -1].split(",") # type: ignore # noqa - ) - ): - settings.update(config.items(config_key)) - - elif config.has_section(section): - settings.update(config.items(section)) + for section in sections: + if section.startswith("*.{") and section.endswith("}"): + extension = section[len("*.{") : -1] + for config_key in config.keys(): + if ( + config_key.startswith("*.{") + and config_key.endswith("}") + and extension + in map( + lambda text: text.strip(), config_key[len("*.{") : -1].split(",") # type: ignore # noqa + ) + ): + settings.update(config.items(config_key)) + + elif config.has_section(section): + settings.update(config.items(section)) if settings: settings["source"] = file_path From c29c6d6c0eaa9ed987157593822e501e89ca02b1 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Fri, 6 Aug 2021 23:22:21 -0700 Subject: [PATCH 06/54] Add test case for issue #1799 --- tests/unit/test_regressions.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index 1853893ea..d1003e210 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -1869,3 +1869,33 @@ class Bar: ... ''' ) + + +def test_isort_should_produce_the_same_code_on_subsequent_runs_issue_1799(tmpdir): + code = """import sys + +if sys.version_info[:2] >= (3, 8): + # TODO: Import directly (no need for conditional) when `python_requires = >= 3.8` + from importlib.metadata import PackageNotFoundError, version # pragma: no cover +else: + from importlib_metadata import PackageNotFoundError, version # pragma: no cover +""" + config_file = tmpdir.join(".isort.cfg") + config_file.write( + """[isort] +profile=black +src_paths=isort,test +line_length=100 +skip=.tox,.venv,build,dist,docs,tests +extra_standard_library=pkg_resources,setuptools,typing +known_test=pytest +known_first_party=ibpt +sections=FUTURE,STDLIB,TEST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER +import_heading_firstparty=internal +import_heading_thirdparty=external +""" + ) + settings = isort.settings.Config(str(config_file)) + assert isort.code(code, config=settings) == isort.code( + isort.code(code, config=settings), config=settings + ) From 013fb7f73dc3e606802b0b1dc3aefa4c99caef9d Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Tue, 10 Aug 2021 22:26:47 -0700 Subject: [PATCH 07/54] Fixed #1801: CLI bug (--exend-skip-glob, overrides instead of extending). --- CHANGELOG.md | 1 + isort/main.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3096ae0e..a46c3a97b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/ ### 5.10.0 TBD - Implemented #1796: Switch to `tomli` for pyproject.toml configuration loader. + - Fixed #1801: CLI bug (--exend-skip-glob, overrides instead of extending). #### Potentially breaking changes: - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. diff --git a/isort/main.py b/isort/main.py index fc893a4f8..3a1e45df9 100644 --- a/isort/main.py +++ b/isort/main.py @@ -346,7 +346,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: target_group.add_argument( "--extend-skip-glob", help="Additional files that isort should skip over (extending --skip-glob).", - dest="skip_glob", + dest="extend_skip_glob", action="append", ) target_group.add_argument( From 9695fde58502ff072eb1d9486be3f12b0e66c052 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Tue, 10 Aug 2021 22:36:28 -0700 Subject: [PATCH 08/54] Regenerate the docs --- docs/configuration/options.md | 16 +++++++++------- isort/main.py | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/configuration/options.md b/docs/configuration/options.md index 47f034433..05536cabe 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -9,7 +9,7 @@ profiles](https://pycqa.github.io/isort/docs/configuration/profiles.html). ## Python Version -Tells isort to set the known standard library based on the specified Python version. Default is to assume any Python 3 version could be the target, and use a union of all stdlib modules across versions. If auto is specified, the version of the interpreter used to run isort (currently: 38) will be used. +Tells isort to set the known standard library based on the specified Python version. Default is to assume any Python 3 version could be the target, and use a union of all stdlib modules across versions. If auto is specified, the version of the interpreter used to run isort (currently: 39) will be used. **Type:** String **Default:** `py3` @@ -56,23 +56,26 @@ Extends --skip to add additional files that isort should skip over. If you want ## Skip Glob -Additional files that isort should skip over (extending --skip-glob). +Files that isort should skip over. **Type:** Frozenset **Default:** `frozenset()` **Python & Config File Name:** skip_glob **CLI Flags:** -- --extend-skip-glob +- --sg +- --skip-glob ## Extend Skip Glob -**No Description** +Additional files that isort should skip over (extending --skip-glob). **Type:** Frozenset **Default:** `frozenset()` **Python & Config File Name:** extend_skip_glob -**CLI Flags:** **Not Supported** +**CLI Flags:** + +- --extend-skip-glob ## Skip Gitignore @@ -199,7 +202,7 @@ Force isort to recognize a module as being a local folder. Generally, this is re Force isort to recognize a module as part of Python's standard library. **Type:** Frozenset -**Default:** `('_dummy_thread', '_thread', 'abc', 'aifc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins', 'bz2', 'cProfile', 'calendar', 'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', 'colorsys', 'compileall', 'concurrent', 'configparser', 'contextlib', 'contextvars', 'copy', 'copyreg', 'crypt', 'csv', 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm', 'decimal', 'difflib', 'dis', 'distutils', 'doctest', 'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fpectl', 'fractions', 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext', 'glob', 'graphlib', 'grp', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http', 'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io', 'ipaddress', 'itertools', 'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', 'macpath', 'mailbox', 'mailcap', 'marshal', 'math', 'mimetypes', 'mmap', 'modulefinder', 'msilib', 'msvcrt', 'multiprocessing', 'netrc', 'nis', 'nntplib', 'ntpath', 'numbers', 'operator', 'optparse', 'os', 'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil', 'platform', 'plistlib', 'poplib', 'posix', 'posixpath', 'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rlcompleter', 'runpy', 'sched', 'secrets', 'select', 'selectors', 'shelve', 'shlex', 'shutil', 'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver', 'spwd', 'sqlite3', 'sre', 'sre_compile', 'sre_constants', 'sre_parse', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct', 'subprocess', 'sunau', 'symbol', 'symtable', 'sys', 'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios', 'test', 'textwrap', 'threading', 'time', 'timeit', 'tkinter', 'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'tty', 'turtle', 'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'uu', 'uuid', 'venv', 'warnings', 'wave', 'weakref', 'webbrowser', 'winreg', 'winsound', 'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'zipapp', 'zipfile', 'zipimport', 'zlib', 'zoneinfo')` +**Default:** `('_ast', '_dummy_thread', '_thread', 'abc', 'aifc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins', 'bz2', 'cProfile', 'calendar', 'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', 'colorsys', 'compileall', 'concurrent', 'configparser', 'contextlib', 'contextvars', 'copy', 'copyreg', 'crypt', 'csv', 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm', 'decimal', 'difflib', 'dis', 'distutils', 'doctest', 'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fpectl', 'fractions', 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext', 'glob', 'graphlib', 'grp', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http', 'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io', 'ipaddress', 'itertools', 'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', 'macpath', 'mailbox', 'mailcap', 'marshal', 'math', 'mimetypes', 'mmap', 'modulefinder', 'msilib', 'msvcrt', 'multiprocessing', 'netrc', 'nis', 'nntplib', 'ntpath', 'numbers', 'operator', 'optparse', 'os', 'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil', 'platform', 'plistlib', 'poplib', 'posix', 'posixpath', 'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rlcompleter', 'runpy', 'sched', 'secrets', 'select', 'selectors', 'shelve', 'shlex', 'shutil', 'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver', 'spwd', 'sqlite3', 'sre', 'sre_compile', 'sre_constants', 'sre_parse', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct', 'subprocess', 'sunau', 'symbol', 'symtable', 'sys', 'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios', 'test', 'textwrap', 'threading', 'time', 'timeit', 'tkinter', 'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'tty', 'turtle', 'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'uu', 'uuid', 'venv', 'warnings', 'wave', 'weakref', 'webbrowser', 'winreg', 'winsound', 'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'zipapp', 'zipfile', 'zipimport', 'zlib', 'zoneinfo')` **Python & Config File Name:** known_standard_library **CLI Flags:** @@ -796,7 +799,6 @@ Tells isort to honor noqa comments to enforce skipping those comments. Add an explicitly defined source path (modules within src paths have their imports automatically categorized as first_party). Glob expansion (`*` and `**`) is supported for this option. - **Type:** Tuple **Default:** `()` **Python & Config File Name:** src_paths diff --git a/isort/main.py b/isort/main.py index 3a1e45df9..dd938ed4b 100644 --- a/isort/main.py +++ b/isort/main.py @@ -778,7 +778,8 @@ def _build_arg_parser() -> argparse.ArgumentParser: dest="src_paths", action="append", help="Add an explicitly defined source path " - "(modules within src paths have their imports automatically categorized as first_party).", + "(modules within src paths have their imports automatically categorized as first_party)." + " Glob expansion (`*` and `**`) is supported for this option.", ) section_group.add_argument( "-b", From b06a000a730e5b7036bc1eef3c760f2df9359353 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Wed, 11 Aug 2021 22:47:44 -0700 Subject: [PATCH 09/54] Fixed #1802: respect PATH customization in nested calls to git. --- CHANGELOG.md | 1 + isort/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a46c3a97b..ec707da8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/ ### 5.10.0 TBD - Implemented #1796: Switch to `tomli` for pyproject.toml configuration loader. - Fixed #1801: CLI bug (--exend-skip-glob, overrides instead of extending). + - Fixed #1802: respect PATH customization in nested calls to git. #### Potentially breaking changes: - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. diff --git a/isort/settings.py b/isort/settings.py index 67c4b7932..3752b6336 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -538,7 +538,7 @@ def is_supported_filetype(self, file_name: str) -> bool: return bool(_SHEBANG_RE.match(line)) def _check_folder_gitignore(self, folder: str) -> Optional[Path]: - env = {"LANG": "C.UTF-8"} + env = {**os.environ, "LANG": "C.UTF-8"} try: topfolder_result = subprocess.check_output( # nosec # skipcq: PYL-W1510 ["git", "-C", folder, "rev-parse", "--show-toplevel"], encoding="utf-8", env=env From e67e474388f4b964579f4383b62ce18afff19f63 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Thu, 12 Aug 2021 23:32:55 -0700 Subject: [PATCH 10/54] Force static version of mkdocs since new versions change output structure and break URLs. Closes #1803 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 8976a99dc..d73824dbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ hypothesmith = "^0.1.3" examples = { version = "^1.0.0" } cruft = { version = "^2.2" } portray = { version = "^1.6.0" } +mkdocs = { version = "1.2.1" } pipfile = "^0.0.2" requirementslib = "^1.5" pipreqs = "^0.4.9" From b0007e703a67d0939a4fd123fe594ee04a7a03e5 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Thu, 12 Aug 2021 23:33:00 -0700 Subject: [PATCH 11/54] Update lock file --- poetry.lock | 189 +++++++++++++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 91 deletions(-) diff --git a/poetry.lock b/poetry.lock index d76a9b231..4315dfb1f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -532,7 +532,7 @@ python-versions = "*" [[package]] name = "hypothesis" -version = "6.14.5" +version = "6.14.6" description = "A library for property-based testing" category = "dev" optional = false @@ -588,7 +588,7 @@ libcst = ">=0.3.8" [[package]] name = "identify" -version = "2.2.11" +version = "2.2.13" description = "File identification library for Python" category = "dev" optional = false @@ -607,14 +607,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "immutables" -version = "0.15" +version = "0.16" description = "Immutable Collections" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [package.extras] -test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)"] +test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (>=0.910)", "pytest (>=6.2.4,<6.3.0)"] [[package]] name = "importlib-metadata" @@ -751,7 +754,7 @@ regex = ["regex"] [[package]] name = "libcst" -version = "0.3.19" +version = "0.3.20" description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7 and 3.8 programs." category = "dev" optional = false @@ -833,7 +836,7 @@ python-versions = ">=3.6" [[package]] name = "mkdocs" -version = "1.2.2" +version = "1.2.1" description = "Project documentation with Markdown." category = "dev" optional = false @@ -856,7 +859,7 @@ i18n = ["babel (>=2.9.0)"] [[package]] name = "mkdocs-material" -version = "7.2.2" +version = "7.2.3" description = "A Material Design theme for MkDocs" category = "dev" optional = false @@ -1161,7 +1164,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pre-commit" -version = "2.13.0" +version = "2.14.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false @@ -1414,7 +1417,7 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.7.6" +version = "2021.8.3" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -1576,7 +1579,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.2.0" +version = "1.2.1" description = "A lil' TOML parser" category = "main" optional = false @@ -1641,7 +1644,7 @@ doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown- [[package]] name = "types-colorama" -version = "0.4.2" +version = "0.4.3" description = "Typing stubs for colorama" category = "dev" optional = false @@ -1657,7 +1660,7 @@ python-versions = "*" [[package]] name = "types-toml" -version = "0.1.3" +version = "0.1.5" description = "Typing stubs for toml" category = "dev" optional = false @@ -1698,7 +1701,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.7.0" +version = "20.7.2" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1803,7 +1806,7 @@ requirements_deprecated_finder = ["pipreqs", "pip-api"] [metadata] lock-version = "1.1" python-versions = ">=3.6.1,<4.0" -content-hash = "982204115a3093f1615a240a7b46887dc273fb86e973d8029e75c1aefc15fa04" +content-hash = "89953225da137cf01f6889cc2c4e6f44e0aea847dda012968864cbabd904db14" [metadata.files] appdirs = [ @@ -2037,8 +2040,8 @@ hyperframe = [ {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, ] hypothesis = [ - {file = "hypothesis-6.14.5-py3-none-any.whl", hash = "sha256:cc4efbce2446fa6f04ce55bb20d53dcfef9cf2187ec51332aac2c30306f537e2"}, - {file = "hypothesis-6.14.5.tar.gz", hash = "sha256:0563b9711fd9bf478cb591580a575c369d2c396f283efa85d0f9a75b26db65b5"}, + {file = "hypothesis-6.14.6-py3-none-any.whl", hash = "sha256:a776b4545e8ad54c68f001591cd5c39c8c05dfd340d0cf974112bf89439f126b"}, + {file = "hypothesis-6.14.6.tar.gz", hash = "sha256:2586eae07e48b35ab5a2d61d607d29ba76939ce140c427d66ccf5db4ddc788d2"}, ] hypothesis-auto = [ {file = "hypothesis-auto-1.1.4.tar.gz", hash = "sha256:5e2c2fb09dc09842512d80630bb792359a1d33d2c0473ad47ee23da0be9e32b1"}, @@ -2049,29 +2052,41 @@ hypothesmith = [ {file = "hypothesmith-0.1.8.tar.gz", hash = "sha256:f9ff047b15c4ed312ce3da57ea27570f86d6b53ce12af9f25e59e6576a00410a"}, ] identify = [ - {file = "identify-2.2.11-py2.py3-none-any.whl", hash = "sha256:7abaecbb414e385752e8ce02d8c494f4fbc780c975074b46172598a28f1ab839"}, - {file = "identify-2.2.11.tar.gz", hash = "sha256:a0e700637abcbd1caae58e0463861250095dfe330a8371733a471af706a4a29a"}, + {file = "identify-2.2.13-py2.py3-none-any.whl", hash = "sha256:7199679b5be13a6b40e6e19ea473e789b11b4e3b60986499b1f589ffb03c217c"}, + {file = "identify-2.2.13.tar.gz", hash = "sha256:7bc6e829392bd017236531963d2d937d66fc27cadc643ac0aba2ce9f26157c79"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] immutables = [ - {file = "immutables-0.15-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:6728f4392e3e8e64b593a5a0cd910a1278f07f879795517e09f308daed138631"}, - {file = "immutables-0.15-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f0836cd3bdc37c8a77b192bbe5f41dbcc3ce654db048ebbba89bdfe6db7a1c7a"}, - {file = "immutables-0.15-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8703d8abfd8687932f2a05f38e7de270c3a6ca3bd1c1efb3c938656b3f2f985a"}, - {file = "immutables-0.15-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b8ad986f9b532c026f19585289384b0769188fcb68b37c7f0bd0df9092a6ca54"}, - {file = "immutables-0.15-cp36-cp36m-win_amd64.whl", hash = "sha256:6f117d9206165b9dab8fd81c5129db757d1a044953f438654236ed9a7a4224ae"}, - {file = "immutables-0.15-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b75ade826920c4e490b1bb14cf967ac14e61eb7c5562161c5d7337d61962c226"}, - {file = "immutables-0.15-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b7e13c061785e34f73c4f659861f1b3e4a5fd918e4395c84b21c4e3d449ebe27"}, - {file = "immutables-0.15-cp37-cp37m-win_amd64.whl", hash = "sha256:3035849accee4f4e510ed7c94366a40e0f5fef9069fbe04a35f4787b13610a4a"}, - {file = "immutables-0.15-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:b04fa69174e0c8f815f9c55f2a43fc9e5a68452fab459a08e904a74e8471639f"}, - {file = "immutables-0.15-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:141c2e9ea515a3a815007a429f0b47a578ebeb42c831edaec882a245a35fffca"}, - {file = "immutables-0.15-cp38-cp38-win_amd64.whl", hash = "sha256:cbe8c64640637faa5535d539421b293327f119c31507c33ca880bd4f16035eb6"}, - {file = "immutables-0.15-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a0a4e4417d5ef4812d7f99470cd39347b58cb927365dd2b8da9161040d260db0"}, - {file = "immutables-0.15-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3b15c08c71c59e5b7c2470ef949d49ff9f4263bb77f488422eaa157da84d6999"}, - {file = "immutables-0.15-cp39-cp39-win_amd64.whl", hash = "sha256:2283a93c151566e6830aee0e5bee55fc273455503b43aa004356b50f9182092b"}, - {file = "immutables-0.15.tar.gz", hash = "sha256:3713ab1ebbb6946b7ce1387bb9d1d7f5e09c45add58c2a2ee65f963c171e746b"}, + {file = "immutables-0.16-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:acbfa79d44228d96296279068441f980dc63dbed52522d9227ff9f4d96c6627e"}, + {file = "immutables-0.16-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c9ed003eacb92e630ef200e31f47236c2139b39476894f7963b32bd39bafa3"}, + {file = "immutables-0.16-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a396314b9024fa55bf83a27813fd76cf9f27dce51f53b0f19b51de035146251"}, + {file = "immutables-0.16-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4a2a71678348fb95b13ca108d447f559a754c41b47bd1e7e4fb23974e735682d"}, + {file = "immutables-0.16-cp36-cp36m-win32.whl", hash = "sha256:064001638ab5d36f6aa05b6101446f4a5793fb71e522bc81b8fc65a1894266ff"}, + {file = "immutables-0.16-cp36-cp36m-win_amd64.whl", hash = "sha256:1de393f1b188740ca7b38f946f2bbc7edf3910d2048f03bbb8d01f17a038d67c"}, + {file = "immutables-0.16-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fcf678a3074613119385a02a07c469ec5130559f5ea843c85a0840c80b5b71c6"}, + {file = "immutables-0.16-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a307eb0984eb43e815dcacea3ac50c11d00a936ecf694c46991cd5a23bcb0ec0"}, + {file = "immutables-0.16-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7a58825ff2254e2612c5a932174398a4ea8fbddd8a64a02c880cc32ee28b8820"}, + {file = "immutables-0.16-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:798b095381eb42cf40db6876339e7bed84093e5868018a9e73d8e1f7ab4bb21e"}, + {file = "immutables-0.16-cp37-cp37m-win32.whl", hash = "sha256:19bdede174847c2ef1292df0f23868ab3918b560febb09fcac6eec621bd4812b"}, + {file = "immutables-0.16-cp37-cp37m-win_amd64.whl", hash = "sha256:9ccf4c0e3e2e3237012b516c74c49de8872ccdf9129739f7a0b9d7444a8c4862"}, + {file = "immutables-0.16-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d59beef203a3765db72b1d0943547425c8318ecf7d64c451fd1e130b653c2fbb"}, + {file = "immutables-0.16-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0020aaa4010b136056c20a46ce53204e1407a9e4464246cb2cf95b90808d9161"}, + {file = "immutables-0.16-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edd9f67671555af1eb99ad3c7550238487dd7ac0ac5205b40204ed61c9a922ac"}, + {file = "immutables-0.16-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:298a301f85f307b4c056a0825eb30f060e64d73605e783289f3df37dd762bab8"}, + {file = "immutables-0.16-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b779617f5b94486bfd0f22162cd72eb5f2beb0214a14b75fdafb7b2c908ed0cb"}, + {file = "immutables-0.16-cp38-cp38-win32.whl", hash = "sha256:511c93d8b1bbbf103ff3f1f120c5a68a9866ce03dea6ac406537f93ca9b19139"}, + {file = "immutables-0.16-cp38-cp38-win_amd64.whl", hash = "sha256:b651b61c1af6cda2ee201450f2ffe048a5959bc88e43e6c312f4c93e69c9e929"}, + {file = "immutables-0.16-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:aa7bf572ae1e006104c584be70dc634849cf0dc62f42f4ee194774f97e7fd17d"}, + {file = "immutables-0.16-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50793a44ba0d228ed8cad4d0925e00dfd62ea32f44ddee8854f8066447272d05"}, + {file = "immutables-0.16-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:799621dcdcdcbb2516546a40123b87bf88de75fe7459f7bd8144f079ace6ec3e"}, + {file = "immutables-0.16-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7bcf52aeb983bd803b7c6106eae1b2d9a0c7ab1241bc6b45e2174ba2b7283031"}, + {file = "immutables-0.16-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:734c269e82e5f307fb6e17945953b67659d1731e65309787b8f7ba267d1468f2"}, + {file = "immutables-0.16-cp39-cp39-win32.whl", hash = "sha256:a454d5d3fee4b7cc627345791eb2ca4b27fa3bbb062ccf362ecaaa51679a07ed"}, + {file = "immutables-0.16-cp39-cp39-win_amd64.whl", hash = "sha256:2505d93395d3f8ae4223e21465994c3bc6952015a38dc4f03cb3e07a2b8d8325"}, + {file = "immutables-0.16.tar.gz", hash = "sha256:d67e86859598eed0d926562da33325dac7767b7b1eff84e232c22abea19f4360"}, ] importlib-metadata = [ {file = "importlib_metadata-4.6.3-py3-none-any.whl", hash = "sha256:51c6635429c77cf1ae634c997ff9e53ca3438b495f10a55ba28594dd69764a8b"}, @@ -2109,8 +2124,8 @@ lark-parser = [ {file = "lark-parser-0.11.3.tar.gz", hash = "sha256:e29ca814a98bb0f81674617d878e5f611cb993c19ea47f22c80da3569425f9bd"}, ] libcst = [ - {file = "libcst-0.3.19-py3-none-any.whl", hash = "sha256:9e26313ded6e17605658b93319299bce43cc8d7e24dafc12d6f782f758a3faf4"}, - {file = "libcst-0.3.19.tar.gz", hash = "sha256:4876239db55164acaf034ee01f56a7db0a2f90cacea24b183d8aa69efc11b067"}, + {file = "libcst-0.3.20-py3-none-any.whl", hash = "sha256:d213e833fdbad43c4fcaf9c952a695b36d601dce1c527ec724e75aa36e60834f"}, + {file = "libcst-0.3.20.tar.gz", hash = "sha256:9d50d4eab28b570e254cc63287ce3009b945be4114c7a29662b67204cfc18060"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, @@ -2168,12 +2183,12 @@ mergedeep = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] mkdocs = [ - {file = "mkdocs-1.2.2-py3-none-any.whl", hash = "sha256:d019ff8e17ec746afeb54eb9eb4112b5e959597aebc971da46a5c9486137f0ff"}, - {file = "mkdocs-1.2.2.tar.gz", hash = "sha256:a334f5bd98ec960638511366eb8c5abc9c99b9083a0ed2401d8791b112d6b078"}, + {file = "mkdocs-1.2.1-py3-none-any.whl", hash = "sha256:11141126e5896dd9d279b3e4814eb488e409a0990fb638856255020406a8e2e7"}, + {file = "mkdocs-1.2.1.tar.gz", hash = "sha256:6e0ea175366e3a50d334597b0bc042b8cebd512398cdd3f6f34842d0ef524905"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.2.2.tar.gz", hash = "sha256:4f501e139e2f8546653e7d8777c9b97ca639d03d8c86345a60609864cc5bbb03"}, - {file = "mkdocs_material-7.2.2-py2.py3-none-any.whl", hash = "sha256:76de22213f0e0319b9bddf1bfa86530e93efb4a604e9ddf8f8419f0438572523"}, + {file = "mkdocs-material-7.2.3.tar.gz", hash = "sha256:688f0162e7356aa5d019cf687851f5b24c7002886bd939b8159595cc16966edf"}, + {file = "mkdocs_material-7.2.3-py2.py3-none-any.whl", hash = "sha256:039ce80555ba457faa10af993c57e9b6469918c6a5427851dcdd65591cc47fac"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.1.tar.gz", hash = "sha256:6947fb7f5e4291e3c61405bad3539d81e0b3cd62ae0d66ced018128af509c68f"}, @@ -2328,8 +2343,8 @@ poyo = [ {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"}, ] pre-commit = [ - {file = "pre_commit-2.13.0-py2.py3-none-any.whl", hash = "sha256:b679d0fddd5b9d6d98783ae5f10fd0c4c59954f375b70a58cbe1ce9bcf9809a4"}, - {file = "pre_commit-2.13.0.tar.gz", hash = "sha256:764972c60693dc668ba8e86eb29654ec3144501310f7198742a767bec385a378"}, + {file = "pre_commit-2.14.0-py2.py3-none-any.whl", hash = "sha256:ec3045ae62e1aa2eecfb8e86fa3025c2e3698f77394ef8d2011ce0aedd85b2d4"}, + {file = "pre_commit-2.14.0.tar.gz", hash = "sha256:2386eeb4cf6633712c7cc9ede83684d53c8cafca6b59f79c738098b51c6d206c"}, ] prompt-toolkit = [ {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, @@ -2458,47 +2473,39 @@ pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ccb3d2190476d00414aab36cca453e4596e8f70a206e2aa8db3d495a109153d2"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ed693137a9187052fc46eedfafdcb74e09917166362af4cc4fddc3b31560e93d"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99d8ab206a5270c1002bfcf25c51bf329ca951e5a169f3b43214fdda1f0b5f0d"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b85ac458354165405c8a84725de7bbd07b00d9f72c31a60ffbf96bb38d3e25fa"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:3f5716923d3d0bfb27048242a6e0f14eecdb2e2a7fac47eda1d055288595f222"}, - {file = "regex-2021.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5983c19d0beb6af88cb4d47afb92d96751fb3fa1784d8785b1cdf14c6519407"}, - {file = "regex-2021.7.6-cp36-cp36m-win32.whl", hash = "sha256:c92831dac113a6e0ab28bc98f33781383fe294df1a2c3dfd1e850114da35fd5b"}, - {file = "regex-2021.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:791aa1b300e5b6e5d597c37c346fb4d66422178566bbb426dd87eaae475053fb"}, - {file = "regex-2021.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:59506c6e8bd9306cd8a41511e32d16d5d1194110b8cfe5a11d102d8b63cf945d"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:564a4c8a29435d1f2256ba247a0315325ea63335508ad8ed938a4f14c4116a5d"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:59c00bb8dd8775473cbfb967925ad2c3ecc8886b3b2d0c90a8e2707e06c743f0"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9a854b916806c7e3b40e6616ac9e85d3cdb7649d9e6590653deb5b341a736cec"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:db2b7df831c3187a37f3bb80ec095f249fa276dbe09abd3d35297fc250385694"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:173bc44ff95bc1e96398c38f3629d86fa72e539c79900283afa895694229fe6a"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:15dddb19823f5147e7517bb12635b3c82e6f2a3a6b696cc3e321522e8b9308ad"}, - {file = "regex-2021.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ddeabc7652024803666ea09f32dd1ed40a0579b6fbb2a213eba590683025895"}, - {file = "regex-2021.7.6-cp37-cp37m-win32.whl", hash = "sha256:f080248b3e029d052bf74a897b9d74cfb7643537fbde97fe8225a6467fb559b5"}, - {file = "regex-2021.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:d8bbce0c96462dbceaa7ac4a7dfbbee92745b801b24bce10a98d2f2b1ea9432f"}, - {file = "regex-2021.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edd1a68f79b89b0c57339bce297ad5d5ffcc6ae7e1afdb10f1947706ed066c9c"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:422dec1e7cbb2efbbe50e3f1de36b82906def93ed48da12d1714cabcd993d7f0"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cbe23b323988a04c3e5b0c387fe3f8f363bf06c0680daf775875d979e376bd26"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0eb2c6e0fcec5e0f1d3bcc1133556563222a2ffd2211945d7b1480c1b1a42a6f"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1c78780bf46d620ff4fff40728f98b8afd8b8e35c3efd638c7df67be2d5cddbf"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:bc84fb254a875a9f66616ed4538542fb7965db6356f3df571d783f7c8d256edd"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:598c0a79b4b851b922f504f9f39a863d83ebdfff787261a5ed061c21e67dd761"}, - {file = "regex-2021.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875c355360d0f8d3d827e462b29ea7682bf52327d500a4f837e934e9e4656068"}, - {file = "regex-2021.7.6-cp38-cp38-win32.whl", hash = "sha256:e586f448df2bbc37dfadccdb7ccd125c62b4348cb90c10840d695592aa1b29e0"}, - {file = "regex-2021.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:2fe5e71e11a54e3355fa272137d521a40aace5d937d08b494bed4529964c19c4"}, - {file = "regex-2021.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6110bab7eab6566492618540c70edd4d2a18f40ca1d51d704f1d81c52d245026"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4f64fc59fd5b10557f6cd0937e1597af022ad9b27d454e182485f1db3008f417"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:89e5528803566af4df368df2d6f503c84fbfb8249e6631c7b025fe23e6bd0cde"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2366fe0479ca0e9afa534174faa2beae87847d208d457d200183f28c74eaea59"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f9392a4555f3e4cb45310a65b403d86b589adc773898c25a39184b1ba4db8985"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:2bceeb491b38225b1fee4517107b8491ba54fba77cf22a12e996d96a3c55613d"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:f98dc35ab9a749276f1a4a38ab3e0e2ba1662ce710f6530f5b0a6656f1c32b58"}, - {file = "regex-2021.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319eb2a8d0888fa6f1d9177705f341bc9455a2c8aca130016e52c7fe8d6c37a3"}, - {file = "regex-2021.7.6-cp39-cp39-win32.whl", hash = "sha256:eaf58b9e30e0e546cdc3ac06cf9165a1ca5b3de8221e9df679416ca667972035"}, - {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, - {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, + {file = "regex-2021.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8764a78c5464ac6bde91a8c87dd718c27c1cabb7ed2b4beaf36d3e8e390567f9"}, + {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4551728b767f35f86b8e5ec19a363df87450c7376d7419c3cac5b9ceb4bce576"}, + {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:577737ec3d4c195c4aef01b757905779a9e9aee608fa1cf0aec16b5576c893d3"}, + {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c856ec9b42e5af4fe2d8e75970fcc3a2c15925cbcc6e7a9bcb44583b10b95e80"}, + {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3835de96524a7b6869a6c710b26c90e94558c31006e96ca3cf6af6751b27dca1"}, + {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cea56288eeda8b7511d507bbe7790d89ae7049daa5f51ae31a35ae3c05408531"}, + {file = "regex-2021.8.3-cp36-cp36m-win32.whl", hash = "sha256:a4eddbe2a715b2dd3849afbdeacf1cc283160b24e09baf64fa5675f51940419d"}, + {file = "regex-2021.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:57fece29f7cc55d882fe282d9de52f2f522bb85290555b49394102f3621751ee"}, + {file = "regex-2021.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a5c6dbe09aff091adfa8c7cfc1a0e83fdb8021ddb2c183512775a14f1435fe16"}, + {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff4a8ad9638b7ca52313d8732f37ecd5fd3c8e3aff10a8ccb93176fd5b3812f6"}, + {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b63e3571b24a7959017573b6455e05b675050bbbea69408f35f3cb984ec54363"}, + {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fbc20975eee093efa2071de80df7f972b7b35e560b213aafabcec7c0bd00bd8c"}, + {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14caacd1853e40103f59571f169704367e79fb78fac3d6d09ac84d9197cadd16"}, + {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb350eb1060591d8e89d6bac4713d41006cd4d479f5e11db334a48ff8999512f"}, + {file = "regex-2021.8.3-cp37-cp37m-win32.whl", hash = "sha256:18fdc51458abc0a974822333bd3a932d4e06ba2a3243e9a1da305668bd62ec6d"}, + {file = "regex-2021.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:026beb631097a4a3def7299aa5825e05e057de3c6d72b139c37813bfa351274b"}, + {file = "regex-2021.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:16d9eaa8c7e91537516c20da37db975f09ac2e7772a0694b245076c6d68f85da"}, + {file = "regex-2021.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3905c86cc4ab6d71635d6419a6f8d972cab7c634539bba6053c47354fd04452c"}, + {file = "regex-2021.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937b20955806381e08e54bd9d71f83276d1f883264808521b70b33d98e4dec5d"}, + {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:28e8af338240b6f39713a34e337c3813047896ace09d51593d6907c66c0708ba"}, + {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c09d88a07483231119f5017904db8f60ad67906efac3f1baa31b9b7f7cca281"}, + {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:85f568892422a0e96235eb8ea6c5a41c8ccbf55576a2260c0160800dbd7c4f20"}, + {file = "regex-2021.8.3-cp38-cp38-win32.whl", hash = "sha256:bf6d987edd4a44dd2fa2723fca2790f9442ae4de2c8438e53fcb1befdf5d823a"}, + {file = "regex-2021.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:8fe58d9f6e3d1abf690174fd75800fda9bdc23d2a287e77758dc0e8567e38ce6"}, + {file = "regex-2021.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7976d410e42be9ae7458c1816a416218364e06e162b82e42f7060737e711d9ce"}, + {file = "regex-2021.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9569da9e78f0947b249370cb8fadf1015a193c359e7e442ac9ecc585d937f08d"}, + {file = "regex-2021.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459bbe342c5b2dec5c5223e7c363f291558bc27982ef39ffd6569e8c082bdc83"}, + {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f421e3cdd3a273bace013751c345f4ebeef08f05e8c10757533ada360b51a39"}, + {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea212df6e5d3f60341aef46401d32fcfded85593af1d82b8b4a7a68cd67fdd6b"}, + {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a3b73390511edd2db2d34ff09aa0b2c08be974c71b4c0505b4a048d5dc128c2b"}, + {file = "regex-2021.8.3-cp39-cp39-win32.whl", hash = "sha256:f35567470ee6dbfb946f069ed5f5615b40edcbb5f1e6e1d3d2b114468d505fc6"}, + {file = "regex-2021.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:bfa6a679410b394600eafd16336b2ce8de43e9b13f7fb9247d84ef5ad2b45e91"}, + {file = "regex-2021.8.3.tar.gz", hash = "sha256:8935937dad2c9b369c3d932b0edbc52a62647c2afb2fafc0c280f14a8bf56a6a"}, ] requests = [ {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, @@ -2553,8 +2560,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomli = [ - {file = "tomli-1.2.0-py3-none-any.whl", hash = "sha256:056f0376bf5a6b182c513f9582c1e5b0487265eb6c48842b69aa9ca1cd5f640a"}, - {file = "tomli-1.2.0.tar.gz", hash = "sha256:d60e681734099207a6add7a10326bc2ddd1fdc36c1b0f547d00ef73ac63739c2"}, + {file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"}, + {file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"}, ] tomlkit = [ {file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, @@ -2644,16 +2651,16 @@ typer = [ {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, ] types-colorama = [ - {file = "types-colorama-0.4.2.tar.gz", hash = "sha256:ae4f7fcb533e529c182b934423b0c589452ec8b3470430b2ee7baf06cb7f4a8d"}, - {file = "types_colorama-0.4.2-py2.py3-none-any.whl", hash = "sha256:42bd280fad509c698e1485f9658493076d315d189a5014be843dffee2d264902"}, + {file = "types-colorama-0.4.3.tar.gz", hash = "sha256:3b2c7877878f2ba8cd1c2b3da524158f718c10e2fe046f91948b43459b69dc6a"}, + {file = "types_colorama-0.4.3-py3-none-any.whl", hash = "sha256:3cdd76e8080a146d55b7281b352a4330be6d7ba91217d28c7e3a50dc433d4b89"}, ] types-pkg-resources = [ {file = "types-pkg_resources-0.1.3.tar.gz", hash = "sha256:834a9b8d3dbea343562fd99d5d3359a726f6bf9d3733bccd2b4f3096fbab9dae"}, {file = "types_pkg_resources-0.1.3-py2.py3-none-any.whl", hash = "sha256:0cb9972cee992249f93fff1a491bf2dc3ce674e5a1926e27d4f0866f7d9b6d9c"}, ] types-toml = [ - {file = "types-toml-0.1.3.tar.gz", hash = "sha256:33ebe67bebaec55a123ecbaa2bd98fe588335d8d8dda2c7ac53502ef5a81a79a"}, - {file = "types_toml-0.1.3-py2.py3-none-any.whl", hash = "sha256:d4add39a90993173d49ff0b069edd122c66ad4cf5c01082b590e380ca670ee1a"}, + {file = "types-toml-0.1.5.tar.gz", hash = "sha256:fc5e1df92c245404e4360c63568e9f0e732b0cabea7a220a4788d52b78f5dc59"}, + {file = "types_toml-0.1.5-py3-none-any.whl", hash = "sha256:dd00526680595aad0eade682bd8a9e9513e9b4b8932daed159925fe446fc90a9"}, ] typing-extensions = [ {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, @@ -2670,8 +2677,8 @@ urllib3 = [ {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, ] virtualenv = [ - {file = "virtualenv-20.7.0-py2.py3-none-any.whl", hash = "sha256:fdfdaaf0979ac03ae7f76d5224a05b58165f3c804f8aa633f3dd6f22fbd435d5"}, - {file = "virtualenv-20.7.0.tar.gz", hash = "sha256:97066a978431ec096d163e72771df5357c5c898ffdd587048f45e0aecc228094"}, + {file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"}, + {file = "virtualenv-20.7.2.tar.gz", hash = "sha256:9ef4e8ee4710826e98ff3075c9a4739e2cb1040de6a2a8d35db0055840dc96a0"}, ] vistir = [ {file = "vistir-0.5.2-py2.py3-none-any.whl", hash = "sha256:a37079cdbd85d31a41cdd18457fe521e15ec08b255811e81aa061fd5f48a20fb"}, From dff5e9105320ae39cbce4f375ef33803d0f3a593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@iki.fi> Date: Mon, 16 Aug 2021 23:46:26 +0300 Subject: [PATCH 12/54] Spelling fixes --- Dockerfile | 2 +- docs/configuration/options.md | 2 +- docs/configuration/pre-commit.md | 2 +- docs/contributing/1.-contributing-guide.md | 2 +- isort/_future/_dataclasses.py | 6 +++--- isort/hooks.py | 2 +- isort/main.py | 2 +- isort/pylama_isort.py | 4 ++-- tests/unit/test_deprecated_finders.py | 4 ++-- tests/unit/test_format.py | 2 +- tests/unit/test_regressions.py | 2 +- tests/unit/utils.py | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9c2d8ac62..e2c0d0073 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM python:$VERSION # Install pip and poetry RUN python -m pip install --upgrade pip && python -m pip install poetry -# Setup as minimal a stub project as posible, simply to allow caching base dependencies +# Setup as minimal a stub project as possible, simply to allow caching base dependencies # between builds. # # If error is encountered in these steps, can safely be removed locally. diff --git a/docs/configuration/options.md b/docs/configuration/options.md index 05536cabe..a1e1b953f 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -80,7 +80,7 @@ Additional files that isort should skip over (extending --skip-glob). ## Skip Gitignore Treat project as a git repository and ignore files listed in .gitignore. -NOTE: This requires git to be installed and accesible from the same shell as isort. +NOTE: This requires git to be installed and accessible from the same shell as isort. **Type:** Bool **Default:** `False` diff --git a/docs/configuration/pre-commit.md b/docs/configuration/pre-commit.md index be495d2d7..19362f816 100644 --- a/docs/configuration/pre-commit.md +++ b/docs/configuration/pre-commit.md @@ -26,7 +26,7 @@ under the `repos` section of your projects `.pre-commit-config.yaml` file. ### seed-isort-config Older versions of isort used a lot of magic to determine import placement, that could easily break when running on CI/CD. -To fix this, a utilitiy called `seed-isort-config` was created. Since isort 5 however, the project has drastically improved its placement +To fix this, a utility called `seed-isort-config` was created. Since isort 5 however, the project has drastically improved its placement logic and ensured a good level of consistency across environments. If you have a step in your pre-commit config called `seed-isort-config` or similar, it is highly recommend that you remove this. It is guaranteed to slow things down, and can conflict with isort's own module placement logic. diff --git a/docs/contributing/1.-contributing-guide.md b/docs/contributing/1.-contributing-guide.md index 2ba296f8d..ee29ec7c9 100644 --- a/docs/contributing/1.-contributing-guide.md +++ b/docs/contributing/1.-contributing-guide.md @@ -49,7 +49,7 @@ A local test cycle might look like the following: 3. if #2 fails, debug, save, and goto #1 * `docker run -it isort bash` will get you into the failed environment * `docker run -v $(git rev-parse --show-toplevel):/isort` will make changes made in the docker environment persist on your local checkout. - **TIP**: combine both to get an interacive docker shell that loads changes made locally, even after build, to quickly rerun that pesky failing test + **TIP**: combine both to get an interactive docker shell that loads changes made locally, even after build, to quickly rerun that pesky failing test 4. `./scripts/docker.sh` 5. if #4 fails, debug, save and goto #1; you may need to specify a different `--build-arg VERSION=$VER` 6. congrats! you are probably ready to push a contribution diff --git a/isort/_future/_dataclasses.py b/isort/_future/_dataclasses.py index 87acb666e..71962e2d4 100644 --- a/isort/_future/_dataclasses.py +++ b/isort/_future/_dataclasses.py @@ -284,7 +284,7 @@ def __repr__(self): # This is used to support the PEP 487 __set_name__ protocol in the # case where we're using a field that contains a descriptor as a - # defaul value. For details on __set_name__, see + # default value. For details on __set_name__, see # https://www.python.org/dev/peps/pep-0487/#implementation-details. # # Note that in _process_class, this Field object is overwritten @@ -680,7 +680,7 @@ def _get_field(cls, a_name, a_type): # In addition to checking for actual types here, also check for # string annotations. get_type_hints() won't always work for us # (see https://github.com/python/typing/issues/508 for example), - # plus it's expensive and would require an eval for every stirng + # plus it's expensive and would require an eval for every string # annotation. So, make a best effort to see if this is a ClassVar # or InitVar using regex's and checking that the thing referenced # is actually of the correct type. @@ -1148,7 +1148,7 @@ class C(Base): raise TypeError(f"Invalid field: {item!r}") if not isinstance(name, str) or not name.isidentifier(): - raise TypeError(f"Field names must be valid identifers: {name!r}") + raise TypeError(f"Field names must be valid identifiers: {name!r}") if keyword.iskeyword(name): raise TypeError(f"Field names must not be keywords: {name!r}") if name in seen: diff --git a/isort/hooks.py b/isort/hooks.py index 244e7ea11..135886fcb 100644 --- a/isort/hooks.py +++ b/isort/hooks.py @@ -44,7 +44,7 @@ def git_hook( modifying anything. :param bool lazy - if True, also check/fix unstaged files. This is useful if you frequently use ``git commit -a`` for example. - If False, ony check/fix the staged files for isort errors. + If False, only check/fix the staged files for isort errors. :param str settings_file - A path to a file to be used as the configuration file for this run. When settings_file is the empty string, the configuration file diff --git a/isort/main.py b/isort/main.py index dd938ed4b..1c338aa54 100644 --- a/isort/main.py +++ b/isort/main.py @@ -355,7 +355,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: action="store_true", dest="skip_gitignore", help="Treat project as a git repository and ignore files listed in .gitignore." - "\nNOTE: This requires git to be installed and accesible from the same shell as isort.", + "\nNOTE: This requires git to be installed and accessible from the same shell as isort.", ) target_group.add_argument( "--ext", diff --git a/isort/pylama_isort.py b/isort/pylama_isort.py index 00e743823..52da5356a 100644 --- a/isort/pylama_isort.py +++ b/isort/pylama_isort.py @@ -11,7 +11,7 @@ @contextmanager -def supress_stdout() -> Iterator[None]: +def suppress_stdout() -> Iterator[None]: stdout = sys.stdout with open(os.devnull, "w") as devnull: sys.stdout = devnull @@ -28,7 +28,7 @@ def run( self, path: str, params: Optional[Dict[str, Any]] = None, **meta: Any ) -> List[Dict[str, Any]]: """Lint the file. Return an array of error dicts if appropriate.""" - with supress_stdout(): + with suppress_stdout(): try: if not api.check_file(path, disregard_skip=False, **params or {}): return [ diff --git a/tests/unit/test_deprecated_finders.py b/tests/unit/test_deprecated_finders.py index 3e3be56e3..3d715c2ea 100644 --- a/tests/unit/test_deprecated_finders.py +++ b/tests/unit/test_deprecated_finders.py @@ -158,7 +158,7 @@ def test_requirements_finder(tmpdir) -> None: assert finder._normalize_name("deal") == "deal" assert finder._normalize_name("Django") == "django" # lowercase assert finder._normalize_name("django_haystack") == "haystack" # mapping - assert finder._normalize_name("Flask-RESTful") == "flask_restful" # conver `-`to `_` + assert finder._normalize_name("Flask-RESTful") == "flask_restful" # convert `-`to `_` req_file.remove() @@ -178,7 +178,7 @@ def test_pipfile_finder(tmpdir) -> None: assert finder._normalize_name("deal") == "deal" assert finder._normalize_name("Django") == "django" # lowercase assert finder._normalize_name("django_haystack") == "haystack" # mapping - assert finder._normalize_name("Flask-RESTful") == "flask_restful" # conver `-`to `_` + assert finder._normalize_name("Flask-RESTful") == "flask_restful" # convert `-`to `_` pipfile.remove() diff --git a/tests/unit/test_format.py b/tests/unit/test_format.py index 527feaa0b..81f235310 100644 --- a/tests/unit/test_format.py +++ b/tests/unit/test_format.py @@ -85,7 +85,7 @@ def test_colored_printer_diff(capsys): assert colorama.Fore.GREEN + "+ added line" in out # Removed lines are red assert colorama.Fore.RED + "- removed line" in out - # Normal lines are resetted back + # Normal lines are reset back assert colorama.Style.RESET_ALL + "normal line" in out diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index d1003e210..69008b2df 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -98,7 +98,7 @@ def test_blank_lined_removed_issue_1283(): def test_extra_blank_line_added_nested_imports_issue_1290(): - """Ensure isort doesn't added unecessary blank lines above nested imports. + """Ensure isort doesn't add unnecessary blank lines above nested imports. See: https://github.com/pycqa/isort/issues/1290 """ test_input = '''from typing import TYPE_CHECKING diff --git a/tests/unit/utils.py b/tests/unit/utils.py index b87e7a45e..3b00ced93 100644 --- a/tests/unit/utils.py +++ b/tests/unit/utils.py @@ -19,7 +19,7 @@ def as_stream(text: str) -> UnseekableTextIOWrapper: def isort_test(code: str, expected_output: str = "", **config): """Runs isort against the given code snippet and ensures that it - gives consistent output accross multiple runs, and if an expected_output + gives consistent output across multiple runs, and if an expected_output is given - that it matches that. """ expected_output = expected_output or code From 5bf1dbca7bf7abc03892868aec6795e336546bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@iki.fi> Date: Mon, 16 Aug 2021 23:48:40 +0300 Subject: [PATCH 13/54] Document negative number of jobs semantics --- docs/configuration/options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/options.md b/docs/configuration/options.md index 05536cabe..7bd619552 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -1246,7 +1246,7 @@ Explicitly set the settings path or file instead of auto determining based on fi ## Jobs -Number of files to process in parallel. +Number of files to process in parallel. Negative value means use number of CPUs. **Type:** Int **Default:** `None` From 9749f1b3b301bd8f900c735e84ba854a867cb2f1 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sat, 11 Sep 2021 17:31:12 +0200 Subject: [PATCH 14/54] feat(stdlibs): add Python 3.10 modules --- isort/stdlibs/py310.py | 221 +++++++++++++++++++++++++++++++++++++++++ scripts/mkstdlibs.py | 2 +- 2 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 isort/stdlibs/py310.py diff --git a/isort/stdlibs/py310.py b/isort/stdlibs/py310.py new file mode 100644 index 000000000..1db27550c --- /dev/null +++ b/isort/stdlibs/py310.py @@ -0,0 +1,221 @@ +""" +File contains the standard library of Python 3.10. + +DO NOT EDIT. If the standard library changes, a new list should be created +using the mkstdlibs.py script. +""" + +stdlib = { + "_ast", + "_thread", + "abc", + "aifc", + "argparse", + "array", + "ast", + "asynchat", + "asyncio", + "asyncore", + "atexit", + "audioop", + "base64", + "bdb", + "binascii", + "binhex", + "bisect", + "builtins", + "bz2", + "cProfile", + "calendar", + "cgi", + "cgitb", + "chunk", + "cmath", + "cmd", + "code", + "codecs", + "codeop", + "collections", + "colorsys", + "compileall", + "concurrent", + "configparser", + "contextlib", + "contextvars", + "copy", + "copyreg", + "crypt", + "csv", + "ctypes", + "curses", + "dataclasses", + "datetime", + "dbm", + "decimal", + "difflib", + "dis", + "distutils", + "doctest", + "email", + "encodings", + "ensurepip", + "enum", + "errno", + "faulthandler", + "fcntl", + "filecmp", + "fileinput", + "fnmatch", + "fractions", + "ftplib", + "functools", + "gc", + "getopt", + "getpass", + "gettext", + "glob", + "graphlib", + "grp", + "gzip", + "hashlib", + "heapq", + "hmac", + "html", + "http", + "imaplib", + "imghdr", + "imp", + "importlib", + "inspect", + "io", + "ipaddress", + "itertools", + "json", + "keyword", + "lib2to3", + "linecache", + "locale", + "logging", + "lzma", + "mailbox", + "mailcap", + "marshal", + "math", + "mimetypes", + "mmap", + "modulefinder", + "msilib", + "msvcrt", + "multiprocessing", + "netrc", + "nis", + "nntplib", + "ntpath", + "numbers", + "operator", + "optparse", + "os", + "ossaudiodev", + "pathlib", + "pdb", + "pickle", + "pickletools", + "pipes", + "pkgutil", + "platform", + "plistlib", + "poplib", + "posix", + "posixpath", + "pprint", + "profile", + "pstats", + "pty", + "pwd", + "py_compile", + "pyclbr", + "pydoc", + "queue", + "quopri", + "random", + "re", + "readline", + "reprlib", + "resource", + "rlcompleter", + "runpy", + "sched", + "secrets", + "select", + "selectors", + "shelve", + "shlex", + "shutil", + "signal", + "site", + "smtpd", + "smtplib", + "sndhdr", + "socket", + "socketserver", + "spwd", + "sqlite3", + "sre", + "sre_compile", + "sre_constants", + "sre_parse", + "ssl", + "stat", + "statistics", + "string", + "stringprep", + "struct", + "subprocess", + "sunau", + "symtable", + "sys", + "sysconfig", + "syslog", + "tabnanny", + "tarfile", + "telnetlib", + "tempfile", + "termios", + "test", + "textwrap", + "threading", + "time", + "timeit", + "tkinter", + "token", + "tokenize", + "trace", + "traceback", + "tracemalloc", + "tty", + "turtle", + "turtledemo", + "types", + "typing", + "unicodedata", + "unittest", + "urllib", + "uu", + "uuid", + "venv", + "warnings", + "wave", + "weakref", + "webbrowser", + "winreg", + "winsound", + "wsgiref", + "xdrlib", + "xml", + "xmlrpc", + "zipapp", + "zipfile", + "zipimport", + "zlib", + "zoneinfo", +} diff --git a/scripts/mkstdlibs.py b/scripts/mkstdlibs.py index cf5237987..5ee368bd5 100755 --- a/scripts/mkstdlibs.py +++ b/scripts/mkstdlibs.py @@ -4,7 +4,7 @@ URL = "https://docs.python.org/{}/objects.inv" PATH = "isort/stdlibs/py{}.py" -VERSIONS = [("2", "7"), ("3", "5"), ("3", "6"), ("3", "7"), ("3", "8"), ("3", "9")] +VERSIONS = [("2", "7"), ("3", "5"), ("3", "6"), ("3", "7"), ("3", "8"), ("3", "9"), ("3", "10")] DOCSTRING = """ File contains the standard library of Python {}. From bf78e17fbb2448768e785889694ef346e2e6b557 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sat, 11 Sep 2021 17:36:26 +0200 Subject: [PATCH 15/54] feat(stdlibs): import py310 stdlib to add isort support --- isort/stdlibs/__init__.py | 2 +- isort/stdlibs/py3.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/isort/stdlibs/__init__.py b/isort/stdlibs/__init__.py index ed5aa89dc..7b00716b8 100644 --- a/isort/stdlibs/__init__.py +++ b/isort/stdlibs/__init__.py @@ -1,2 +1,2 @@ from . import all as _all -from . import py2, py3, py27, py35, py36, py37, py38, py39 +from . import py2, py3, py27, py35, py36, py37, py38, py39, py310 diff --git a/isort/stdlibs/py3.py b/isort/stdlibs/py3.py index b7dbcc2cb..4e0b5eec9 100644 --- a/isort/stdlibs/py3.py +++ b/isort/stdlibs/py3.py @@ -1,3 +1,3 @@ -from . import py35, py36, py37, py38, py39 +from . import py35, py36, py37, py38, py39, py310 -stdlib = py35.stdlib | py36.stdlib | py37.stdlib | py38.stdlib | py39.stdlib +stdlib = py35.stdlib | py36.stdlib | py37.stdlib | py38.stdlib | py39.stdlib | py310.stdlib From a3c44ad77cb0bfba01820af66296e589457eaa94 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sun, 12 Sep 2021 14:00:29 +0200 Subject: [PATCH 16/54] feat(settings): support Python 3.10 in auto mode --- isort/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isort/settings.py b/isort/settings.py index 3752b6336..f091bbbef 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -245,7 +245,7 @@ def __post_init__(self) -> None: if sys.version_info.major == 2 and sys.version_info.minor <= 6: py_version = "2" elif sys.version_info.major == 3 and ( - sys.version_info.minor <= 5 or sys.version_info.minor >= 9 + sys.version_info.minor <= 5 or sys.version_info.minor >= 10 ): py_version = "3" else: From 3f062b2a341358432efe406b786b78e1135cb266 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sun, 12 Sep 2021 01:24:57 +0200 Subject: [PATCH 17/54] chore(pyproject): add Python 3.10 classifier --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d73824dbd..aeb42f5b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", From 44a03934d70c580b5f4e5558fd5c50b58d493ae1 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sun, 12 Sep 2021 03:14:41 +0200 Subject: [PATCH 18/54] build(deps): remove unneeded numpy dev dependency --- poetry.lock | 66 ++++++++++++++++---------------------------------- pyproject.toml | 1 - 2 files changed, 21 insertions(+), 46 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4315dfb1f..cf8167dc6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -929,14 +929,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "numpy" -version = "1.19.5" -description = "NumPy is the fundamental package for array computing with Python." -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "orderedmultidict" version = "1.0.1" @@ -1806,7 +1798,7 @@ requirements_deprecated_finder = ["pipreqs", "pip-api"] [metadata] lock-version = "1.1" python-versions = ">=3.6.1,<4.0" -content-hash = "89953225da137cf01f6889cc2c4e6f44e0aea847dda012968864cbabd904db14" +content-hash = "62a0a0b1f84f078af18e91535580fd457ed1ad811487ec3a73da5d279b9167b1" [metadata.files] appdirs = [ @@ -2139,12 +2131,22 @@ markdown = [ {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -2153,14 +2155,21 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -2170,6 +2179,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -2231,42 +2243,6 @@ nodeenv = [ {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"}, ] -numpy = [ - {file = "numpy-1.19.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc6bd4fd593cb261332568485e20a0712883cf631f6f5e8e86a52caa8b2b50ff"}, - {file = "numpy-1.19.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aeb9ed923be74e659984e321f609b9ba54a48354bfd168d21a2b072ed1e833ea"}, - {file = "numpy-1.19.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8b5e972b43c8fc27d56550b4120fe6257fdc15f9301914380b27f74856299fea"}, - {file = "numpy-1.19.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:43d4c81d5ffdff6bae58d66a3cd7f54a7acd9a0e7b18d97abb255defc09e3140"}, - {file = "numpy-1.19.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a4646724fba402aa7504cd48b4b50e783296b5e10a524c7a6da62e4a8ac9698d"}, - {file = "numpy-1.19.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2e55195bc1c6b705bfd8ad6f288b38b11b1af32f3c8289d6c50d47f950c12e76"}, - {file = "numpy-1.19.5-cp36-cp36m-win32.whl", hash = "sha256:39b70c19ec771805081578cc936bbe95336798b7edf4732ed102e7a43ec5c07a"}, - {file = "numpy-1.19.5-cp36-cp36m-win_amd64.whl", hash = "sha256:dbd18bcf4889b720ba13a27ec2f2aac1981bd41203b3a3b27ba7a33f88ae4827"}, - {file = "numpy-1.19.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:603aa0706be710eea8884af807b1b3bc9fb2e49b9f4da439e76000f3b3c6ff0f"}, - {file = "numpy-1.19.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cae865b1cae1ec2663d8ea56ef6ff185bad091a5e33ebbadd98de2cfa3fa668f"}, - {file = "numpy-1.19.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:36674959eed6957e61f11c912f71e78857a8d0604171dfd9ce9ad5cbf41c511c"}, - {file = "numpy-1.19.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:06fab248a088e439402141ea04f0fffb203723148f6ee791e9c75b3e9e82f080"}, - {file = "numpy-1.19.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6149a185cece5ee78d1d196938b2a8f9d09f5a5ebfbba66969302a778d5ddd1d"}, - {file = "numpy-1.19.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:50a4a0ad0111cc1b71fa32dedd05fa239f7fb5a43a40663269bb5dc7877cfd28"}, - {file = "numpy-1.19.5-cp37-cp37m-win32.whl", hash = "sha256:d051ec1c64b85ecc69531e1137bb9751c6830772ee5c1c426dbcfe98ef5788d7"}, - {file = "numpy-1.19.5-cp37-cp37m-win_amd64.whl", hash = "sha256:a12ff4c8ddfee61f90a1633a4c4afd3f7bcb32b11c52026c92a12e1325922d0d"}, - {file = "numpy-1.19.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf2402002d3d9f91c8b01e66fbb436a4ed01c6498fffed0e4c7566da1d40ee1e"}, - {file = "numpy-1.19.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1ded4fce9cfaaf24e7a0ab51b7a87be9038ea1ace7f34b841fe3b6894c721d1c"}, - {file = "numpy-1.19.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:012426a41bc9ab63bb158635aecccc7610e3eff5d31d1eb43bc099debc979d94"}, - {file = "numpy-1.19.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:759e4095edc3c1b3ac031f34d9459fa781777a93ccc633a472a5468587a190ff"}, - {file = "numpy-1.19.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a9d17f2be3b427fbb2bce61e596cf555d6f8a56c222bd2ca148baeeb5e5c783c"}, - {file = "numpy-1.19.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99abf4f353c3d1a0c7a5f27699482c987cf663b1eac20db59b8c7b061eabd7fc"}, - {file = "numpy-1.19.5-cp38-cp38-win32.whl", hash = "sha256:384ec0463d1c2671170901994aeb6dce126de0a95ccc3976c43b0038a37329c2"}, - {file = "numpy-1.19.5-cp38-cp38-win_amd64.whl", hash = "sha256:811daee36a58dc79cf3d8bdd4a490e4277d0e4b7d103a001a4e73ddb48e7e6aa"}, - {file = "numpy-1.19.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c843b3f50d1ab7361ca4f0b3639bf691569493a56808a0b0c54a051d260b7dbd"}, - {file = "numpy-1.19.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d6631f2e867676b13026e2846180e2c13c1e11289d67da08d71cacb2cd93d4aa"}, - {file = "numpy-1.19.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7fb43004bce0ca31d8f13a6eb5e943fa73371381e53f7074ed21a4cb786c32f8"}, - {file = "numpy-1.19.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2ea52bd92ab9f768cc64a4c3ef8f4b2580a17af0a5436f6126b08efbd1838371"}, - {file = "numpy-1.19.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:400580cbd3cff6ffa6293df2278c75aef2d58d8d93d3c5614cd67981dae68ceb"}, - {file = "numpy-1.19.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:df609c82f18c5b9f6cb97271f03315ff0dbe481a2a02e56aeb1b1a985ce38e60"}, - {file = "numpy-1.19.5-cp39-cp39-win32.whl", hash = "sha256:ab83f24d5c52d60dbc8cd0528759532736b56db58adaa7b5f1f76ad551416a1e"}, - {file = "numpy-1.19.5-cp39-cp39-win_amd64.whl", hash = "sha256:0eef32ca3132a48e43f6a0f5a82cb508f22ce5a3d6f67a8329c81c8e226d3f6e"}, - {file = "numpy-1.19.5-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:a0d53e51a6cb6f0d9082decb7a4cb6dfb33055308c4c44f53103c073f649af73"}, - {file = "numpy-1.19.5.zip", hash = "sha256:a76f502430dd98d7546e1ea2250a7360c065a5fdea52b2dffe8ae7180909b6f4"}, -] orderedmultidict = [ {file = "orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3"}, {file = "orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad"}, diff --git a/pyproject.toml b/pyproject.toml index aeb42f5b3..4d681e3b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,6 @@ pipfile = "^0.0.2" requirementslib = "^1.5" pipreqs = "^0.4.9" pip_api = "^0.0.12" -numpy = "^1.16.0" pylama = "^7.7" pip = "^21.1.1" pip-shims = "^0.5.2" From e5d5a4daa28d5e55eb4a5a8229615e6c48d62f0c Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sun, 12 Sep 2021 01:27:34 +0200 Subject: [PATCH 19/54] chore(ci): run tests against Python 3.9 and 3.10.0-rc.2 --- .github/workflows/integration.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 13 ++++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3f66a7ef2..b5bc72950 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8] + python-version: ["3.8"] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index af9158bc9..b2db9e29e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8] + python-version: ["3.8"] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 132172447..892d89988 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.6, 3.7, 3.8] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10.0-rc.2"] os: [ubuntu-latest, ubuntu-18.04, macos-latest, windows-latest] steps: @@ -48,11 +48,18 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install poetry run: | python -m pip install --upgrade pip python -m pip install --upgrade poetry - poetry install + + # New poetry installer doesn't work well with Python 3.10 (see https://github.com/python-poetry/poetry/issues/4210). + - name: Use legacy poetry installer + if: startsWith(matrix.python-version, '3.10') + run: poetry config experimental.new-installer false + + - name: Install dependencies + run: poetry install - name: Test shell: bash From e10dbfa11799ac6d7ad3fae8a5d19557f6e41e97 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Sun, 12 Sep 2021 03:15:04 +0200 Subject: [PATCH 20/54] doc(changelog): add entry for Python 3.10 support --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec707da8f..98a06d4f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Find out more about isort's release policy [here](https://pycqa.github.io/isort/ - Implemented #1796: Switch to `tomli` for pyproject.toml configuration loader. - Fixed #1801: CLI bug (--exend-skip-glob, overrides instead of extending). - Fixed #1802: respect PATH customization in nested calls to git. + - Added support for Python 3.10 #### Potentially breaking changes: - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. From 3f13b80d1dca23be18b1ac6a3859b91530b0d7db Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Tue, 14 Sep 2021 11:01:32 +0530 Subject: [PATCH 21/54] ensure all cases are covered by appropriate exception handling --- isort/parse.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/isort/parse.py b/isort/parse.py index fb109013a..53d57725d 100644 --- a/isort/parse.py +++ b/isort/parse.py @@ -447,6 +447,10 @@ def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedConte f"could not place module {import_from} of line {line} --" " Do you need to define a default section?" ) + + if placed_module and placed_module not in imports: + raise MissingSection(import_module=import_from, section=placed_module) + root = imports[placed_module][type_of_import] # type: ignore for import_name in just_imports: associated_comment = nested_comments.get(import_name) From 86217946108682b95a4014a701dfbf53387a0c5e Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Tue, 14 Sep 2021 11:02:24 +0530 Subject: [PATCH 22/54] Add test to test adequate exception handling --- tests/unit/test_isort.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index f6f905fda..bf22d34b8 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -19,7 +19,7 @@ from isort.settings import Config from isort.utils import exists_case_sensitive -from isort.exceptions import FileSkipped, ExistingSyntaxErrors +from isort.exceptions import FileSkipped, ExistingSyntaxErrors, MissingSection from .utils import as_stream, UnreadableStream if TYPE_CHECKING: @@ -2037,6 +2037,41 @@ def test_custom_sections() -> None: ) +def test_custom_sections_exception_handling() -> None: + """Ensure that appropriate exception is raised for missing sections""" + test_input = "import requests\n" + + with pytest.raises(MissingSection): + isort.code( + code=test_input, + default_section="THIRDPARTY", + sections=[ + "FUTURE", + "STDLIB", + "DJANGO", + "PANDAS", + "FIRSTPARTY", + "LOCALFOLDER", + ], + ) + + test_input = "from requests import get, post\n" + + with pytest.raises(MissingSection): + isort.code( + code=test_input, + default_section="THIRDPARTY", + sections=[ + "FUTURE", + "STDLIB", + "DJANGO", + "PANDAS", + "FIRSTPARTY", + "LOCALFOLDER", + ], + ) + + def test_glob_known() -> None: """Ensure that most specific placement control match wins""" test_input = ( From 146e01bc64765149d270485086e06a37e8ab6e03 Mon Sep 17 00:00:00 2001 From: Parnassius <Parnassius@users.noreply.github.com> Date: Thu, 30 Sep 2021 11:53:08 +0200 Subject: [PATCH 23/54] Add an option to set a footer for every import section Closes #1733 --- docs/configuration/options.md | 9 + isort/core.py | 6 +- isort/output.py | 11 ++ isort/parse.py | 4 +- isort/settings.py | 19 +++ .../integration/test_setting_combinations.py | 4 + tests/unit/test_isort.py | 157 ++++++++++++++++++ 7 files changed, 208 insertions(+), 2 deletions(-) diff --git a/docs/configuration/options.md b/docs/configuration/options.md index ecacef0d1..3bd81a8e1 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -431,6 +431,15 @@ Sets the default section for import options: ('FUTURE', 'STDLIB', 'THIRDPARTY', **Python & Config File Name:** import_headings **CLI Flags:** **Not Supported** +## Import Footers + +**No Description** + +**Type:** Dict +**Default:** `{}` +**Python & Config File Name:** import_footers +**CLI Flags:** **Not Supported** + ## Balanced Wrapping Balances wrapping to produce the most consistent line length possible diff --git a/isort/core.py b/isort/core.py index 4d0a46eb3..018c8e0b7 100644 --- a/isort/core.py +++ b/isort/core.py @@ -249,7 +249,10 @@ def process( else: code_sorting_section += line line = "" - elif stripped_line in config.section_comments: + elif ( + stripped_line in config.section_comments + or stripped_line in config.section_comments_end + ): if import_section and not contains_imports: output_stream.write(import_section) import_section = line @@ -460,6 +463,7 @@ def _indented_config(config: Config, indent: str) -> Config: wrap_length=max(config.wrap_length - len(indent), 0), lines_after_imports=1, import_headings=config.import_headings if config.indented_import_headings else {}, + import_footers=config.import_footers if config.indented_import_headings else {}, ) diff --git a/isort/output.py b/isort/output.py index 76f2637d4..f3003751b 100644 --- a/isort/output.py +++ b/isort/output.py @@ -138,6 +138,17 @@ def sorted_imports( if section_comment not in parsed.lines_without_imports[0:1]: # pragma: no branch section_output.insert(0, section_comment) + section_footer = config.import_footers.get(section_name.lower(), "") + if section_footer and section_footer not in seen_headings: + if config.dedup_headings: + seen_headings.add(section_footer) + section_comment_end = f"# {section_footer}" + if ( + section_comment_end not in parsed.lines_without_imports[-1:] + ): # pragma: no branch + section_output.append("") # Empty line for black compatibility + section_output.append(section_comment_end) + if pending_lines_before or not no_lines_before: output += [""] * config.lines_between_sections diff --git a/isort/parse.py b/isort/parse.py index 53d57725d..7fc6c8e65 100644 --- a/isort/parse.py +++ b/isort/parse.py @@ -187,7 +187,9 @@ def file_contents(contents: str, config: Config = DEFAULT_CONFIG) -> ParsedConte line, in_quote=in_quote, index=index, section_comments=config.section_comments ) - if line in config.section_comments and not skipping_line: + if ( + line in config.section_comments or line in config.section_comments_end + ) and not skipping_line: if import_index == -1: # pragma: no branch import_index = index - 1 continue diff --git a/isort/settings.py b/isort/settings.py index f091bbbef..0736b57ec 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -102,6 +102,7 @@ FALLBACK_CONFIG_SECTIONS: Tuple[str, ...] = ("isort", "tool:isort", "tool.isort") IMPORT_HEADING_PREFIX = "import_heading_" +IMPORT_FOOTER_PREFIX = "import_footer_" KNOWN_PREFIX = "known_" KNOWN_SECTION_MAPPING: Dict[str, str] = { STDLIB: "STANDARD_LIBRARY", @@ -173,6 +174,7 @@ class _Config: single_line_exclusions: Tuple[str, ...] = () default_section: str = THIRDPARTY import_headings: Dict[str, str] = field(default_factory=dict) + import_footers: Dict[str, str] = field(default_factory=dict) balanced_wrapping: bool = False use_parentheses: bool = False order_by_type: bool = True @@ -297,6 +299,7 @@ def __init__( ): self._known_patterns: Optional[List[Tuple[Pattern[str], str]]] = None self._section_comments: Optional[Tuple[str, ...]] = None + self._section_comments_end: Optional[Tuple[str, ...]] = None self._skips: Optional[FrozenSet[str]] = None self._skip_globs: Optional[FrozenSet[str]] = None self._sorting_function: Optional[Callable[..., List[str]]] = None @@ -307,6 +310,7 @@ def __init__( config_vars["py_version"] = config_vars["py_version"].replace("py", "") config_vars.pop("_known_patterns") config_vars.pop("_section_comments") + config_vars.pop("_section_comments_end") config_vars.pop("_skips") config_vars.pop("_skip_globs") config_vars.pop("_sorting_function") @@ -381,6 +385,7 @@ def __init__( known_other = {} import_headings = {} + import_footers = {} for key, value in tuple(combined_config.items()): # Collect all known sections beyond those that have direct entries if key.startswith(KNOWN_PREFIX) and key not in ( @@ -417,6 +422,8 @@ def __init__( ) if key.startswith(IMPORT_HEADING_PREFIX): import_headings[key[len(IMPORT_HEADING_PREFIX) :].lower()] = str(value) + if key.startswith(IMPORT_FOOTER_PREFIX): + import_footers[key[len(IMPORT_FOOTER_PREFIX) :].lower()] = str(value) # Coerce all provided config values into their correct type default_value = _DEFAULT_SETTINGS.get(key, None) @@ -495,6 +502,10 @@ def __init__( for import_heading_key in import_headings: combined_config.pop(f"{IMPORT_HEADING_PREFIX}{import_heading_key}") combined_config["import_headings"] = import_headings + if import_footers: + for import_footer_key in import_footers: + combined_config.pop(f"{IMPORT_FOOTER_PREFIX}{import_footer_key}") + combined_config["import_footers"] = import_footers unsupported_config_errors = {} for option in set(combined_config.keys()).difference( @@ -653,6 +664,14 @@ def section_comments(self) -> Tuple[str, ...]: self._section_comments = tuple(f"# {heading}" for heading in self.import_headings.values()) return self._section_comments + @property + def section_comments_end(self) -> Tuple[str, ...]: + if self._section_comments_end is not None: + return self._section_comments_end + + self._section_comments_end = tuple(f"# {footer}" for footer in self.import_footers.values()) + return self._section_comments_end + @property def skips(self) -> FrozenSet[str]: if self._skips is not None: diff --git a/tests/integration/test_setting_combinations.py b/tests/integration/test_setting_combinations.py index d2159fd3e..aca9c9ca9 100644 --- a/tests/integration/test_setting_combinations.py +++ b/tests/integration/test_setting_combinations.py @@ -553,6 +553,7 @@ def _raise(*a): ), default_section="THIRDPARTY", import_headings={}, + import_footers={}, balanced_wrapping=False, use_parentheses=True, order_by_type=True, @@ -859,6 +860,7 @@ def _raise(*a): "single_line_exclusions": (), "default_section": "THIRDPARTY", "import_headings": {}, + "import_footers": {}, "balanced_wrapping": False, "use_parentheses": False, "order_by_type": True, @@ -1414,6 +1416,7 @@ def test_isort_is_idempotent(config: isort.Config, disregard_skip: bool) -> None ), default_section="THIRDPARTY", import_headings={}, + import_footers={}, balanced_wrapping=False, use_parentheses=True, order_by_type=True, @@ -1720,6 +1723,7 @@ def test_isort_is_idempotent(config: isort.Config, disregard_skip: bool) -> None "single_line_exclusions": (), "default_section": "THIRDPARTY", "import_headings": {}, + "import_footers": {}, "balanced_wrapping": False, "use_parentheses": False, "order_by_type": True, diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index bf22d34b8..a10138849 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -1356,6 +1356,163 @@ def test_titled_imports() -> None: ) +def test_footered_imports() -> None: + """Tests setting both custom titles and footers to import sections.""" + test_input = ( + "import sys\n" + "import unicodedata\n" + "import statistics\n" + "import os\n" + "import myproject.test\n" + "import django.settings" + ) + test_output = isort.code( + code=test_input, + known_first_party=["myproject"], + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_output == ( + "import os\n" + "import statistics\n" + "import sys\n" + "import unicodedata\n" + "\n" + "# Standard Library End\n" + "\n" + "import django.settings\n" + "\n" + "import myproject.test\n" + "\n" + "# My Stuff End\n" + ) + test_second_run = isort.code( + code=test_output, + known_first_party=["myproject"], + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_second_run == test_output + + test_input_lines_down = ( + "# comment 1\n" + "import django.settings\n" + "\n" + "import sys\n" + "import unicodedata\n" + "import statistics\n" + "import os\n" + "import myproject.test\n" + "\n" + "# Standard Library End\n" + ) + test_output_lines_down = isort.code( + code=test_input_lines_down, + known_first_party=["myproject"], + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_output_lines_down == ( + "# comment 1\n" + "import os\n" + "import statistics\n" + "import sys\n" + "import unicodedata\n" + "\n" + "# Standard Library End\n" + "\n" + "import django.settings\n" + "\n" + "import myproject.test\n" + "\n" + "# My Stuff End\n" + ) + + +def test_titled_and_footered_imports() -> None: + """Tests setting custom footers to import sections.""" + test_input = ( + "import sys\n" + "import unicodedata\n" + "import statistics\n" + "import os\n" + "import myproject.test\n" + "import django.settings" + ) + test_output = isort.code( + code=test_input, + known_first_party=["myproject"], + import_heading_stdlib="Standard Library", + import_heading_firstparty="My Stuff", + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_output == ( + "# Standard Library\n" + "import os\n" + "import statistics\n" + "import sys\n" + "import unicodedata\n" + "\n" + "# Standard Library End\n" + "\n" + "import django.settings\n" + "\n" + "# My Stuff\n" + "import myproject.test\n" + "\n" + "# My Stuff End\n" + ) + test_second_run = isort.code( + code=test_output, + known_first_party=["myproject"], + import_heading_stdlib="Standard Library", + import_heading_firstparty="My Stuff", + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_second_run == test_output + + test_input_lines_down = ( + "# comment 1\n" + "import django.settings\n" + "\n" + "# Standard Library\n" + "import sys\n" + "import unicodedata\n" + "import statistics\n" + "import os\n" + "import myproject.test\n" + "\n" + "# Standard Library End\n" + ) + test_output_lines_down = isort.code( + code=test_input_lines_down, + known_first_party=["myproject"], + import_heading_stdlib="Standard Library", + import_heading_firstparty="My Stuff", + import_footer_stdlib="Standard Library End", + import_footer_firstparty="My Stuff End", + ) + assert test_output_lines_down == ( + "# comment 1\n" + "# Standard Library\n" + "import os\n" + "import statistics\n" + "import sys\n" + "import unicodedata\n" + "\n" + "# Standard Library End\n" + "\n" + "import django.settings\n" + "\n" + "# My Stuff\n" + "import myproject.test\n" + "\n" + "# My Stuff End\n" + ) + + def test_balanced_wrapping() -> None: """Tests balanced wrapping mode, where the length of individual lines maintain width.""" test_input = ( From 960d208ae5be5e7b0391c17fd3d31408adb1538e Mon Sep 17 00:00:00 2001 From: Samuel Gaist <samuel.gaist@idiap.ch> Date: Tue, 28 Sep 2021 23:24:57 +0200 Subject: [PATCH 24/54] feature: implement lines before imports --- docs/configuration/options.md | 12 ++++++++++++ isort/main.py | 3 +++ isort/output.py | 3 +++ isort/settings.py | 1 + tests/integration/test_hypothesmith.py | 1 + tests/integration/test_setting_combinations.py | 5 +++++ tests/unit/test_isort.py | 13 +++++++++++++ 7 files changed, 38 insertions(+) diff --git a/docs/configuration/options.md b/docs/configuration/options.md index ecacef0d1..642e70b03 100644 --- a/docs/configuration/options.md +++ b/docs/configuration/options.md @@ -482,6 +482,18 @@ Ensures the output doesn't save if the resulting file contains syntax errors. - --ac - --atomic +## Lines Before Imports + +How many lines to add before an import section + +**Type:** Int +**Default:** `-1` +**Python & Config File Name:** lines_before_imports +**CLI Flags:** + +- --lbi +- --lines-before-imports + ## Lines After Imports **No Description** diff --git a/isort/main.py b/isort/main.py index 1c338aa54..a6661a076 100644 --- a/isort/main.py +++ b/isort/main.py @@ -484,6 +484,9 @@ def _build_arg_parser() -> argparse.ArgumentParser: dest="indent", type=str, ) + output_group.add_argument( + "--lbi", "--lines-before-imports", dest="lines_before_imports", type=int + ) output_group.add_argument( "--lai", "--lines-after-imports", dest="lines_after_imports", type=int ) diff --git a/isort/output.py b/isort/output.py index 76f2637d4..5730015e4 100644 --- a/isort/output.py +++ b/isort/output.py @@ -206,6 +206,9 @@ def sorted_imports( else: formatted_output[imports_tail:0] = [""] + if config.lines_before_imports != -1: + formatted_output[:0] = ["" for line in range(config.lines_before_imports)] + if parsed.place_imports: new_out_lines = [] for index, line in enumerate(formatted_output): diff --git a/isort/settings.py b/isort/settings.py index f091bbbef..09875978b 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -177,6 +177,7 @@ class _Config: use_parentheses: bool = False order_by_type: bool = True atomic: bool = False + lines_before_imports: int = -1 lines_after_imports: int = -1 lines_between_sections: int = 1 lines_between_types: int = 0 diff --git a/tests/integration/test_hypothesmith.py b/tests/integration/test_hypothesmith.py index 94964cee0..2c8b4a482 100644 --- a/tests/integration/test_hypothesmith.py +++ b/tests/integration/test_hypothesmith.py @@ -40,6 +40,7 @@ def configs(**force_strategies: st.SearchStrategy) -> st.SearchStrategy[isort.Co "sections", "known_future_library", "forced_separate", + "lines_before_imports", "lines_after_imports", "lines_between_sections", "lines_between_types", diff --git a/tests/integration/test_setting_combinations.py b/tests/integration/test_setting_combinations.py index d2159fd3e..cda39a60c 100644 --- a/tests/integration/test_setting_combinations.py +++ b/tests/integration/test_setting_combinations.py @@ -29,6 +29,7 @@ def configs() -> st.SearchStrategy[isort.Config]: "known_local_folder", "extra_standard_library", "forced_separate", + "lines_before_imports", "lines_after_imports", "add_imports", "lines_between_sections", @@ -557,6 +558,7 @@ def _raise(*a): use_parentheses=True, order_by_type=True, atomic=False, + lines_before_imports=-1, lines_after_imports=-1, lines_between_sections=1, lines_between_types=0, @@ -863,6 +865,7 @@ def _raise(*a): "use_parentheses": False, "order_by_type": True, "atomic": False, + "lines_before_imports": -1, "lines_after_imports": -1, "lines_between_sections": 1, "lines_between_types": 0, @@ -1418,6 +1421,7 @@ def test_isort_is_idempotent(config: isort.Config, disregard_skip: bool) -> None use_parentheses=True, order_by_type=True, atomic=False, + lines_before_imports=-1, lines_after_imports=-1, lines_between_sections=1, lines_between_types=0, @@ -1724,6 +1728,7 @@ def test_isort_is_idempotent(config: isort.Config, disregard_skip: bool) -> None "use_parentheses": False, "order_by_type": True, "atomic": False, + "lines_before_imports": -1, "lines_after_imports": -1, "lines_between_sections": 1, "lines_between_types": 0, diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index bf22d34b8..eb0177fb0 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -1473,6 +1473,19 @@ def test_order_by_type() -> None: ) +def test_custom_lines_before_import_section() -> None: + """Test the case where the number of lines to output after imports has been explicitly set.""" + test_input = "from a import b\nfrom c import d\nfoo = 'bar'\n" + + # default case is no line added before the import + assert isort.code(test_input) == ("from a import b\nfrom c import d\n\nfoo = 'bar'\n") + + # test again with a custom number of lines before the import section + assert isort.code(test_input, lines_before_imports=2) == ( + "\n\nfrom a import b\nfrom c import d\n\nfoo = 'bar'\n" + ) + + def test_custom_lines_after_import_section() -> None: """Test the case where the number of lines to output after imports has been explicitly set.""" test_input = "from a import b\nfoo = 'bar'\n" From 1072501d041add187e4d534022f54529f30de3c0 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sat, 2 Oct 2021 15:37:18 +0530 Subject: [PATCH 25/54] AAdd support to use multiple configs in single isort execution --- isort/api.py | 28 ++++++++++++++++++--- isort/main.py | 16 +++++++++++- isort/settings.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/isort/api.py b/isort/api.py index 392c94ca6..de4053c3f 100644 --- a/isort/api.py +++ b/isort/api.py @@ -323,12 +323,23 @@ def check_file( - **extension**: The file extension that contains imports. Defaults to filename extension or py. - ****config_kwargs**: Any config modifications. """ + file_config: Config = config + + if "config_trie" in config_kwargs: + config_trie = config_kwargs.pop("config_trie", None) + if config_trie: + config_info = config_trie._search(filename) + if config.verbose: + print(f"{config_info[0]} used for file {filename}") + + file_config = config_info[1] + with io.File.read(filename) as source_file: return check_stream( source_file.stream, show_diff=show_diff, extension=extension, - config=config, + config=file_config, file_path=file_path or source_file.path, disregard_skip=disregard_skip, **config_kwargs, @@ -380,6 +391,17 @@ def sort_file( the original file content. - ****config_kwargs**: Any config modifications. """ + file_config: Config = config + + if "config_trie" in config_kwargs: + config_trie = config_kwargs.pop("config_trie", None) + if config_trie: + config_info = config_trie._search(filename) + if config.verbose: + print(f"{config_info[0]} used for file {filename}") + + file_config = config_info[1] + with io.File.read(filename) as source_file: actual_file_path = file_path or source_file.path config = _config(path=actual_file_path, config=config, **config_kwargs) @@ -389,7 +411,7 @@ def sort_file( changed = sort_stream( input_stream=source_file.stream, output_stream=sys.stdout, - config=config, + config=file_config, file_path=actual_file_path, disregard_skip=disregard_skip, extension=extension, @@ -407,7 +429,7 @@ def sort_file( changed = sort_stream( input_stream=source_file.stream, output_stream=output_stream, - config=config, + config=file_config, file_path=actual_file_path, disregard_skip=disregard_skip, extension=extension, diff --git a/isort/main.py b/isort/main.py index 1c338aa54..f01a30cb8 100644 --- a/isort/main.py +++ b/isort/main.py @@ -15,7 +15,7 @@ from .format import create_terminal_printer from .logo import ASCII_ART from .profiles import profiles -from .settings import VALID_PY_TARGETS, Config +from .settings import VALID_PY_TARGETS, Config, Trie, find_all_configs from .wrap_modes import WrapModes DEPRECATED_SINGLE_DASH_ARGS = { @@ -259,6 +259,13 @@ def _build_arg_parser() -> argparse.ArgumentParser: help="Explicitly set the settings path or file instead of auto determining " "based on file location.", ) + general_group.add_argument( + "--resolve-all-configs", + dest="resolve_all_configs", + action="store_true", + help="Tells isort to resolve the configs for all sub-directories " + "and sort files in terms of its closest config files.", + ) general_group.add_argument( "--profile", dest="profile", @@ -1071,10 +1078,15 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = stream_filename = config_dict.pop("filename", None) ext_format = config_dict.pop("ext_format", None) allow_root = config_dict.pop("allow_root", None) + resolve_all_configs = config_dict.pop("resolve_all_configs", False) wrong_sorted_files = False all_attempt_broken = False no_valid_encodings = False + config_trie: Optional[Trie] = None + if resolve_all_configs: + config_trie = find_all_configs(config_dict.get("src_paths", ("."))) + if "src_paths" in config_dict: config_dict["src_paths"] = { Path(src_path).resolve() for src_path in config_dict.get("src_paths", ()) @@ -1162,6 +1174,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = ask_to_apply=ask_to_apply, write_to_stdout=write_to_stdout, extension=ext_format, + config_trie=config_trie, ), file_names, ) @@ -1176,6 +1189,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = show_diff=show_diff, write_to_stdout=write_to_stdout, extension=ext_format, + config_trie=config_trie, ) for file_name in file_names ) diff --git a/isort/settings.py b/isort/settings.py index f091bbbef..ee9152412 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -706,6 +706,45 @@ def _parse_known_pattern(self, pattern: str) -> List[str]: return patterns +class Trie_Node: + def __init__(self) -> None: + self.nodes: Dict[str, Optional[Trie_Node]] = {} + self.config_info: Tuple[str, Config] = ("", DEFAULT_CONFIG) + + +class Trie: + def __init__(self) -> None: + self.root: Trie_Node = Trie_Node() + + + def _insert(self, config_path: str, config_file: str, config_data: Dict[str, Any]) -> None: + resolved_config_path_as_tuple = Path(config_path).parent.resolve().parts + + temp = self.root + + for path in resolved_config_path_as_tuple: + if path not in temp.nodes: + temp.nodes[path] = Trie_Node() + + temp = temp.nodes[path] + + temp.config_info = (config_file, Config(**config_data)) + + + def _search(self, filename: str) -> Tuple[str, Config]: + resolved_file_path_as_tuple = Path(filename).resolve().parts + + temp = self.root + + for path in resolved_file_path_as_tuple: + if path not in temp.nodes: + return temp.config_info + + temp = temp.nodes[path] + + return temp.config_info + + def _get_str_to_type_converter(setting_name: str) -> Union[Callable[[str], Any], Type[Any]]: type_converter: Union[Callable[[str], Any], Type[Any]] = type( _DEFAULT_SETTINGS.get(setting_name, "") @@ -765,6 +804,31 @@ def _find_config(path: str) -> Tuple[str, Dict[str, Any]]: return (path, {}) +@lru_cache() +def find_all_configs(src_paths: Tuple[str]) -> Trie: + trie_root = Trie() + + for path in src_paths: + for (dirpath, _, _) in os.walk(path): + for config_file_name in CONFIG_SOURCES: + potential_config_file = os.path.join(dirpath, config_file_name) + if os.path.isfile(potential_config_file): + config_data: Dict[str, Any] + try: + config_data = _get_config_data( + potential_config_file, CONFIG_SECTIONS[config_file_name] + ) + except Exception: + warn(f"Failed to pull configuration information from {potential_config_file}") + config_data = {} + + if config_data: + trie_root._insert(potential_config_file, potential_config_file, config_data) + break + + return trie_root + + @lru_cache() def _get_config_data(file_path: str, sections: Tuple[str]) -> Dict[str, Any]: settings: Dict[str, Any] = {} From 6cb81c198b7c45a6786815f2ad0a5419f28f7c43 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sat, 2 Oct 2021 15:43:25 +0530 Subject: [PATCH 26/54] Correct linting errors --- isort/settings.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/isort/settings.py b/isort/settings.py index 512e8f841..43e9cd711 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -726,34 +726,32 @@ def _parse_known_pattern(self, pattern: str) -> List[str]: return patterns -class Trie_Node: +class TrieNode: def __init__(self) -> None: - self.nodes: Dict[str, Optional[Trie_Node]] = {} + self.nodes: Dict[str, TrieNode] = {} self.config_info: Tuple[str, Config] = ("", DEFAULT_CONFIG) class Trie: def __init__(self) -> None: - self.root: Trie_Node = Trie_Node() + self.root: TrieNode = TrieNode() - def _insert(self, config_path: str, config_file: str, config_data: Dict[str, Any]) -> None: resolved_config_path_as_tuple = Path(config_path).parent.resolve().parts - + temp = self.root for path in resolved_config_path_as_tuple: if path not in temp.nodes: - temp.nodes[path] = Trie_Node() + temp.nodes[path] = TrieNode() temp = temp.nodes[path] temp.config_info = (config_file, Config(**config_data)) - def _search(self, filename: str) -> Tuple[str, Config]: resolved_file_path_as_tuple = Path(filename).resolve().parts - + temp = self.root for path in resolved_file_path_as_tuple: @@ -839,7 +837,9 @@ def find_all_configs(src_paths: Tuple[str]) -> Trie: potential_config_file, CONFIG_SECTIONS[config_file_name] ) except Exception: - warn(f"Failed to pull configuration information from {potential_config_file}") + warn( + f"Failed to pull configuration information from {potential_config_file}" + ) config_data = {} if config_data: From 26819c0b2dda1a0f5fd8216d2aada30c748deed3 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sat, 2 Oct 2021 23:37:39 +0530 Subject: [PATCH 27/54] Correct failing test --- isort/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/isort/api.py b/isort/api.py index de4053c3f..92ce7ef87 100644 --- a/isort/api.py +++ b/isort/api.py @@ -404,14 +404,14 @@ def sort_file( with io.File.read(filename) as source_file: actual_file_path = file_path or source_file.path - config = _config(path=actual_file_path, config=config, **config_kwargs) + config = _config(path=actual_file_path, config=file_config, **config_kwargs) changed: bool = False try: if write_to_stdout: changed = sort_stream( input_stream=source_file.stream, output_stream=sys.stdout, - config=file_config, + config=config, file_path=actual_file_path, disregard_skip=disregard_skip, extension=extension, @@ -429,7 +429,7 @@ def sort_file( changed = sort_stream( input_stream=source_file.stream, output_stream=output_stream, - config=file_config, + config=config, file_path=actual_file_path, disregard_skip=disregard_skip, extension=extension, From d134aa0a1becfedda2c9e773dfa8916e61f13c85 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sun, 3 Oct 2021 11:40:34 +0530 Subject: [PATCH 28/54] moved trie to utils.py --- isort/api.py | 4 ++-- isort/main.py | 3 ++- isort/settings.py | 40 ++------------------------------ isort/utils.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 41 deletions(-) diff --git a/isort/api.py b/isort/api.py index 92ce7ef87..4ae07a264 100644 --- a/isort/api.py +++ b/isort/api.py @@ -332,7 +332,7 @@ def check_file( if config.verbose: print(f"{config_info[0]} used for file {filename}") - file_config = config_info[1] + file_config = Config(**config_info[1]) with io.File.read(filename) as source_file: return check_stream( @@ -400,7 +400,7 @@ def sort_file( if config.verbose: print(f"{config_info[0]} used for file {filename}") - file_config = config_info[1] + file_config = Config(**config_info[1]) with io.File.read(filename) as source_file: actual_file_path = file_path or source_file.path diff --git a/isort/main.py b/isort/main.py index 41e3c8a4a..afd230010 100644 --- a/isort/main.py +++ b/isort/main.py @@ -15,7 +15,8 @@ from .format import create_terminal_printer from .logo import ASCII_ART from .profiles import profiles -from .settings import VALID_PY_TARGETS, Config, Trie, find_all_configs +from .settings import VALID_PY_TARGETS, Config, find_all_configs +from .utils import Trie from .wrap_modes import WrapModes DEPRECATED_SINGLE_DASH_ARGS = { diff --git a/isort/settings.py b/isort/settings.py index 43e9cd711..67cee6913 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -41,6 +41,7 @@ from .profiles import profiles from .sections import DEFAULT as SECTION_DEFAULTS from .sections import FIRSTPARTY, FUTURE, LOCALFOLDER, STDLIB, THIRDPARTY +from .utils import Trie from .wrap_modes import WrapModes from .wrap_modes import from_string as wrap_mode_from_string @@ -726,43 +727,6 @@ def _parse_known_pattern(self, pattern: str) -> List[str]: return patterns -class TrieNode: - def __init__(self) -> None: - self.nodes: Dict[str, TrieNode] = {} - self.config_info: Tuple[str, Config] = ("", DEFAULT_CONFIG) - - -class Trie: - def __init__(self) -> None: - self.root: TrieNode = TrieNode() - - def _insert(self, config_path: str, config_file: str, config_data: Dict[str, Any]) -> None: - resolved_config_path_as_tuple = Path(config_path).parent.resolve().parts - - temp = self.root - - for path in resolved_config_path_as_tuple: - if path not in temp.nodes: - temp.nodes[path] = TrieNode() - - temp = temp.nodes[path] - - temp.config_info = (config_file, Config(**config_data)) - - def _search(self, filename: str) -> Tuple[str, Config]: - resolved_file_path_as_tuple = Path(filename).resolve().parts - - temp = self.root - - for path in resolved_file_path_as_tuple: - if path not in temp.nodes: - return temp.config_info - - temp = temp.nodes[path] - - return temp.config_info - - def _get_str_to_type_converter(setting_name: str) -> Union[Callable[[str], Any], Type[Any]]: type_converter: Union[Callable[[str], Any], Type[Any]] = type( _DEFAULT_SETTINGS.get(setting_name, "") @@ -824,7 +788,7 @@ def _find_config(path: str) -> Tuple[str, Dict[str, Any]]: @lru_cache() def find_all_configs(src_paths: Tuple[str]) -> Trie: - trie_root = Trie() + trie_root = Trie("default", DEFAULT_CONFIG.__dict__) for path in src_paths: for (dirpath, _, _) in os.walk(path): diff --git a/isort/utils.py b/isort/utils.py index 63b519902..b50fc297b 100644 --- a/isort/utils.py +++ b/isort/utils.py @@ -1,5 +1,64 @@ import os import sys +from pathlib import Path +from typing import Any, Dict, Optional, Tuple + + +class TrieNode: + def __init__(self, config_file: str = "", config_data: Optional[Dict[str, Any]] = None) -> None: + if not config_file: + config_file = "" + + if not config_data: + config_data = {} + + self.nodes: Dict[str, TrieNode] = {} + self.config_info: Tuple[str, Dict[str, Any]] = (config_file, config_data) + + +class Trie: + """ + A prefix tree to store the paths of all config files and to search the nearest config + associated with each file + """ + + def __init__(self, config_file: str = "", config_data: Optional[Dict[str, Any]] = None) -> None: + self.root: TrieNode = TrieNode(config_file, config_data) + + def _insert(self, config_path: str, config_file: str, config_data: Dict[str, Any]) -> None: + resolved_config_path_as_tuple = Path(config_path).parent.resolve().parts + + temp = self.root + + for path in resolved_config_path_as_tuple: + if path not in temp.nodes: + temp.nodes[path] = TrieNode() + + temp = temp.nodes[path] + + temp.config_info = (config_file, config_data) + + def _search(self, filename: str) -> Tuple[str, Dict[str, Any]]: + """ + Returns the closest config relative to filename by doing a depth + first search on the prefix tree. + """ + resolved_file_path_as_tuple = Path(filename).resolve().parts + + temp = self.root + + last_stored_config: Tuple[str, Dict[str, Any]] = ("", {}) + + for path in resolved_file_path_as_tuple: + if temp.config_info[0]: + last_stored_config = temp.config_info + + if path not in temp.nodes: + break + + temp = temp.nodes[path] + + return last_stored_config def exists_case_sensitive(path: str) -> bool: From 33e49a31ad810b73426ad678bb99152866743dc5 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sun, 3 Oct 2021 12:58:29 +0530 Subject: [PATCH 29/54] Minor changes in function defintions --- isort/settings.py | 2 +- isort/utils.py | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/isort/settings.py b/isort/settings.py index 67cee6913..dcca83899 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -807,7 +807,7 @@ def find_all_configs(src_paths: Tuple[str]) -> Trie: config_data = {} if config_data: - trie_root._insert(potential_config_file, potential_config_file, config_data) + trie_root._insert(potential_config_file, config_data) break return trie_root diff --git a/isort/utils.py b/isort/utils.py index b50fc297b..8447d7afc 100644 --- a/isort/utils.py +++ b/isort/utils.py @@ -6,9 +6,6 @@ class TrieNode: def __init__(self, config_file: str = "", config_data: Optional[Dict[str, Any]] = None) -> None: - if not config_file: - config_file = "" - if not config_data: config_data = {} @@ -25,8 +22,8 @@ class Trie: def __init__(self, config_file: str = "", config_data: Optional[Dict[str, Any]] = None) -> None: self.root: TrieNode = TrieNode(config_file, config_data) - def _insert(self, config_path: str, config_file: str, config_data: Dict[str, Any]) -> None: - resolved_config_path_as_tuple = Path(config_path).parent.resolve().parts + def _insert(self, config_file: str, config_data: Dict[str, Any]) -> None: + resolved_config_path_as_tuple = Path(config_file).parent.resolve().parts temp = self.root From 36fcf3990ae6a0af19ad1158f8aed7aa6d2fe7d7 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sun, 3 Oct 2021 14:02:51 +0530 Subject: [PATCH 30/54] Add test for resolve-all-configs flag --- tests/unit/test_settings.py | 50 +++++++++++++++++++++++++++++++++++++ tests/unit/test_utils.py | 38 ++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tests/unit/test_utils.py diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py index 92f60d692..4ba3475f5 100644 --- a/tests/unit/test_settings.py +++ b/tests/unit/test_settings.py @@ -238,3 +238,53 @@ def test_as_bool(): settings._as_bool("falsey") with pytest.raises(ValueError): settings._as_bool("truthy") + + +def test_find_all_configs(tmpdir): + setup_cfg = """ +[isort] +profile=django +""" + + pyproject_toml = """ +[tool.isort] +profile = "hug" +""" + + isort_cfg = """ +[settings] +profile=black +""" + dir1 = tmpdir / "subdir1" + dir2 = tmpdir / "subdir2" + dir3 = tmpdir / "subdir3" + + dir1.mkdir() + dir2.mkdir() + dir3.mkdir() + + setup_cfg_file = dir1 / "setup.cfg" + setup_cfg_file.write_text(setup_cfg, "utf-8") + + pyproject_toml_file = dir2 / "pyproject.toml" + pyproject_toml_file.write_text(pyproject_toml, "utf-8") + + isort_cfg_file = dir3 / ".isort.cfg" + isort_cfg_file.write_text(isort_cfg, "utf-8") + + config_trie = settings.find_all_configs((str(tmpdir),)) + + config_info_1 = config_trie._search(str(dir1 / "test1.py")) + assert config_info_1[0] == str(setup_cfg_file) + assert "profile" in config_info_1[1] and config_info_1[1]["profile"] == "django" + + config_info_2 = config_trie._search(str(dir2 / "test2.py")) + assert config_info_2[0] == str(pyproject_toml_file) + assert "profile" in config_info_2[1] and config_info_2[1]["profile"] == "hug" + + config_info_3 = config_trie._search(str(dir3 / "test3.py")) + assert config_info_3[0] == str(isort_cfg_file) + assert "profile" in config_info_3[1] and config_info_3[1]["profile"] == "black" + + config_info_4 = config_trie._search(str(tmpdir / "file4.py")) + assert config_info_4[0] == "default" diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py new file mode 100644 index 000000000..cb723d3a7 --- /dev/null +++ b/tests/unit/test_utils.py @@ -0,0 +1,38 @@ +from isort.utils import Trie + + +def test_trie(): + trie_root = Trie("default", {"line_length": 70}) + + trie_root._insert("/temp/config1/.isort.cfg", {"line_length": 71}) + trie_root._insert("/temp/config2/setup.cfg", {"line_length": 72}) + trie_root._insert("/temp/config3/pyproject.toml", {"line_length": 73}) + + # Ensure that appropriate configs are resolved for files in different directories + config1 = trie_root._search("/temp/config1/subdir/file1.py") + assert config1[0] == "/temp/config1/.isort.cfg" + assert config1[1] == {"line_length": 71} + + config1_2 = trie_root._search("/temp/config1/file1_2.py") + assert config1_2[0] == "/temp/config1/.isort.cfg" + assert config1_2[1] == {"line_length": 71} + + config2 = trie_root._search("/temp/config2/subdir/subsubdir/file2.py") + assert config2[0] == "/temp/config2/setup.cfg" + assert config2[1] == {"line_length": 72} + + config2_2 = trie_root._search("/temp/config2/subdir/file2_2.py") + assert config2_2[0] == "/temp/config2/setup.cfg" + assert config2_2[1] == {"line_length": 72} + + config3 = trie_root._search("/temp/config3/subdir/subsubdir/subsubsubdir/file3.py") + assert config3[0] == "/temp/config3/pyproject.toml" + assert config3[1] == {"line_length": 73} + + config3_2 = trie_root._search("/temp/config3/file3.py") + assert config3_2[0] == "/temp/config3/pyproject.toml" + assert config3_2[1] == {"line_length": 73} + + config_outside = trie_root._search("/temp/file.py") + assert config_outside[0] == "default" + assert config_outside[1] == {"line_length": 70} From 2f2bc56485e986b8ddd245f97c91cadea6e5573d Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Sun, 3 Oct 2021 16:47:01 +0530 Subject: [PATCH 31/54] RCorrect deepsource errors --- isort/api.py | 4 ++-- isort/settings.py | 2 +- isort/utils.py | 4 ++-- tests/unit/test_settings.py | 8 ++++---- tests/unit/test_utils.py | 20 ++++++++++---------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/isort/api.py b/isort/api.py index 4ae07a264..4e48fc208 100644 --- a/isort/api.py +++ b/isort/api.py @@ -328,7 +328,7 @@ def check_file( if "config_trie" in config_kwargs: config_trie = config_kwargs.pop("config_trie", None) if config_trie: - config_info = config_trie._search(filename) + config_info = config_trie.search(filename) if config.verbose: print(f"{config_info[0]} used for file {filename}") @@ -396,7 +396,7 @@ def sort_file( if "config_trie" in config_kwargs: config_trie = config_kwargs.pop("config_trie", None) if config_trie: - config_info = config_trie._search(filename) + config_info = config_trie.search(filename) if config.verbose: print(f"{config_info[0]} used for file {filename}") diff --git a/isort/settings.py b/isort/settings.py index dcca83899..b0fd15a71 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -807,7 +807,7 @@ def find_all_configs(src_paths: Tuple[str]) -> Trie: config_data = {} if config_data: - trie_root._insert(potential_config_file, config_data) + trie_root.insert(potential_config_file, config_data) break return trie_root diff --git a/isort/utils.py b/isort/utils.py index 8447d7afc..339c86f6a 100644 --- a/isort/utils.py +++ b/isort/utils.py @@ -22,7 +22,7 @@ class Trie: def __init__(self, config_file: str = "", config_data: Optional[Dict[str, Any]] = None) -> None: self.root: TrieNode = TrieNode(config_file, config_data) - def _insert(self, config_file: str, config_data: Dict[str, Any]) -> None: + def insert(self, config_file: str, config_data: Dict[str, Any]) -> None: resolved_config_path_as_tuple = Path(config_file).parent.resolve().parts temp = self.root @@ -35,7 +35,7 @@ def _insert(self, config_file: str, config_data: Dict[str, Any]) -> None: temp.config_info = (config_file, config_data) - def _search(self, filename: str) -> Tuple[str, Dict[str, Any]]: + def search(self, filename: str) -> Tuple[str, Dict[str, Any]]: """ Returns the closest config relative to filename by doing a depth first search on the prefix tree. diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py index 4ba3475f5..119f1887d 100644 --- a/tests/unit/test_settings.py +++ b/tests/unit/test_settings.py @@ -274,17 +274,17 @@ def test_find_all_configs(tmpdir): config_trie = settings.find_all_configs((str(tmpdir),)) - config_info_1 = config_trie._search(str(dir1 / "test1.py")) + config_info_1 = config_trie.search(str(dir1 / "test1.py")) assert config_info_1[0] == str(setup_cfg_file) assert "profile" in config_info_1[1] and config_info_1[1]["profile"] == "django" - config_info_2 = config_trie._search(str(dir2 / "test2.py")) + config_info_2 = config_trie.search(str(dir2 / "test2.py")) assert config_info_2[0] == str(pyproject_toml_file) assert "profile" in config_info_2[1] and config_info_2[1]["profile"] == "hug" - config_info_3 = config_trie._search(str(dir3 / "test3.py")) + config_info_3 = config_trie.search(str(dir3 / "test3.py")) assert config_info_3[0] == str(isort_cfg_file) assert "profile" in config_info_3[1] and config_info_3[1]["profile"] == "black" - config_info_4 = config_trie._search(str(tmpdir / "file4.py")) + config_info_4 = config_trie.search(str(tmpdir / "file4.py")) assert config_info_4[0] == "default" diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index cb723d3a7..0bc7a0fe8 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -4,35 +4,35 @@ def test_trie(): trie_root = Trie("default", {"line_length": 70}) - trie_root._insert("/temp/config1/.isort.cfg", {"line_length": 71}) - trie_root._insert("/temp/config2/setup.cfg", {"line_length": 72}) - trie_root._insert("/temp/config3/pyproject.toml", {"line_length": 73}) + trie_root.insert("/temp/config1/.isort.cfg", {"line_length": 71}) + trie_root.insert("/temp/config2/setup.cfg", {"line_length": 72}) + trie_root.insert("/temp/config3/pyproject.toml", {"line_length": 73}) # Ensure that appropriate configs are resolved for files in different directories - config1 = trie_root._search("/temp/config1/subdir/file1.py") + config1 = trie_root.search("/temp/config1/subdir/file1.py") assert config1[0] == "/temp/config1/.isort.cfg" assert config1[1] == {"line_length": 71} - config1_2 = trie_root._search("/temp/config1/file1_2.py") + config1_2 = trie_root.search("/temp/config1/file1_2.py") assert config1_2[0] == "/temp/config1/.isort.cfg" assert config1_2[1] == {"line_length": 71} - config2 = trie_root._search("/temp/config2/subdir/subsubdir/file2.py") + config2 = trie_root.search("/temp/config2/subdir/subsubdir/file2.py") assert config2[0] == "/temp/config2/setup.cfg" assert config2[1] == {"line_length": 72} - config2_2 = trie_root._search("/temp/config2/subdir/file2_2.py") + config2_2 = trie_root.search("/temp/config2/subdir/file2_2.py") assert config2_2[0] == "/temp/config2/setup.cfg" assert config2_2[1] == {"line_length": 72} - config3 = trie_root._search("/temp/config3/subdir/subsubdir/subsubsubdir/file3.py") + config3 = trie_root.search("/temp/config3/subdir/subsubdir/subsubsubdir/file3.py") assert config3[0] == "/temp/config3/pyproject.toml" assert config3[1] == {"line_length": 73} - config3_2 = trie_root._search("/temp/config3/file3.py") + config3_2 = trie_root.search("/temp/config3/file3.py") assert config3_2[0] == "/temp/config3/pyproject.toml" assert config3_2[1] == {"line_length": 73} - config_outside = trie_root._search("/temp/file.py") + config_outside = trie_root.search("/temp/file.py") assert config_outside[0] == "default" assert config_outside[1] == {"line_length": 70} From 616f710796058719b0ad1a397bfe33b3f99fc6db Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner <mathieu.kniewallner@gmail.com> Date: Tue, 5 Oct 2021 21:43:06 +0200 Subject: [PATCH 32/54] chore(ci): run tests against Python 3.10 --- .github/workflows/test.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 892d89988..31e9d4dd0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10.0-rc.2"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] os: [ubuntu-latest, ubuntu-18.04, macos-latest, windows-latest] steps: @@ -53,11 +53,6 @@ jobs: python -m pip install --upgrade pip python -m pip install --upgrade poetry - # New poetry installer doesn't work well with Python 3.10 (see https://github.com/python-poetry/poetry/issues/4210). - - name: Use legacy poetry installer - if: startsWith(matrix.python-version, '3.10') - run: poetry config experimental.new-installer false - - name: Install dependencies run: poetry install From bc9c7fd42f5eab14319288d2d301978a07dce88e Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 09:33:05 +0530 Subject: [PATCH 33/54] Refactor the find_all_configs function --- isort/settings.py | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/isort/settings.py b/isort/settings.py index b0fd15a71..63ec6d44c 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -787,28 +787,32 @@ def _find_config(path: str) -> Tuple[str, Dict[str, Any]]: @lru_cache() -def find_all_configs(src_paths: Tuple[str]) -> Trie: - trie_root = Trie("default", DEFAULT_CONFIG.__dict__) - - for path in src_paths: - for (dirpath, _, _) in os.walk(path): - for config_file_name in CONFIG_SOURCES: - potential_config_file = os.path.join(dirpath, config_file_name) - if os.path.isfile(potential_config_file): - config_data: Dict[str, Any] - try: - config_data = _get_config_data( - potential_config_file, CONFIG_SECTIONS[config_file_name] - ) - except Exception: - warn( - f"Failed to pull configuration information from {potential_config_file}" - ) - config_data = {} +def find_all_configs(path: str) -> Trie: + """ + Looks for config files in the path provided and in all of its sub-directories. + Parses and stores any config file encountered in a trie and returns the root of + the trie + """ + trie_root = Trie("default", {}) - if config_data: - trie_root.insert(potential_config_file, config_data) - break + for (dirpath, _, _) in os.walk(path): + for config_file_name in CONFIG_SOURCES: + potential_config_file = os.path.join(dirpath, config_file_name) + if os.path.isfile(potential_config_file): + config_data: Dict[str, Any] + try: + config_data = _get_config_data( + potential_config_file, CONFIG_SECTIONS[config_file_name] + ) + except Exception: + warn( + f"Failed to pull configuration information from {potential_config_file}" + ) + config_data = {} + + if config_data: + trie_root.insert(potential_config_file, config_data) + break return trie_root From 59fff6c8077460f18bc315b173087326385d2cdf Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 09:34:06 +0530 Subject: [PATCH 34/54] Add config-root flag to let users explicitly set the path for resolving all config files --- isort/main.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/isort/main.py b/isort/main.py index afd230010..657ada8d3 100644 --- a/isort/main.py +++ b/isort/main.py @@ -260,6 +260,15 @@ def _build_arg_parser() -> argparse.ArgumentParser: help="Explicitly set the settings path or file instead of auto determining " "based on file location.", ) + general_group.add_argument( + "--cr", + "--config-root", + dest="config_root", + help="Explicitly set the config root for resolving all configs. When used " + "with the --resolve-all-configs flag, isort will look at all sub-folders " + "in this config root to resolve config files and sort files based on the " + "closest available config(if any)", + ) general_group.add_argument( "--resolve-all-configs", dest="resolve_all_configs", @@ -1089,7 +1098,7 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] = config_trie: Optional[Trie] = None if resolve_all_configs: - config_trie = find_all_configs(config_dict.get("src_paths", ("."))) + config_trie = find_all_configs(config_dict.pop("config_root", ".")) if "src_paths" in config_dict: config_dict["src_paths"] = { From daa37f4216a4c0eb12668dc10ea7cde92c88107e Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 09:35:06 +0530 Subject: [PATCH 35/54] Add test for resolve all configs flag --- tests/unit/test_main.py | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 2b13f9aa4..3d726a3c5 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -79,6 +79,7 @@ def test_parse_args(): assert main.parse_args(["--dont-follow-links"]) == {"follow_links": False} assert main.parse_args(["--overwrite-in-place"]) == {"overwrite_in_place": True} assert main.parse_args(["--from-first"]) == {"from_first": True} + assert main.parse_args(["--resolve-all-configs"]) == {"resolve_all_configs": True} def test_ascii_art(capsys): @@ -1211,3 +1212,78 @@ def main_check(args): out, error = main_check([str(git_project0), "--skip-gitignore", "--filter-files"]) assert all(f"{str(tmpdir)}{file}" in out for file in should_check) + + +def test_multiple_configs(capsys, tmpdir): + setup_cfg = """ +[isort] +from_first=True +""" + + pyproject_toml = """ +[tool.isort] +no_inline_sort = \"True\" +""" + + isort_cfg = """ +[settings] +force_single_line=True +""" + + dir1 = tmpdir / "subdir1" + dir2 = tmpdir / "subdir2" + dir3 = tmpdir / "subdir3" + + dir1.mkdir() + dir2.mkdir() + dir3.mkdir() + + setup_cfg_file = dir1 / "setup.cfg" + setup_cfg_file.write_text(setup_cfg, "utf-8") + + pyproject_toml_file = dir2 / "pyproject.toml" + pyproject_toml_file.write_text(pyproject_toml, "utf-8") + + isort_cfg_file = dir3 / ".isort.cfg" + isort_cfg_file.write_text(isort_cfg, "utf-8") + + import_section = """ +from a import y, z, x +import b +""" + + file1 = dir1 / "file1.py" + file1.write_text(import_section, "utf-8") + + file2 = dir2 / "file2.py" + file2.write_text(import_section, "utf-8") + + file3 = dir3 / "file3.py" + file3.write_text(import_section, "utf-8") + + file4 = tmpdir / "file4.py" + file4.write_text(import_section, "utf-8") + + main.main([str(tmpdir), "--resolve-all-configs", "--rp", str(tmpdir)]) + + assert file1.read() == """ +from a import x, y, z +import b +""" + +# assert file2.read() == """ +# import b +# from a import y, z, x +# """ +# +# assert file3.read() == """ +# import b +# from a import x +# from a import y +# from a import z +# """ +# +# assert file4.read() == """ +# import b +# from a import x, y z +# """ From 6f600cf301849f70607b00b057785433e820cb0d Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 09:42:56 +0530 Subject: [PATCH 36/54] Linting changes --- isort/settings.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/isort/settings.py b/isort/settings.py index 63ec6d44c..d0060d056 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -805,9 +805,7 @@ def find_all_configs(path: str) -> Trie: potential_config_file, CONFIG_SECTIONS[config_file_name] ) except Exception: - warn( - f"Failed to pull configuration information from {potential_config_file}" - ) + warn(f"Failed to pull configuration information from {potential_config_file}") config_data = {} if config_data: From 99898786c76c03ead57221a5521dee41477246a5 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 09:44:28 +0530 Subject: [PATCH 37/54] Correct linting errors and update tests --- tests/unit/test_main.py | 48 ++++++++++++++++++++++--------------- tests/unit/test_settings.py | 2 +- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 3d726a3c5..cc19f65ce 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -1264,26 +1264,36 @@ def test_multiple_configs(capsys, tmpdir): file4 = tmpdir / "file4.py" file4.write_text(import_section, "utf-8") - main.main([str(tmpdir), "--resolve-all-configs", "--rp", str(tmpdir)]) - - assert file1.read() == """ + main.main([str(tmpdir), "--resolve-all-configs", "--cr", str(tmpdir)]) + + assert ( + file1.read() + == """ from a import x, y, z import b """ + ) -# assert file2.read() == """ -# import b -# from a import y, z, x -# """ -# -# assert file3.read() == """ -# import b -# from a import x -# from a import y -# from a import z -# """ -# -# assert file4.read() == """ -# import b -# from a import x, y z -# """ + assert ( + file2.read() + == """ +import b +from a import y, z, x +""" + ) + assert ( + file3.read() + == """ +import b +from a import x +from a import y +from a import z +""" + ) + assert ( + file4.read() + == """ +import b +from a import x, y, z +""" + ) diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py index 119f1887d..d64e4173b 100644 --- a/tests/unit/test_settings.py +++ b/tests/unit/test_settings.py @@ -272,7 +272,7 @@ def test_find_all_configs(tmpdir): isort_cfg_file = dir3 / ".isort.cfg" isort_cfg_file.write_text(isort_cfg, "utf-8") - config_trie = settings.find_all_configs((str(tmpdir),)) + config_trie = settings.find_all_configs(str(tmpdir)) config_info_1 = config_trie.search(str(dir1 / "test1.py")) assert config_info_1[0] == str(setup_cfg_file) From 4435942a3e7d5aba351335302e44427e16a4da7a Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 14:49:15 +0530 Subject: [PATCH 38/54] Increase test coverage --- tests/unit/test_main.py | 2 +- tests/unit/test_settings.py | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index cc19f65ce..a317df89f 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -1264,7 +1264,7 @@ def test_multiple_configs(capsys, tmpdir): file4 = tmpdir / "file4.py" file4.write_text(import_section, "utf-8") - main.main([str(tmpdir), "--resolve-all-configs", "--cr", str(tmpdir)]) + main.main([str(tmpdir), "--resolve-all-configs", "--cr", str(tmpdir), "--verbose"]) assert ( file1.read() diff --git a/tests/unit/test_settings.py b/tests/unit/test_settings.py index d64e4173b..86354512c 100644 --- a/tests/unit/test_settings.py +++ b/tests/unit/test_settings.py @@ -255,13 +255,21 @@ def test_find_all_configs(tmpdir): [settings] profile=black """ + + pyproject_toml_broken = """ +[tool.isorts] +something = nothing +""" + dir1 = tmpdir / "subdir1" dir2 = tmpdir / "subdir2" dir3 = tmpdir / "subdir3" + dir4 = tmpdir / "subdir4" dir1.mkdir() dir2.mkdir() dir3.mkdir() + dir4.mkdir() setup_cfg_file = dir1 / "setup.cfg" setup_cfg_file.write_text(setup_cfg, "utf-8") @@ -272,19 +280,22 @@ def test_find_all_configs(tmpdir): isort_cfg_file = dir3 / ".isort.cfg" isort_cfg_file.write_text(isort_cfg, "utf-8") + pyproject_toml_file_broken = dir4 / "pyproject.toml" + pyproject_toml_file_broken.write_text(pyproject_toml_broken, "utf-8") + config_trie = settings.find_all_configs(str(tmpdir)) config_info_1 = config_trie.search(str(dir1 / "test1.py")) assert config_info_1[0] == str(setup_cfg_file) - assert "profile" in config_info_1[1] and config_info_1[1]["profile"] == "django" + assert config_info_1[0] == str(setup_cfg_file) and config_info_1[1]["profile"] == "django" config_info_2 = config_trie.search(str(dir2 / "test2.py")) assert config_info_2[0] == str(pyproject_toml_file) - assert "profile" in config_info_2[1] and config_info_2[1]["profile"] == "hug" + assert config_info_2[0] == str(pyproject_toml_file) and config_info_2[1]["profile"] == "hug" config_info_3 = config_trie.search(str(dir3 / "test3.py")) assert config_info_3[0] == str(isort_cfg_file) - assert "profile" in config_info_3[1] and config_info_3[1]["profile"] == "black" + assert config_info_3[0] == str(isort_cfg_file) and config_info_3[1]["profile"] == "black" config_info_4 = config_trie.search(str(tmpdir / "file4.py")) assert config_info_4[0] == "default" From 5e44c66c83693ed24c5c868ff5cbe496c987a511 Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Thu, 7 Oct 2021 23:27:31 +0530 Subject: [PATCH 39/54] Add test coverage --- tests/unit/test_main.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index a317df89f..dd6a417d0 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -1215,6 +1215,9 @@ def main_check(args): def test_multiple_configs(capsys, tmpdir): + # Ensure that --resolve-all-configs flag resolves multiple configs correctly + # and sorts files corresponding to their nearest config + setup_cfg = """ [isort] from_first=True @@ -1297,3 +1300,20 @@ def test_multiple_configs(capsys, tmpdir): from a import x, y, z """ ) + + # Ensure that --resolve-all-config flags works with --check + + file5 = dir1 / "file5.py" + file5.write( + """ +import b +from a import x, y, z + """ + ) + + with pytest.raises(SystemExit): + main.main([str(tmpdir), "--resolve-all-configs", "--cr", str(tmpdir), "--check"]) + + _, err = capsys.readouterr() + + assert f"{str(file5)} Imports are incorrectly sorted and/or formatted" in err From 65d983f594341f8b5c859252ef664bb9f15dbb10 Mon Sep 17 00:00:00 2001 From: MapleCCC <littlelittlemaple@gmail.com> Date: Fri, 8 Oct 2021 03:36:01 +0800 Subject: [PATCH 40/54] Fix typos in the help message 1. Several small typos are fixed. 2. The adjective "same" is always preceded by the article "the". 3. The word "etc." is always preceded by a comma. 4. The past participle of the verb "run" is "run" instead of "ran". 5. Add comma after an if clause. 6. Add space after a period and before another sentence. 7. Add space after a comma and before another word. --- isort/main.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/isort/main.py b/isort/main.py index a6661a076..3392bbd83 100644 --- a/isort/main.py +++ b/isort/main.py @@ -207,8 +207,8 @@ def _build_arg_parser() -> argparse.ArgumentParser: ) general_group.add_argument( "--overwrite-in-place", - help="Tells isort to overwrite in place using the same file handle." - "Comes at a performance and memory usage penalty over it's standard " + help="Tells isort to overwrite in place using the same file handle. " + "Comes at a performance and memory usage penalty over its standard " "approach but ensures all file flags and modes stay unchanged.", dest="overwrite_in_place", action="store_true", @@ -223,7 +223,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: "--show-files", dest="show_files", action="store_true", - help="See the files isort will be ran against with the current config options.", + help="See the files isort will be run against with the current config options.", ) general_group.add_argument( "--df", @@ -363,13 +363,13 @@ def _build_arg_parser() -> argparse.ArgumentParser: "--supported-extension", dest="supported_extensions", action="append", - help="Specifies what extensions isort can be ran against.", + help="Specifies what extensions isort can be run against.", ) target_group.add_argument( "--blocked-extension", dest="blocked_extensions", action="append", - help="Specifies what extensions isort can never be ran against.", + help="Specifies what extensions isort can never be run against.", ) target_group.add_argument( "--dont-follow-links", @@ -386,7 +386,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: "--allow-root", action="store_true", default=False, - help="Tells isort not to treat / specially, allowing it to be ran against the root dir.", + help="Tells isort not to treat / specially, allowing it to be run against the root dir.", ) output_group.add_argument( @@ -703,9 +703,9 @@ def _build_arg_parser() -> argparse.ArgumentParser: "--os", dest="only_sections", action="store_true", - help="Causes imports to be sorted based on their sections like STDLIB,THIRDPARTY etc. " + help="Causes imports to be sorted based on their sections like STDLIB, THIRDPARTY, etc. " "Within sections, the imports are ordered by their import style and the imports with " - "same style maintain their relative positions.", + "the same style maintain their relative positions.", ) section_group.add_argument( "--ds", @@ -805,7 +805,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: help="Force isort to recognize a module as part of Python's internal future compatibility " "libraries. WARNING: this overrides the behavior of __future__ handling and therefore" " can result in code that can't execute. If you're looking to add dependencies such " - "as six a better option is to create a another section below --future using custom " + "as six, a better option is to create another section below --future using custom " "sections. See: https://github.com/PyCQA/isort#custom-sections-and-ordering and the " "discussion here: https://github.com/PyCQA/isort/issues/1463.", ) From d6e3056579a03fcc2837aa47ec8f854a952dfbda Mon Sep 17 00:00:00 2001 From: SaucyGames05 <47290046+SaucyGames05@users.noreply.github.com> Date: Tue, 12 Oct 2021 02:24:14 -0700 Subject: [PATCH 41/54] Fixed unnecessary "elif" after "raise" Fixed unnecessary "elif" after "raise" on lines 200 and 228 --- isort/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/isort/api.py b/isort/api.py index 392c94ca6..f9097e4aa 100644 --- a/isort/api.py +++ b/isort/api.py @@ -197,7 +197,7 @@ def sort_stream( except SyntaxError: if extension not in CYTHON_EXTENSIONS: raise ExistingSyntaxErrors(content_source) - elif config.verbose: + if config.verbose: warn( f"{content_source} Python AST errors found but ignored due to Cython extension" ) @@ -225,7 +225,7 @@ def sort_stream( except SyntaxError: # pragma: no cover if extension not in CYTHON_EXTENSIONS: raise IntroducedSyntaxErrors(content_source) - elif config.verbose: + if config.verbose: warn( f"{content_source} Python AST errors found but ignored due to Cython extension" ) From 8797ac7fb3790b836a4ac04dc32f2be8b54fe71a Mon Sep 17 00:00:00 2001 From: Aniruddha <aniruddha97bhatt@gmail.com> Date: Fri, 15 Oct 2021 10:11:57 +0530 Subject: [PATCH 42/54] Increase test coverage --- tests/unit/test_main.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index dd6a417d0..66ac0b02c 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -1231,15 +1231,22 @@ def test_multiple_configs(capsys, tmpdir): isort_cfg = """ [settings] force_single_line=True +""" + + broken_isort_cfg = """ +[iaort_confg] +force_single_line=True """ dir1 = tmpdir / "subdir1" dir2 = tmpdir / "subdir2" dir3 = tmpdir / "subdir3" + dir4 = tmpdir / "subdir4" dir1.mkdir() dir2.mkdir() dir3.mkdir() + dir4.mkdir() setup_cfg_file = dir1 / "setup.cfg" setup_cfg_file.write_text(setup_cfg, "utf-8") @@ -1250,6 +1257,9 @@ def test_multiple_configs(capsys, tmpdir): isort_cfg_file = dir3 / ".isort.cfg" isort_cfg_file.write_text(isort_cfg, "utf-8") + broken_isort_cfg_file = dir4 / ".isort.cfg" + broken_isort_cfg_file.write_text(broken_isort_cfg, "utf-8") + import_section = """ from a import y, z, x import b @@ -1264,10 +1274,20 @@ def test_multiple_configs(capsys, tmpdir): file3 = dir3 / "file3.py" file3.write_text(import_section, "utf-8") - file4 = tmpdir / "file4.py" + file4 = dir4 / "file4.py" file4.write_text(import_section, "utf-8") + file5 = tmpdir / "file5.py" + file5.write_text(import_section, "utf-8") + main.main([str(tmpdir), "--resolve-all-configs", "--cr", str(tmpdir), "--verbose"]) + out, _ = capsys.readouterr() + + assert f"{str(setup_cfg_file)} used for file {str(file1)}" in out + assert f"{str(pyproject_toml_file)} used for file {str(file2)}" in out + assert f"{str(isort_cfg_file)} used for file {str(file3)}" in out + assert f"default used for file {str(file4)}" in out + assert f"default used for file {str(file5)}" in out assert ( file1.read() @@ -1301,10 +1321,18 @@ def test_multiple_configs(capsys, tmpdir): """ ) + assert ( + file5.read() + == """ +import b +from a import x, y, z +""" + ) + # Ensure that --resolve-all-config flags works with --check - file5 = dir1 / "file5.py" - file5.write( + file6 = dir1 / "file6.py" + file6.write( """ import b from a import x, y, z @@ -1316,4 +1344,4 @@ def test_multiple_configs(capsys, tmpdir): _, err = capsys.readouterr() - assert f"{str(file5)} Imports are incorrectly sorted and/or formatted" in err + assert f"{str(file6)} Imports are incorrectly sorted and/or formatted" in err From 36eab1223bc729c7d711b6e24d3f0fc00c3133be Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Sat, 16 Oct 2021 22:31:25 -0700 Subject: [PATCH 43/54] Update packages --- poetry.lock | 475 ++++++++++++++++++++++++++-------------------------- 1 file changed, 241 insertions(+), 234 deletions(-) diff --git a/poetry.lock b/poetry.lock index cf8167dc6..575f0adfa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -16,7 +16,7 @@ python-versions = "*" [[package]] name = "arrow" -version = "1.1.1" +version = "1.2.0" description = "Better dates & times for Python" category = "dev" optional = false @@ -138,7 +138,7 @@ python-versions = ">=2.7" [[package]] name = "certifi" -version = "2021.5.30" +version = "2021.10.8" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -146,7 +146,7 @@ python-versions = "*" [[package]] name = "cfgv" -version = "3.3.0" +version = "3.3.1" description = "Validate configuration and produce human readable error messages." category = "dev" optional = false @@ -162,7 +162,7 @@ python-versions = "*" [[package]] name = "charset-normalizer" -version = "2.0.4" +version = "2.0.7" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -218,7 +218,7 @@ six = ">=1.10" [[package]] name = "coverage" -version = "6.0b1" +version = "6.0.2" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -255,7 +255,7 @@ python-versions = ">=3.6, <3.7" [[package]] name = "decorator" -version = "5.0.9" +version = "5.1.0" description = "Decorators for Humans" category = "dev" optional = false @@ -263,7 +263,7 @@ python-versions = ">=3.5" [[package]] name = "distlib" -version = "0.3.2" +version = "0.3.3" description = "Distribution utilities" category = "main" optional = false @@ -353,11 +353,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "filelock" -version = "3.0.12" +version = "3.3.1" description = "A platform independent file lock." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" + +[package.extras] +docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] +testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] [[package]] name = "flake8" @@ -398,7 +402,7 @@ flake8 = "*" [[package]] name = "ghp-import" -version = "2.0.1" +version = "2.0.2" description = "Copy your docs directly to the gh-pages branch." category = "dev" optional = false @@ -408,7 +412,7 @@ python-versions = "*" python-dateutil = ">=2.8.1" [package.extras] -dev = ["twine", "markdown", "flake8"] +dev = ["twine", "markdown", "flake8", "wheel"] [[package]] name = "gitdb" @@ -474,7 +478,7 @@ python-versions = "*" [[package]] name = "hstspreload" -version = "2021.8.1" +version = "2021.10.1" description = "Chromium HSTS Preload list as a Python package" category = "dev" optional = false @@ -532,7 +536,7 @@ python-versions = "*" [[package]] name = "hypothesis" -version = "6.14.6" +version = "6.23.2" description = "A library for property-based testing" category = "dev" optional = false @@ -575,7 +579,7 @@ pytest = ["pytest (>=4.0.0,<5.0.0)"] [[package]] name = "hypothesmith" -version = "0.1.8" +version = "0.1.9" description = "Hypothesis strategies for generating Python programs, something like CSmith" category = "dev" optional = false @@ -588,7 +592,7 @@ libcst = ">=0.3.8" [[package]] name = "identify" -version = "2.2.13" +version = "2.3.0" description = "File identification library for Python" category = "dev" optional = false @@ -621,7 +625,7 @@ test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (>=0.91 [[package]] name = "importlib-metadata" -version = "4.6.3" +version = "4.8.1" description = "Read metadata from Python packages" category = "main" optional = false @@ -715,7 +719,7 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] [[package]] name = "jinja2" -version = "3.0.1" +version = "3.0.2" description = "A very fast and expressive template engine." category = "dev" optional = false @@ -741,7 +745,7 @@ jinja2 = "*" [[package]] name = "lark-parser" -version = "0.11.3" +version = "0.12.0" description = "a modern parsing library" category = "dev" optional = false @@ -754,7 +758,7 @@ regex = ["regex"] [[package]] name = "libcst" -version = "0.3.20" +version = "0.3.21" description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7 and 3.8 programs." category = "dev" optional = false @@ -767,7 +771,7 @@ typing-extensions = ">=3.7.4.2" typing-inspect = ">=0.4.0" [package.extras] -dev = ["black (==20.8b1)", "codecov (>=2.1.4)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "isort (==5.5.3)", "jupyter (>=1.0.0)", "nbsphinx (>=0.4.2)", "pyre-check (==0.0.41)", "sphinx-rtd-theme (>=0.4.3)", "prompt-toolkit (>=2.0.9)", "tox (>=3.18.1)"] +dev = ["black (==20.8b1)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jupyter (>=1.0.0)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.3)", "setuptools-scm (>=6.0.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.18.1)", "ufmt (==1.2)", "usort (==0.6.3)"] [[package]] name = "livereload" @@ -783,7 +787,7 @@ tornado = {version = "*", markers = "python_version > \"2.7\""} [[package]] name = "mako" -version = "1.1.4" +version = "1.1.5" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." category = "dev" optional = false @@ -874,14 +878,11 @@ pymdown-extensions = ">=7.0" [[package]] name = "mkdocs-material-extensions" -version = "1.0.1" +version = "1.0.3" description = "Extension pack for Python Markdown." category = "dev" optional = false -python-versions = ">=3.5" - -[package.dependencies] -mkdocs-material = ">=5.0.0" +python-versions = ">=3.6" [[package]] name = "mypy" @@ -1086,7 +1087,7 @@ yarg = "*" [[package]] name = "platformdirs" -version = "2.2.0" +version = "2.4.0" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false @@ -1115,17 +1116,18 @@ validation = ["cerberus"] [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "portray" @@ -1156,7 +1158,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pre-commit" -version = "2.14.0" +version = "2.15.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false @@ -1255,7 +1257,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.9.0" +version = "2.10.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false @@ -1296,7 +1298,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.4" +version = "6.2.5" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -1309,7 +1311,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" toml = "*" @@ -1390,11 +1392,11 @@ unidecode = ["Unidecode (>=1.1.1)"] [[package]] name = "pyyaml" -version = "5.4.1" +version = "6.0" description = "YAML parser and emitter for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" [[package]] name = "pyyaml-env-tag" @@ -1409,7 +1411,7 @@ pyyaml = "*" [[package]] name = "regex" -version = "2021.8.3" +version = "2021.10.8" description = "Alternative regular expression module, to replace re." category = "dev" optional = false @@ -1543,7 +1545,7 @@ python-versions = "*" [[package]] name = "stevedore" -version = "3.3.0" +version = "3.4.0" description = "Manage dynamic plugins for Python applications" category = "dev" optional = false @@ -1636,7 +1638,7 @@ doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown- [[package]] name = "types-colorama" -version = "0.4.3" +version = "0.4.4" description = "Typing stubs for colorama" category = "dev" optional = false @@ -1660,7 +1662,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "3.10.0.0" +version = "3.10.0.2" description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false @@ -1680,7 +1682,7 @@ typing-extensions = ">=3.7.4" [[package]] name = "urllib3" -version = "1.26.6" +version = "1.26.7" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -1693,7 +1695,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.7.2" +version = "20.8.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1741,14 +1743,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "watchdog" -version = "2.1.3" +version = "2.1.6" description = "Filesystem events monitoring" category = "dev" optional = false python-versions = ">=3.6" [package.extras] -watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] +watchmedo = ["PyYAML (>=3.10)"] [[package]] name = "wcwidth" @@ -1779,7 +1781,7 @@ python-versions = "*" [[package]] name = "zipp" -version = "3.5.0" +version = "3.6.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -1810,8 +1812,8 @@ appnope = [ {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, ] arrow = [ - {file = "arrow-1.1.1-py3-none-any.whl", hash = "sha256:77a60a4db5766d900a2085ce9074c5c7b8e2c99afeaa98ad627637ff6f292510"}, - {file = "arrow-1.1.1.tar.gz", hash = "sha256:dee7602f6c60e3ec510095b5e301441bc56288cb8f51def14dcb3079f623823a"}, + {file = "arrow-1.2.0-py3-none-any.whl", hash = "sha256:8fb7d9d3d4bf90e49e734c22fa077bdd0964135c4b8120de2510575a8d1f620c"}, + {file = "arrow-1.2.0.tar.gz", hash = "sha256:16fc29bbd9e425e3eb0fef3018297910a0f4568f21116fc31771e2760a50e074"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -1848,20 +1850,20 @@ cerberus = [ {file = "Cerberus-1.3.4.tar.gz", hash = "sha256:d1b21b3954b2498d9a79edf16b3170a3ac1021df88d197dc2ce5928ba519237c"}, ] certifi = [ - {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, - {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, ] cfgv = [ - {file = "cfgv-3.3.0-py2.py3-none-any.whl", hash = "sha256:b449c9c6118fe8cca7fa5e00b9ec60ba08145d281d52164230a69211c5d597a1"}, - {file = "cfgv-3.3.0.tar.gz", hash = "sha256:9e600479b3b99e8af981ecdfc80a0296104ee610cab48a5ae4ffd0b668650eb1"}, + {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, + {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.0.4.tar.gz", hash = "sha256:f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"}, - {file = "charset_normalizer-2.0.4-py3-none-any.whl", hash = "sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b"}, + {file = "charset-normalizer-2.0.7.tar.gz", hash = "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0"}, + {file = "charset_normalizer-2.0.7-py3-none-any.whl", hash = "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -1879,36 +1881,39 @@ cookiecutter = [ {file = "cookiecutter-1.7.3.tar.gz", hash = "sha256:6b9a4d72882e243be077a7397d0f1f76fe66cf3df91f3115dbb5330e214fa457"}, ] coverage = [ - {file = "coverage-6.0b1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:da7de6e4162c69cc03cc56b7d051ae11147ac30872ff57df4ba4cac6d70ce5d9"}, - {file = "coverage-6.0b1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:23c1611471cbfa2ac0e283862a76a333c13e5e7c4d499feb9919a5f52884610e"}, - {file = "coverage-6.0b1-cp310-cp310-win_amd64.whl", hash = "sha256:ddb2287f66500ac57b24cce60341074b148977b74cd20eca755f95262928086f"}, - {file = "coverage-6.0b1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c8099c7033fb1ca73ac2246c3e52f45dd6a9c3826c59b3b5ad94e5be4e08d99b"}, - {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdaa96733c9cf85491ad406fd78aa16025a1ea468951545b3da7ee133c150c7a"}, - {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9981294b131023e63061ba88f4498fe27b9b15d908079d1866ee66a63d6e793f"}, - {file = "coverage-6.0b1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea784c96ca3b94912176d7adc9c4bb7d1988f36a0223a9ac128f4c834775202c"}, - {file = "coverage-6.0b1-cp36-cp36m-win32.whl", hash = "sha256:7beec4df7542cf681356ef243fee3bf948775fc0d125bdcad3508e834229e07d"}, - {file = "coverage-6.0b1-cp36-cp36m-win_amd64.whl", hash = "sha256:84a1000f622d1df8824cd1ac629aa8392679c5c4de3f0de9e6889373f99ff3a0"}, - {file = "coverage-6.0b1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c1630e847ae0a2a366f18ddc3e017b69f80d729e95830579c61b5f9e9b94b91e"}, - {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a585ba4087cc1fb5bfe34d1ecaaee183b854427992be2b42f1722ba8289fa82"}, - {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:16db4173575901db8f3e6cc05e50fe19c7849b0256f6dc2e0979485184053417"}, - {file = "coverage-6.0b1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a8826f6ecf079cb648534790ba59218a64e12a59bf2cd9ff00199abb39864a79"}, - {file = "coverage-6.0b1-cp37-cp37m-win32.whl", hash = "sha256:40e30139113b141c238620b700aa5bd5c1b3a7b29ae47398936ff1c9166109d9"}, - {file = "coverage-6.0b1-cp37-cp37m-win_amd64.whl", hash = "sha256:95d2293d6a60da8952c675050231c02c9f4f1c1b9cf916315173e921d137d683"}, - {file = "coverage-6.0b1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22888d3ce1b6fa1125f0be1602d8c634e00e7ec3a87bdb594ad87bde0b00b2b6"}, - {file = "coverage-6.0b1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6fbe69d52628b3e8a144265fd134f5da07cf287a00cf529730ae10380d315b2"}, - {file = "coverage-6.0b1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f0b250a03891255feb3ae69ac29d05cf9a62f5869bb8bac0e7f4968e7274efac"}, - {file = "coverage-6.0b1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:951e8d7bc98bceb61fc4fb426966fae854160301c0f8cd0945c62f2504f68615"}, - {file = "coverage-6.0b1-cp38-cp38-win32.whl", hash = "sha256:e6a4260f0abf90c023b4f838905f645695b31666b76837152e2befad3d1ef5d6"}, - {file = "coverage-6.0b1-cp38-cp38-win_amd64.whl", hash = "sha256:ceb872b89c6461d4365be5f8fbf14f867be6b5217760980de7e014e54648f8ef"}, - {file = "coverage-6.0b1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2dcc6d62b69a82759e5dddd788e09dd329124e493e62d92cfd01c0b918d7e511"}, - {file = "coverage-6.0b1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97b387f2744762b9984639b59abd7abb46ea6ae2ea24cb7c07893612328559b"}, - {file = "coverage-6.0b1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4528368196a90f11b70fb5668c13d92e88ba795eb4d37aab5855fd0479db417b"}, - {file = "coverage-6.0b1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18183948d5480e2ae30ad67edddf748149c778592b7e4ee649c058d5de2dcbb1"}, - {file = "coverage-6.0b1-cp39-cp39-win32.whl", hash = "sha256:91cd79f0f2996a4de737de89fdcbcd379a5bfd7b15129378ad1e5fc234e58d33"}, - {file = "coverage-6.0b1-cp39-cp39-win_amd64.whl", hash = "sha256:4cbdc51fc8c00ec6e53b30221d5757034aecf9839761bf97eaec0db7f0ff4955"}, - {file = "coverage-6.0b1-pp36-none-any.whl", hash = "sha256:8394626a07e0a1b3695a16a4548d32e7259e00817d4bab1ef8172a1bd82a724e"}, - {file = "coverage-6.0b1-pp37-none-any.whl", hash = "sha256:79c136327e90ee46a2b3094263df94da5212890d6145678741eb805d79714971"}, - {file = "coverage-6.0b1.tar.gz", hash = "sha256:c6f46d5bbec8fe1ff25215356e819528a90d84b2801703514746b665742f1cd2"}, + {file = "coverage-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7"}, + {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd"}, + {file = "coverage-6.0.2-cp310-cp310-win32.whl", hash = "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7"}, + {file = "coverage-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d"}, + {file = "coverage-6.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9"}, + {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2"}, + {file = "coverage-6.0.2-cp36-cp36m-win32.whl", hash = "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122"}, + {file = "coverage-6.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9"}, + {file = "coverage-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc"}, + {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1"}, + {file = "coverage-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330"}, + {file = "coverage-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1"}, + {file = "coverage-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc"}, + {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb"}, + {file = "coverage-6.0.2-cp38-cp38-win32.whl", hash = "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f"}, + {file = "coverage-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9"}, + {file = "coverage-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0"}, + {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe"}, + {file = "coverage-6.0.2-cp39-cp39-win32.whl", hash = "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce"}, + {file = "coverage-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9"}, + {file = "coverage-6.0.2-pp36-none-any.whl", hash = "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164"}, + {file = "coverage-6.0.2-pp37-none-any.whl", hash = "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895"}, + {file = "coverage-6.0.2.tar.gz", hash = "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149"}, ] cruft = [ {file = "cruft-2.9.0-py3-none-any.whl", hash = "sha256:6e77ff2f59a2e2aee7c54ebf302b5a4dd231af44e5971d5ad60135c9e7f4c29d"}, @@ -1919,12 +1924,12 @@ dataclasses = [ {file = "dataclasses-0.7.tar.gz", hash = "sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"}, ] decorator = [ - {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"}, - {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"}, + {file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"}, + {file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"}, ] distlib = [ - {file = "distlib-0.3.2-py2.py3-none-any.whl", hash = "sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"}, - {file = "distlib-0.3.2.zip", hash = "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736"}, + {file = "distlib-0.3.3-py2.py3-none-any.whl", hash = "sha256:c8b54e8454e5bf6237cc84c20e8264c3e991e824ef27e8f1e81049867d861e31"}, + {file = "distlib-0.3.3.zip", hash = "sha256:d982d0751ff6eaaab5e2ec8e691d949ee80eddf01a62eaa96ddb11531fe16b05"}, ] docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, @@ -1969,8 +1974,8 @@ falcon = [ {file = "falcon-2.0.0.tar.gz", hash = "sha256:eea593cf466b9c126ce667f6d30503624ef24459f118c75594a69353b6c3d5fc"}, ] filelock = [ - {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, - {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, + {file = "filelock-3.3.1-py3-none-any.whl", hash = "sha256:2b5eb3589e7fdda14599e7eb1a50e09b4cc14f34ed98b8ba56d33bfaafcbef2f"}, + {file = "filelock-3.3.1.tar.gz", hash = "sha256:34a9f35f95c441e7b38209775d6e0337f9a3759f3565f6c5798f19618527c76f"}, ] flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, @@ -1985,7 +1990,8 @@ flake8-polyfill = [ {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, ] ghp-import = [ - {file = "ghp-import-2.0.1.tar.gz", hash = "sha256:753de2eace6e0f7d4edfb3cce5e3c3b98cd52aadb80163303d1d036bda7b4483"}, + {file = "ghp-import-2.0.2.tar.gz", hash = "sha256:947b3771f11be850c852c64b561c600fdddf794bab363060854c1ee7ad05e071"}, + {file = "ghp_import-2.0.2-py3-none-any.whl", hash = "sha256:5f8962b30b20652cdffa9c5a9812f7de6bcb56ec475acac579807719bf242c46"}, ] gitdb = [ {file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"}, @@ -2012,8 +2018,8 @@ hpack = [ {file = "hpack-3.0.0.tar.gz", hash = "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"}, ] hstspreload = [ - {file = "hstspreload-2021.8.1-py3-none-any.whl", hash = "sha256:6c1bf74072f5bc01d688fe66835eca6e4bb1352368bf0c9c68292696455f457f"}, - {file = "hstspreload-2021.8.1.tar.gz", hash = "sha256:d51c2c2c183ec0001399b0473ffb200eb75451110b27897e65efd2fe1d70b9be"}, + {file = "hstspreload-2021.10.1-py3-none-any.whl", hash = "sha256:4115ea63e87b4bea3c01a5a4e5d74993485811e0ed16d9a71dec453e2c731b65"}, + {file = "hstspreload-2021.10.1.tar.gz", hash = "sha256:5bb90f438bec40faf320170ee48cf1978f40423ee1ba39a57bb686f3f9c061c7"}, ] httpcore = [ {file = "httpcore-0.9.1-py3-none-any.whl", hash = "sha256:9850fe97a166a794d7e920590d5ec49a05488884c9fc8b5dba8561effab0c2a0"}, @@ -2032,20 +2038,20 @@ hyperframe = [ {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, ] hypothesis = [ - {file = "hypothesis-6.14.6-py3-none-any.whl", hash = "sha256:a776b4545e8ad54c68f001591cd5c39c8c05dfd340d0cf974112bf89439f126b"}, - {file = "hypothesis-6.14.6.tar.gz", hash = "sha256:2586eae07e48b35ab5a2d61d607d29ba76939ce140c427d66ccf5db4ddc788d2"}, + {file = "hypothesis-6.23.2-py3-none-any.whl", hash = "sha256:ffe81bf1e3122edfcdbf21b31a0b8db3759fac6b87cdc2f9ae32cd360311ccf4"}, + {file = "hypothesis-6.23.2.tar.gz", hash = "sha256:b71b257916c91484716a10220ed2b9a0cf82acc3ed8ef421bb2aa0a671761053"}, ] hypothesis-auto = [ {file = "hypothesis-auto-1.1.4.tar.gz", hash = "sha256:5e2c2fb09dc09842512d80630bb792359a1d33d2c0473ad47ee23da0be9e32b1"}, {file = "hypothesis_auto-1.1.4-py3-none-any.whl", hash = "sha256:fea8560c4522c0fd490ed8cc17e420b95dabebb11b9b334c59bf2d768839015f"}, ] hypothesmith = [ - {file = "hypothesmith-0.1.8-py3-none-any.whl", hash = "sha256:6248c3d0e0dc934e5352e3f7d79290560ab5861847ca6701e410f9a287461216"}, - {file = "hypothesmith-0.1.8.tar.gz", hash = "sha256:f9ff047b15c4ed312ce3da57ea27570f86d6b53ce12af9f25e59e6576a00410a"}, + {file = "hypothesmith-0.1.9-py3-none-any.whl", hash = "sha256:f5337fb5fce2f798b356daeb0721566a3e5c696d3a7873aff956753881217768"}, + {file = "hypothesmith-0.1.9.tar.gz", hash = "sha256:039fd6aa0102f89df9df7ad4cff70aa8068678c13c3be2713c92568917317a04"}, ] identify = [ - {file = "identify-2.2.13-py2.py3-none-any.whl", hash = "sha256:7199679b5be13a6b40e6e19ea473e789b11b4e3b60986499b1f589ffb03c217c"}, - {file = "identify-2.2.13.tar.gz", hash = "sha256:7bc6e829392bd017236531963d2d937d66fc27cadc643ac0aba2ce9f26157c79"}, + {file = "identify-2.3.0-py2.py3-none-any.whl", hash = "sha256:d1e82c83d063571bb88087676f81261a4eae913c492dafde184067c584bc7c05"}, + {file = "identify-2.3.0.tar.gz", hash = "sha256:fd08c97f23ceee72784081f1ce5125c8f53a02d3f2716dde79a6ab8f1039fea5"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -2081,8 +2087,8 @@ immutables = [ {file = "immutables-0.16.tar.gz", hash = "sha256:d67e86859598eed0d926562da33325dac7767b7b1eff84e232c22abea19f4360"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.6.3-py3-none-any.whl", hash = "sha256:51c6635429c77cf1ae634c997ff9e53ca3438b495f10a55ba28594dd69764a8b"}, - {file = "importlib_metadata-4.6.3.tar.gz", hash = "sha256:0645585859e9a6689c523927a5032f2ba5919f1f7d0e84bd4533312320de1ff9"}, + {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, + {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, ] importlib-resources = [ {file = "importlib_resources-5.2.2-py3-none-any.whl", hash = "sha256:2480d8e07d1890056cb53c96e3de44fead9c62f2ba949b0f2e4c4345f4afa977"}, @@ -2105,48 +2111,39 @@ jedi = [ {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, ] jinja2 = [ - {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, - {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, + {file = "Jinja2-3.0.2-py3-none-any.whl", hash = "sha256:8569982d3f0889eed11dd620c706d39b60c36d6d25843961f33f77fb6bc6b20c"}, + {file = "Jinja2-3.0.2.tar.gz", hash = "sha256:827a0e32839ab1600d4eb1c4c33ec5a8edfbc5cb42dafa13b81f182f97784b45"}, ] jinja2-time = [ {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, ] lark-parser = [ - {file = "lark-parser-0.11.3.tar.gz", hash = "sha256:e29ca814a98bb0f81674617d878e5f611cb993c19ea47f22c80da3569425f9bd"}, + {file = "lark-parser-0.12.0.tar.gz", hash = "sha256:15967db1f1214013dca65b1180745047b9be457d73da224fcda3d9dd4e96a138"}, + {file = "lark_parser-0.12.0-py2.py3-none-any.whl", hash = "sha256:0eaf30cb5ba787fe404d73a7d6e61df97b21d5a63ac26c5008c78a494373c675"}, ] libcst = [ - {file = "libcst-0.3.20-py3-none-any.whl", hash = "sha256:d213e833fdbad43c4fcaf9c952a695b36d601dce1c527ec724e75aa36e60834f"}, - {file = "libcst-0.3.20.tar.gz", hash = "sha256:9d50d4eab28b570e254cc63287ce3009b945be4114c7a29662b67204cfc18060"}, + {file = "libcst-0.3.21-py3-none-any.whl", hash = "sha256:a9c6fea4fa3bf92f87e40c6850dec099aaa7aaf963a934c763844544b32d3a1e"}, + {file = "libcst-0.3.21.tar.gz", hash = "sha256:4302a8f09cd9e5ab5962f8e126d032bba98541893dd38cce6b4770969fed059d"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, ] mako = [ - {file = "Mako-1.1.4-py2.py3-none-any.whl", hash = "sha256:aea166356da44b9b830c8023cd9b557fa856bd8b4035d6de771ca027dfc5cc6e"}, - {file = "Mako-1.1.4.tar.gz", hash = "sha256:17831f0b7087c313c0ffae2bcbbd3c1d5ba9eeac9c38f2eb7b50e8c99fe9d5ab"}, + {file = "Mako-1.1.5-py2.py3-none-any.whl", hash = "sha256:6804ee66a7f6a6416910463b00d76a7b25194cd27f1918500c5bd7be2a088a23"}, + {file = "Mako-1.1.5.tar.gz", hash = "sha256:169fa52af22a91900d852e937400e79f535496191c63712e3b9fda5a9bed6fc3"}, ] markdown = [ {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"}, {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -2155,21 +2152,14 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -2179,9 +2169,6 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, @@ -2203,8 +2190,8 @@ mkdocs-material = [ {file = "mkdocs_material-7.2.3-py2.py3-none-any.whl", hash = "sha256:039ce80555ba457faa10af993c57e9b6469918c6a5427851dcdd65591cc47fac"}, ] mkdocs-material-extensions = [ - {file = "mkdocs-material-extensions-1.0.1.tar.gz", hash = "sha256:6947fb7f5e4291e3c61405bad3539d81e0b3cd62ae0d66ced018128af509c68f"}, - {file = "mkdocs_material_extensions-1.0.1-py3-none-any.whl", hash = "sha256:d90c807a88348aa6d1805657ec5c0b2d8d609c110e62b9dce4daf7fa981fa338"}, + {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"}, + {file = "mkdocs_material_extensions-1.0.3-py3-none-any.whl", hash = "sha256:a82b70e533ce060b2a5d9eb2bc2e1be201cf61f901f93704b4acf6e3d5983a44"}, ] mypy = [ {file = "mypy-0.902-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3f12705eabdd274b98f676e3e5a89f247ea86dc1af48a2d5a2b080abac4e1243"}, @@ -2299,16 +2286,16 @@ pipreqs = [ {file = "pipreqs-0.4.10.tar.gz", hash = "sha256:9e351d644b28b98d7386b046a73806cbb3bb66b23a30e74feeb95ed9571db939"}, ] platformdirs = [ - {file = "platformdirs-2.2.0-py3-none-any.whl", hash = "sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c"}, - {file = "platformdirs-2.2.0.tar.gz", hash = "sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e"}, + {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, + {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, ] plette = [ {file = "plette-0.2.3-py2.py3-none-any.whl", hash = "sha256:d6c9b96981b347bddd333910b753b6091a2c1eb2ef85bb373b4a67c9d91dca16"}, {file = "plette-0.2.3.tar.gz", hash = "sha256:46402c03e36d6eadddad2a5125990e322dd74f98160c8f2dcd832b2291858a26"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] portray = [ {file = "portray-1.7.0-py3-none-any.whl", hash = "sha256:fb4467105d948fabf0ec35b11af50f3c0c4f2aabaa31d5dcd657fadb1c6132e1"}, @@ -2319,8 +2306,8 @@ poyo = [ {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"}, ] pre-commit = [ - {file = "pre_commit-2.14.0-py2.py3-none-any.whl", hash = "sha256:ec3045ae62e1aa2eecfb8e86fa3025c2e3698f77394ef8d2011ce0aedd85b2d4"}, - {file = "pre_commit-2.14.0.tar.gz", hash = "sha256:2386eeb4cf6633712c7cc9ede83684d53c8cafca6b59f79c738098b51c6d206c"}, + {file = "pre_commit-2.15.0-py2.py3-none-any.whl", hash = "sha256:a4ed01000afcb484d9eb8d504272e642c4c4099bbad3a6b27e519bd6a3e928a6"}, + {file = "pre_commit-2.15.0.tar.gz", hash = "sha256:3c25add78dbdfb6a28a651780d5c311ac40dd17f160eb3954a0c59da40a505a7"}, ] prompt-toolkit = [ {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, @@ -2374,8 +2361,8 @@ pyflakes = [ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ - {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, - {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, + {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, + {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"}, ] pylama = [ {file = "pylama-7.7.1-py2.py3-none-any.whl", hash = "sha256:fd61c11872d6256b019ef1235be37b77c922ef37ac9797df6bd489996dddeb15"}, @@ -2390,8 +2377,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.4-py3-none-any.whl", hash = "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"}, - {file = "pytest-6.2.4.tar.gz", hash = "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b"}, + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] pytest-benchmark = [ {file = "pytest-benchmark-3.4.1.tar.gz", hash = "sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47"}, @@ -2414,74 +2401,92 @@ python-slugify = [ {file = "python_slugify-5.0.2-py2.py3-none-any.whl", hash = "sha256:6d8c5df75cd4a7c3a2d21e257633de53f52ab0265cd2d1dc62a730e8194a7380"}, ] pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] pyyaml-env-tag = [ {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] regex = [ - {file = "regex-2021.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8764a78c5464ac6bde91a8c87dd718c27c1cabb7ed2b4beaf36d3e8e390567f9"}, - {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4551728b767f35f86b8e5ec19a363df87450c7376d7419c3cac5b9ceb4bce576"}, - {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:577737ec3d4c195c4aef01b757905779a9e9aee608fa1cf0aec16b5576c893d3"}, - {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c856ec9b42e5af4fe2d8e75970fcc3a2c15925cbcc6e7a9bcb44583b10b95e80"}, - {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3835de96524a7b6869a6c710b26c90e94558c31006e96ca3cf6af6751b27dca1"}, - {file = "regex-2021.8.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cea56288eeda8b7511d507bbe7790d89ae7049daa5f51ae31a35ae3c05408531"}, - {file = "regex-2021.8.3-cp36-cp36m-win32.whl", hash = "sha256:a4eddbe2a715b2dd3849afbdeacf1cc283160b24e09baf64fa5675f51940419d"}, - {file = "regex-2021.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:57fece29f7cc55d882fe282d9de52f2f522bb85290555b49394102f3621751ee"}, - {file = "regex-2021.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a5c6dbe09aff091adfa8c7cfc1a0e83fdb8021ddb2c183512775a14f1435fe16"}, - {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff4a8ad9638b7ca52313d8732f37ecd5fd3c8e3aff10a8ccb93176fd5b3812f6"}, - {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b63e3571b24a7959017573b6455e05b675050bbbea69408f35f3cb984ec54363"}, - {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fbc20975eee093efa2071de80df7f972b7b35e560b213aafabcec7c0bd00bd8c"}, - {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14caacd1853e40103f59571f169704367e79fb78fac3d6d09ac84d9197cadd16"}, - {file = "regex-2021.8.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb350eb1060591d8e89d6bac4713d41006cd4d479f5e11db334a48ff8999512f"}, - {file = "regex-2021.8.3-cp37-cp37m-win32.whl", hash = "sha256:18fdc51458abc0a974822333bd3a932d4e06ba2a3243e9a1da305668bd62ec6d"}, - {file = "regex-2021.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:026beb631097a4a3def7299aa5825e05e057de3c6d72b139c37813bfa351274b"}, - {file = "regex-2021.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:16d9eaa8c7e91537516c20da37db975f09ac2e7772a0694b245076c6d68f85da"}, - {file = "regex-2021.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3905c86cc4ab6d71635d6419a6f8d972cab7c634539bba6053c47354fd04452c"}, - {file = "regex-2021.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937b20955806381e08e54bd9d71f83276d1f883264808521b70b33d98e4dec5d"}, - {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:28e8af338240b6f39713a34e337c3813047896ace09d51593d6907c66c0708ba"}, - {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c09d88a07483231119f5017904db8f60ad67906efac3f1baa31b9b7f7cca281"}, - {file = "regex-2021.8.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:85f568892422a0e96235eb8ea6c5a41c8ccbf55576a2260c0160800dbd7c4f20"}, - {file = "regex-2021.8.3-cp38-cp38-win32.whl", hash = "sha256:bf6d987edd4a44dd2fa2723fca2790f9442ae4de2c8438e53fcb1befdf5d823a"}, - {file = "regex-2021.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:8fe58d9f6e3d1abf690174fd75800fda9bdc23d2a287e77758dc0e8567e38ce6"}, - {file = "regex-2021.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7976d410e42be9ae7458c1816a416218364e06e162b82e42f7060737e711d9ce"}, - {file = "regex-2021.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9569da9e78f0947b249370cb8fadf1015a193c359e7e442ac9ecc585d937f08d"}, - {file = "regex-2021.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459bbe342c5b2dec5c5223e7c363f291558bc27982ef39ffd6569e8c082bdc83"}, - {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f421e3cdd3a273bace013751c345f4ebeef08f05e8c10757533ada360b51a39"}, - {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea212df6e5d3f60341aef46401d32fcfded85593af1d82b8b4a7a68cd67fdd6b"}, - {file = "regex-2021.8.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a3b73390511edd2db2d34ff09aa0b2c08be974c71b4c0505b4a048d5dc128c2b"}, - {file = "regex-2021.8.3-cp39-cp39-win32.whl", hash = "sha256:f35567470ee6dbfb946f069ed5f5615b40edcbb5f1e6e1d3d2b114468d505fc6"}, - {file = "regex-2021.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:bfa6a679410b394600eafd16336b2ce8de43e9b13f7fb9247d84ef5ad2b45e91"}, - {file = "regex-2021.8.3.tar.gz", hash = "sha256:8935937dad2c9b369c3d932b0edbc52a62647c2afb2fafc0c280f14a8bf56a6a"}, + {file = "regex-2021.10.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:094a905e87a4171508c2a0e10217795f83c636ccc05ddf86e7272c26e14056ae"}, + {file = "regex-2021.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981c786293a3115bc14c103086ae54e5ee50ca57f4c02ce7cf1b60318d1e8072"}, + {file = "regex-2021.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b0f2f874c6a157c91708ac352470cb3bef8e8814f5325e3c5c7a0533064c6a24"}, + {file = "regex-2021.10.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51feefd58ac38eb91a21921b047da8644155e5678e9066af7bcb30ee0dca7361"}, + {file = "regex-2021.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea8de658d7db5987b11097445f2b1f134400e2232cb40e614e5f7b6f5428710e"}, + {file = "regex-2021.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1ce02f420a7ec3b2480fe6746d756530f69769292eca363218c2291d0b116a01"}, + {file = "regex-2021.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39079ebf54156be6e6902f5c70c078f453350616cfe7bfd2dd15bdb3eac20ccc"}, + {file = "regex-2021.10.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ff24897f6b2001c38a805d53b6ae72267025878d35ea225aa24675fbff2dba7f"}, + {file = "regex-2021.10.8-cp310-cp310-win32.whl", hash = "sha256:c6569ba7b948c3d61d27f04e2b08ebee24fec9ff8e9ea154d8d1e975b175bfa7"}, + {file = "regex-2021.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:45cb0f7ff782ef51bc79e227a87e4e8f24bc68192f8de4f18aae60b1d60bc152"}, + {file = "regex-2021.10.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fab3ab8aedfb443abb36729410403f0fe7f60ad860c19a979d47fb3eb98ef820"}, + {file = "regex-2021.10.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74e55f8d66f1b41d44bc44c891bcf2c7fad252f8f323ee86fba99d71fd1ad5e3"}, + {file = "regex-2021.10.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d52c5e089edbdb6083391faffbe70329b804652a53c2fdca3533e99ab0580d9"}, + {file = "regex-2021.10.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1abbd95cbe9e2467cac65c77b6abd9223df717c7ae91a628502de67c73bf6838"}, + {file = "regex-2021.10.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9b5c215f3870aa9b011c00daeb7be7e1ae4ecd628e9beb6d7e6107e07d81287"}, + {file = "regex-2021.10.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f540f153c4f5617bc4ba6433534f8916d96366a08797cbbe4132c37b70403e92"}, + {file = "regex-2021.10.8-cp36-cp36m-win32.whl", hash = "sha256:1f51926db492440e66c89cd2be042f2396cf91e5b05383acd7372b8cb7da373f"}, + {file = "regex-2021.10.8-cp36-cp36m-win_amd64.whl", hash = "sha256:5f55c4804797ef7381518e683249310f7f9646da271b71cb6b3552416c7894ee"}, + {file = "regex-2021.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb2baff66b7d2267e07ef71e17d01283b55b3cc51a81b54cc385e721ae172ba4"}, + {file = "regex-2021.10.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e527ab1c4c7cf2643d93406c04e1d289a9d12966529381ce8163c4d2abe4faf"}, + {file = "regex-2021.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c98b013273e9da5790ff6002ab326e3f81072b4616fd95f06c8fa733d2745f"}, + {file = "regex-2021.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:55ef044899706c10bc0aa052f2fc2e58551e2510694d6aae13f37c50f3f6ff61"}, + {file = "regex-2021.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa0ab3530a279a3b7f50f852f1bab41bc304f098350b03e30a3876b7dd89840e"}, + {file = "regex-2021.10.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a37305eb3199d8f0d8125ec2fb143ba94ff6d6d92554c4b8d4a8435795a6eccd"}, + {file = "regex-2021.10.8-cp37-cp37m-win32.whl", hash = "sha256:2efd47704bbb016136fe34dfb74c805b1ef5c7313aef3ce6dcb5ff844299f432"}, + {file = "regex-2021.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:924079d5590979c0e961681507eb1773a142553564ccae18d36f1de7324e71ca"}, + {file = "regex-2021.10.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:19b8f6d23b2dc93e8e1e7e288d3010e58fafed323474cf7f27ab9451635136d9"}, + {file = "regex-2021.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b09d3904bf312d11308d9a2867427479d277365b1617e48ad09696fa7dfcdf59"}, + {file = "regex-2021.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:951be934dc25d8779d92b530e922de44dda3c82a509cdb5d619f3a0b1491fafa"}, + {file = "regex-2021.10.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f125fce0a0ae4fd5c3388d369d7a7d78f185f904c90dd235f7ecf8fe13fa741"}, + {file = "regex-2021.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f199419a81c1016e0560c39773c12f0bd924c37715bffc64b97140d2c314354"}, + {file = "regex-2021.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:09e1031e2059abd91177c302da392a7b6859ceda038be9e015b522a182c89e4f"}, + {file = "regex-2021.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c070d5895ac6aeb665bd3cd79f673775caf8d33a0b569e98ac434617ecea57d"}, + {file = "regex-2021.10.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:176796cb7f82a7098b0c436d6daac82f57b9101bb17b8e8119c36eecf06a60a3"}, + {file = "regex-2021.10.8-cp38-cp38-win32.whl", hash = "sha256:5e5796d2f36d3c48875514c5cd9e4325a1ca172fc6c78b469faa8ddd3d770593"}, + {file = "regex-2021.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:e4204708fa116dd03436a337e8e84261bc8051d058221ec63535c9403a1582a1"}, + {file = "regex-2021.10.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6dcf53d35850ce938b4f044a43b33015ebde292840cef3af2c8eb4c860730fff"}, + {file = "regex-2021.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b8b6ee6555b6fbae578f1468b3f685cdfe7940a65675611365a7ea1f8d724991"}, + {file = "regex-2021.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e2ec1c106d3f754444abf63b31e5c4f9b5d272272a491fa4320475aba9e8157c"}, + {file = "regex-2021.10.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973499dac63625a5ef9dfa4c791aa33a502ddb7615d992bdc89cf2cc2285daa3"}, + {file = "regex-2021.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88dc3c1acd3f0ecfde5f95c32fcb9beda709dbdf5012acdcf66acbc4794468eb"}, + {file = "regex-2021.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4786dae85c1f0624ac77cb3813ed99267c9adb72e59fdc7297e1cf4d6036d493"}, + {file = "regex-2021.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe6ce4f3d3c48f9f402da1ceb571548133d3322003ce01b20d960a82251695d2"}, + {file = "regex-2021.10.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e3e2cea8f1993f476a6833ef157f5d9e8c75a59a8d8b0395a9a6887a097243b"}, + {file = "regex-2021.10.8-cp39-cp39-win32.whl", hash = "sha256:82cfb97a36b1a53de32b642482c6c46b6ce80803854445e19bc49993655ebf3b"}, + {file = "regex-2021.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:b04e512eb628ea82ed86eb31c0f7fc6842b46bf2601b66b1356a7008327f7700"}, + {file = "regex-2021.10.8.tar.gz", hash = "sha256:26895d7c9bbda5c52b3635ce5991caa90fbb1ddfac9c9ff1c7ce505e2282fb2a"}, ] requests = [ {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, @@ -2524,8 +2529,8 @@ sortedcontainers = [ {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] stevedore = [ - {file = "stevedore-3.3.0-py3-none-any.whl", hash = "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a"}, - {file = "stevedore-3.3.0.tar.gz", hash = "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee"}, + {file = "stevedore-3.4.0-py3-none-any.whl", hash = "sha256:920ce6259f0b2498aaa4545989536a27e4e4607b8318802d7ddc3a533d3d069e"}, + {file = "stevedore-3.4.0.tar.gz", hash = "sha256:59b58edb7f57b11897f150475e7bc0c39c5381f0b8e3fa9f5c20ce6c89ec4aa1"}, ] text-unidecode = [ {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, @@ -2627,8 +2632,8 @@ typer = [ {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, ] types-colorama = [ - {file = "types-colorama-0.4.3.tar.gz", hash = "sha256:3b2c7877878f2ba8cd1c2b3da524158f718c10e2fe046f91948b43459b69dc6a"}, - {file = "types_colorama-0.4.3-py3-none-any.whl", hash = "sha256:3cdd76e8080a146d55b7281b352a4330be6d7ba91217d28c7e3a50dc433d4b89"}, + {file = "types-colorama-0.4.4.tar.gz", hash = "sha256:873b532af2bc07f79fd72e00d4df266a11c96272ece548ae568d3ca0f80113bd"}, + {file = "types_colorama-0.4.4-py3-none-any.whl", hash = "sha256:01a4f967a248e7bbf2afb42da42310f673f155bd46f0185b3d968ab60058df6d"}, ] types-pkg-resources = [ {file = "types-pkg_resources-0.1.3.tar.gz", hash = "sha256:834a9b8d3dbea343562fd99d5d3359a726f6bf9d3733bccd2b4f3096fbab9dae"}, @@ -2639,9 +2644,9 @@ types-toml = [ {file = "types_toml-0.1.5-py3-none-any.whl", hash = "sha256:dd00526680595aad0eade682bd8a9e9513e9b4b8932daed159925fe446fc90a9"}, ] typing-extensions = [ - {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, - {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, - {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, + {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, + {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, + {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, ] typing-inspect = [ {file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"}, @@ -2649,12 +2654,12 @@ typing-inspect = [ {file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"}, ] urllib3 = [ - {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"}, - {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, + {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"}, + {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"}, ] virtualenv = [ - {file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"}, - {file = "virtualenv-20.7.2.tar.gz", hash = "sha256:9ef4e8ee4710826e98ff3075c9a4739e2cb1040de6a2a8d35db0055840dc96a0"}, + {file = "virtualenv-20.8.1-py2.py3-none-any.whl", hash = "sha256:10062e34c204b5e4ec5f62e6ef2473f8ba76513a9a617e873f1f8fb4a519d300"}, + {file = "virtualenv-20.8.1.tar.gz", hash = "sha256:bcc17f0b3a29670dd777d6f0755a4c04f28815395bca279cdcb213b97199a6b8"}, ] vistir = [ {file = "vistir-0.5.2-py2.py3-none-any.whl", hash = "sha256:a37079cdbd85d31a41cdd18457fe521e15ec08b255811e81aa061fd5f48a20fb"}, @@ -2665,27 +2670,29 @@ vulture = [ {file = "vulture-1.6.tar.gz", hash = "sha256:7b94784ededbf8e2913b5142dc875d8f26de7c903b37cd2d8f478f79275f7ce9"}, ] watchdog = [ - {file = "watchdog-2.1.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9628f3f85375a17614a2ab5eac7665f7f7be8b6b0a2a228e6f6a2e91dd4bfe26"}, - {file = "watchdog-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:acc4e2d5be6f140f02ee8590e51c002829e2c33ee199036fcd61311d558d89f4"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b851237cf3533fabbc034ffcd84d0fa52014b3121454e5f8b86974b531560c"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a12539ecf2478a94e4ba4d13476bb2c7a2e0a2080af2bb37df84d88b1b01358a"}, - {file = "watchdog-2.1.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6fe9c8533e955c6589cfea6f3f0a1a95fb16867a211125236c82e1815932b5d7"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d9456f0433845e7153b102fffeb767bde2406b76042f2216838af3b21707894e"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd8c595d5a93abd441ee7c5bb3ff0d7170e79031520d113d6f401d0cf49d7c8f"}, - {file = "watchdog-2.1.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0bcfe904c7d404eb6905f7106c54873503b442e8e918cc226e1828f498bdc0ca"}, - {file = "watchdog-2.1.3-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bf84bd94cbaad8f6b9cbaeef43080920f4cb0e61ad90af7106b3de402f5fe127"}, - {file = "watchdog-2.1.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b8ddb2c9f92e0c686ea77341dcb58216fa5ff7d5f992c7278ee8a392a06e86bb"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8805a5f468862daf1e4f4447b0ccf3acaff626eaa57fbb46d7960d1cf09f2e6d"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_armv7l.whl", hash = "sha256:3e305ea2757f81d8ebd8559d1a944ed83e3ab1bdf68bcf16ec851b97c08dc035"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_i686.whl", hash = "sha256:431a3ea70b20962e6dee65f0eeecd768cd3085ea613ccb9b53c8969de9f6ebd2"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64.whl", hash = "sha256:e4929ac2aaa2e4f1a30a36751160be391911da463a8799460340901517298b13"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:201cadf0b8c11922f54ec97482f95b2aafca429c4c3a4bb869a14f3c20c32686"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_s390x.whl", hash = "sha256:3a7d242a7963174684206093846537220ee37ba9986b824a326a8bb4ef329a33"}, - {file = "watchdog-2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:54e057727dd18bd01a3060dbf5104eb5a495ca26316487e0f32a394fd5fe725a"}, - {file = "watchdog-2.1.3-py3-none-win32.whl", hash = "sha256:b5fc5c127bad6983eecf1ad117ab3418949f18af9c8758bd10158be3647298a9"}, - {file = "watchdog-2.1.3-py3-none-win_amd64.whl", hash = "sha256:44acad6f642996a2b50bb9ce4fb3730dde08f23e79e20cd3d8e2a2076b730381"}, - {file = "watchdog-2.1.3-py3-none-win_ia64.whl", hash = "sha256:0bcdf7b99b56a3ae069866c33d247c9994ffde91b620eaf0306b27e099bd1ae0"}, - {file = "watchdog-2.1.3.tar.gz", hash = "sha256:e5236a8e8602ab6db4b873664c2d356c365ab3cac96fbdec4970ad616415dd45"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9693f35162dc6208d10b10ddf0458cc09ad70c30ba689d9206e02cd836ce28a3"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aba5c812f8ee8a3ff3be51887ca2d55fb8e268439ed44110d3846e4229eb0e8b"}, + {file = "watchdog-2.1.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ae38bf8ba6f39d5b83f78661273216e7db5b00f08be7592062cb1fc8b8ba542"}, + {file = "watchdog-2.1.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ad6f1796e37db2223d2a3f302f586f74c72c630b48a9872c1e7ae8e92e0ab669"}, + {file = "watchdog-2.1.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:922a69fa533cb0c793b483becaaa0845f655151e7256ec73630a1b2e9ebcb660"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b2fcf9402fde2672545b139694284dc3b665fd1be660d73eca6805197ef776a3"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3386b367e950a11b0568062b70cc026c6f645428a698d33d39e013aaeda4cc04"}, + {file = "watchdog-2.1.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f1c00aa35f504197561060ca4c21d3cc079ba29cf6dd2fe61024c70160c990b"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b52b88021b9541a60531142b0a451baca08d28b74a723d0c99b13c8c8d48d604"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8047da932432aa32c515ec1447ea79ce578d0559362ca3605f8e9568f844e3c6"}, + {file = "watchdog-2.1.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e92c2d33858c8f560671b448205a268096e17870dcf60a9bb3ac7bfbafb7f5f9"}, + {file = "watchdog-2.1.6-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7d336912853d7b77f9b2c24eeed6a5065d0a0cc0d3b6a5a45ad6d1d05fb8cd8"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cca7741c0fcc765568350cb139e92b7f9f3c9a08c4f32591d18ab0a6ac9e71b6"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_armv7l.whl", hash = "sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_i686.whl", hash = "sha256:be9be735f827820a06340dff2ddea1fb7234561fa5e6300a62fe7f54d40546a0"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0d19fb2441947b58fbf91336638c2b9f4cc98e05e1045404d7a4cb7cddc7a65"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:3becdb380d8916c873ad512f1701f8a92ce79ec6978ffde92919fd18d41da7fb"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_s390x.whl", hash = "sha256:ae67501c95606072aafa865b6ed47343ac6484472a2f95490ba151f6347acfc2"}, + {file = "watchdog-2.1.6-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e0f30db709c939cabf64a6dc5babb276e6d823fd84464ab916f9b9ba5623ca15"}, + {file = "watchdog-2.1.6-py3-none-win32.whl", hash = "sha256:e02794ac791662a5eafc6ffeaf9bcc149035a0e48eb0a9d40a8feb4622605a3d"}, + {file = "watchdog-2.1.6-py3-none-win_amd64.whl", hash = "sha256:bd9ba4f332cf57b2c1f698be0728c020399ef3040577cde2939f2e045b39c1e5"}, + {file = "watchdog-2.1.6-py3-none-win_ia64.whl", hash = "sha256:a0f1c7edf116a12f7245be06120b1852275f9506a7d90227648b250755a03923"}, + {file = "watchdog-2.1.6.tar.gz", hash = "sha256:a36e75df6c767cbf46f61a91c70b3ba71811dfa0aca4a324d9407a06a8b7a2e7"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, @@ -2700,6 +2707,6 @@ yaspin = [ {file = "yaspin-0.15.0.tar.gz", hash = "sha256:5a938bdc7bab353fd8942d0619d56c6b5159a80997dc1c387a479b39e6dc9391"}, ] zipp = [ - {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, - {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] From 0c24aceb2a30e7e6709282143ea13acf86030cd0 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Sat, 16 Oct 2021 22:32:49 -0700 Subject: [PATCH 44/54] Update to latest mkdocs --- poetry.lock | 16 ++++++++-------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 575f0adfa..6901a99be 100644 --- a/poetry.lock +++ b/poetry.lock @@ -840,7 +840,7 @@ python-versions = ">=3.6" [[package]] name = "mkdocs" -version = "1.2.1" +version = "1.2.3" description = "Project documentation with Markdown." category = "dev" optional = false @@ -863,7 +863,7 @@ i18n = ["babel (>=2.9.0)"] [[package]] name = "mkdocs-material" -version = "7.2.3" +version = "7.3.0" description = "A Material Design theme for MkDocs" category = "dev" optional = false @@ -871,7 +871,7 @@ python-versions = "*" [package.dependencies] markdown = ">=3.2" -mkdocs = ">=1.1" +mkdocs = ">=1.2.2" mkdocs-material-extensions = ">=1.0" Pygments = ">=2.4" pymdown-extensions = ">=7.0" @@ -1800,7 +1800,7 @@ requirements_deprecated_finder = ["pipreqs", "pip-api"] [metadata] lock-version = "1.1" python-versions = ">=3.6.1,<4.0" -content-hash = "62a0a0b1f84f078af18e91535580fd457ed1ad811487ec3a73da5d279b9167b1" +content-hash = "c064ec28d39e179c7212dfebf09bd367e1e49224662428d09487ba44f4086fd0" [metadata.files] appdirs = [ @@ -2182,12 +2182,12 @@ mergedeep = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] mkdocs = [ - {file = "mkdocs-1.2.1-py3-none-any.whl", hash = "sha256:11141126e5896dd9d279b3e4814eb488e409a0990fb638856255020406a8e2e7"}, - {file = "mkdocs-1.2.1.tar.gz", hash = "sha256:6e0ea175366e3a50d334597b0bc042b8cebd512398cdd3f6f34842d0ef524905"}, + {file = "mkdocs-1.2.3-py3-none-any.whl", hash = "sha256:a1fa8c2d0c1305d7fc2b9d9f607c71778572a8b110fb26642aa00296c9e6d072"}, + {file = "mkdocs-1.2.3.tar.gz", hash = "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1"}, ] mkdocs-material = [ - {file = "mkdocs-material-7.2.3.tar.gz", hash = "sha256:688f0162e7356aa5d019cf687851f5b24c7002886bd939b8159595cc16966edf"}, - {file = "mkdocs_material-7.2.3-py2.py3-none-any.whl", hash = "sha256:039ce80555ba457faa10af993c57e9b6469918c6a5427851dcdd65591cc47fac"}, + {file = "mkdocs-material-7.3.0.tar.gz", hash = "sha256:07db0580fa96c3473aee99ec3fb4606a1a5a1e4f4467e64c0cd1ba8da5b6476e"}, + {file = "mkdocs_material-7.3.0-py2.py3-none-any.whl", hash = "sha256:b183c27dc0f44e631bbc32c51057f61a3e2ba8b3c1080e59f944167eeba9ff1d"}, ] mkdocs-material-extensions = [ {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"}, diff --git a/pyproject.toml b/pyproject.toml index 4d681e3b1..5fad868f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,7 @@ hypothesmith = "^0.1.3" examples = { version = "^1.0.0" } cruft = { version = "^2.2" } portray = { version = "^1.6.0" } -mkdocs = { version = "1.2.1" } +mkdocs = { version = "^1.2.3" } pipfile = "^0.0.2" requirementslib = "^1.5" pipreqs = "^0.4.9" From 31c9daa84723e956039990f58d996bf24a6fe64c Mon Sep 17 00:00:00 2001 From: Christian Decker <christian.decker@lookslikematrix.de> Date: Wed, 27 Oct 2021 11:18:06 +0200 Subject: [PATCH 45/54] only skip real comments --- isort/core.py | 2 +- isort/settings.py | 4 ++-- tests/unit/test_isort.py | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/isort/core.py b/isort/core.py index 018c8e0b7..8e12f195b 100644 --- a/isort/core.py +++ b/isort/core.py @@ -151,7 +151,7 @@ def process( line_separator = line[len(line.rstrip()) :].replace(" ", "").replace("\t", "") for file_skip_comment in FILE_SKIP_COMMENTS: - if file_skip_comment in line: + if line.startswith(file_skip_comment): if raise_on_skip: raise FileSkipComment("Passed in content") isort_off = True diff --git a/isort/settings.py b/isort/settings.py index d0060d056..e0c8b98d9 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -55,8 +55,8 @@ SUPPORTED_EXTENSIONS = frozenset({"py", "pyi", *CYTHON_EXTENSIONS}) BLOCKED_EXTENSIONS = frozenset({"pex"}) FILE_SKIP_COMMENTS: Tuple[str, ...] = ( - "isort:" + "skip_file", - "isort: " + "skip_file", + "# isort:" + "skip_file", + "# isort: " + "skip_file", ) # Concatenated to avoid this file being skipped MAX_CONFIG_SEARCH_DEPTH: int = 25 # The number of parent directories to for a config file within STOP_CONFIG_SEARCH_ON_DIRS: Tuple[str, ...] = (".git", ".hg") diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index b0534142b..3467569f9 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -837,6 +837,11 @@ def test_skip_within_file() -> None: with pytest.raises(FileSkipped): isort.code(test_input, known_third_party=["django"]) +def test_skip_comment_is_no_comment() -> None: + """Ensure skipping a whole file works.""" + test_input = "content = \"# isort:skip_file\"" + test_output = isort.code(test_input) + assert test_output == test_input def test_force_to_top() -> None: """Ensure forcing a single import to the top of its category works as expected.""" From f0f4645d49d78650032b330c14e4ca023c9763c6 Mon Sep 17 00:00:00 2001 From: Christian Decker <christian.decker@lookslikematrix.de> Date: Wed, 27 Oct 2021 11:24:30 +0200 Subject: [PATCH 46/54] handle without space after hash --- isort/settings.py | 2 ++ tests/unit/test_isort.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/isort/settings.py b/isort/settings.py index e0c8b98d9..0d736d642 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -57,6 +57,8 @@ FILE_SKIP_COMMENTS: Tuple[str, ...] = ( "# isort:" + "skip_file", "# isort: " + "skip_file", + "#isort:" + "skip_file", + "#isort: " + "skip_file", ) # Concatenated to avoid this file being skipped MAX_CONFIG_SEARCH_DEPTH: int = 25 # The number of parent directories to for a config file within STOP_CONFIG_SEARCH_ON_DIRS: Tuple[str, ...] = (".git", ".hg") diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index 3467569f9..c16a84361 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -837,6 +837,12 @@ def test_skip_within_file() -> None: with pytest.raises(FileSkipped): isort.code(test_input, known_third_party=["django"]) +def test_skip_comment_without_space_after_hash() -> None: + """Ensure skipping a whole file works.""" + test_input = "#isort: skip_file\nimport django\nimport myproject\n" + with pytest.raises(FileSkipped): + isort.code(test_input, known_third_party=["django"]) + def test_skip_comment_is_no_comment() -> None: """Ensure skipping a whole file works.""" test_input = "content = \"# isort:skip_file\"" @@ -849,7 +855,6 @@ def test_force_to_top() -> None: test_output = isort.code(test_input, force_to_top=["lib5"]) assert test_output == "import lib5\nimport lib1\nimport lib2\nimport lib6\n" - def test_add_imports() -> None: """Ensures adding imports works as expected.""" test_input = "import lib6\nimport lib2\nimport lib5\nimport lib1\n\n" From b1c5d7b2768f6c575929a6d9d1c7c6731454f670 Mon Sep 17 00:00:00 2001 From: Adam Parkin <pzelnip@users.noreply.github.com> Date: Wed, 27 Oct 2021 15:17:57 -0700 Subject: [PATCH 47/54] Minor improvements to pre-commit.md Changes to the most recent version of isort, as well as explain better the `types` section. --- docs/configuration/pre-commit.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/configuration/pre-commit.md b/docs/configuration/pre-commit.md index 19362f816..4238483bb 100644 --- a/docs/configuration/pre-commit.md +++ b/docs/configuration/pre-commit.md @@ -7,9 +7,20 @@ isort provides official support for [pre-commit](https://pre-commit.com/). To use isort's official pre-commit integration add the following config: +```yaml + - repo: https://github.com/pycqa/isort + rev: 5.9.3 + hooks: + - id: isort + name: isort (python) ``` + +under the `repos` section of your projects `.pre-commit-config.yaml` file. Optionally if you want to have different hooks +over different file types (ex: python vs cython vs pyi) you can do so with the following config: + +```yaml - repo: https://github.com/pycqa/isort - rev: 5.8.0 + rev: 5.9.3 hooks: - id: isort name: isort (python) @@ -21,8 +32,6 @@ To use isort's official pre-commit integration add the following config: types: [pyi] ``` -under the `repos` section of your projects `.pre-commit-config.yaml` file. - ### seed-isort-config Older versions of isort used a lot of magic to determine import placement, that could easily break when running on CI/CD. From 4e3f64bf91b50c9d2923c60853e0701ab04f388f Mon Sep 17 00:00:00 2001 From: Christian Decker <christian.decker@lookslikematrix.de> Date: Thu, 28 Oct 2021 07:20:40 +0200 Subject: [PATCH 48/54] fix linter --- tests/unit/test_isort.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index c16a84361..05740d292 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -837,24 +837,28 @@ def test_skip_within_file() -> None: with pytest.raises(FileSkipped): isort.code(test_input, known_third_party=["django"]) + def test_skip_comment_without_space_after_hash() -> None: """Ensure skipping a whole file works.""" test_input = "#isort: skip_file\nimport django\nimport myproject\n" with pytest.raises(FileSkipped): isort.code(test_input, known_third_party=["django"]) + def test_skip_comment_is_no_comment() -> None: """Ensure skipping a whole file works.""" - test_input = "content = \"# isort:skip_file\"" + test_input = 'content = "# isort:skip_file"' test_output = isort.code(test_input) assert test_output == test_input + def test_force_to_top() -> None: """Ensure forcing a single import to the top of its category works as expected.""" test_input = "import lib6\nimport lib2\nimport lib5\nimport lib1\n" test_output = isort.code(test_input, force_to_top=["lib5"]) assert test_output == "import lib5\nimport lib1\nimport lib2\nimport lib6\n" + def test_add_imports() -> None: """Ensures adding imports works as expected.""" test_input = "import lib6\nimport lib2\nimport lib5\nimport lib1\n\n" From 3c5da48559a4052b47f170c1a3fe3cdd5bd928da Mon Sep 17 00:00:00 2001 From: Christian Decker <christian.decker@lookslikematrix.de> Date: Thu, 28 Oct 2021 13:56:19 +0200 Subject: [PATCH 49/54] use regex to mach file_skip --- isort/core.py | 14 +++++++------- isort/settings.py | 7 +------ tests/unit/test_isort.py | 7 +++++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/isort/core.py b/isort/core.py index 8e12f195b..ec565bd5b 100644 --- a/isort/core.py +++ b/isort/core.py @@ -1,6 +1,7 @@ import textwrap from io import StringIO from itertools import chain +from re import match from typing import List, TextIO, Union import isort.literal @@ -9,7 +10,7 @@ from . import output, parse from .exceptions import FileSkipComment from .format import format_natural, remove_whitespace -from .settings import FILE_SKIP_COMMENTS +from .settings import FILE_SKIP_RE CIMPORT_IDENTIFIERS = ("cimport ", "cimport*", "from.cimport") IMPORT_START_IDENTIFIERS = ("from ", "from.import", "import ", "import*") + CIMPORT_IDENTIFIERS @@ -150,12 +151,11 @@ def process( if stripped_line and not line_separator: line_separator = line[len(line.rstrip()) :].replace(" ", "").replace("\t", "") - for file_skip_comment in FILE_SKIP_COMMENTS: - if line.startswith(file_skip_comment): - if raise_on_skip: - raise FileSkipComment("Passed in content") - isort_off = True - skip_file = True + if FILE_SKIP_RE.match(line): + if raise_on_skip: + raise FileSkipComment("Passed in content") + isort_off = True + skip_file = True if not in_quote: if stripped_line == "# isort: off": diff --git a/isort/settings.py b/isort/settings.py index 0d736d642..29e17bcb7 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -54,12 +54,7 @@ CYTHON_EXTENSIONS = frozenset({"pyx", "pxd"}) SUPPORTED_EXTENSIONS = frozenset({"py", "pyi", *CYTHON_EXTENSIONS}) BLOCKED_EXTENSIONS = frozenset({"pex"}) -FILE_SKIP_COMMENTS: Tuple[str, ...] = ( - "# isort:" + "skip_file", - "# isort: " + "skip_file", - "#isort:" + "skip_file", - "#isort: " + "skip_file", -) # Concatenated to avoid this file being skipped +FILE_SKIP_RE = re.compile(r"^#?\s?isort:\s?skip_file") MAX_CONFIG_SEARCH_DEPTH: int = 25 # The number of parent directories to for a config file within STOP_CONFIG_SEARCH_ON_DIRS: Tuple[str, ...] = (".git", ".hg") VALID_PY_TARGETS: Tuple[str, ...] = tuple( diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index 05740d292..d9b663d11 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -845,6 +845,13 @@ def test_skip_comment_without_space_after_hash() -> None: isort.code(test_input, known_third_party=["django"]) +def test_skip_comment_with_multiline_comment() -> None: + """Ensure skipping a whole file works.""" + test_input = '"""some comment\n\nisort: skip_file\nimport django\nimport myproject\n"""' + with pytest.raises(FileSkipped): + isort.code(test_input, known_third_party=["django"]) + + def test_skip_comment_is_no_comment() -> None: """Ensure skipping a whole file works.""" test_input = 'content = "# isort:skip_file"' From 488cdcac10d4775d9ac2b63401a9a024a43705cf Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Sat, 30 Oct 2021 00:27:51 -0700 Subject: [PATCH 50/54] Fix formatting --- tests/unit/test_isort.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index d9b663d11..6f885581c 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -4,23 +4,24 @@ """ import os import os.path -from pathlib import Path import subprocess import sys from io import StringIO +from pathlib import Path from tempfile import NamedTemporaryFile -from typing import Any, Dict, Iterator, List, Set, Tuple, TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Set, Tuple import py import pytest import toml + import isort -from isort import api, sections, files +from isort import api, files, sections +from isort.exceptions import ExistingSyntaxErrors, FileSkipped, MissingSection from isort.settings import Config - from isort.utils import exists_case_sensitive -from isort.exceptions import FileSkipped, ExistingSyntaxErrors, MissingSection -from .utils import as_stream, UnreadableStream + +from .utils import UnreadableStream, as_stream if TYPE_CHECKING: WrapModes: Any From 223dc4cdf41e5557f28498b050a5ef1c02fef50c Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Mon, 1 Nov 2021 01:04:18 -0700 Subject: [PATCH 51/54] Remove unused import --- isort/core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/isort/core.py b/isort/core.py index ec565bd5b..d91aec5f8 100644 --- a/isort/core.py +++ b/isort/core.py @@ -1,7 +1,6 @@ import textwrap from io import StringIO from itertools import chain -from re import match from typing import List, TextIO, Union import isort.literal From 73245e942de97fe1a4a2d968bbde3c168a97e64c Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Wed, 3 Nov 2021 00:27:55 -0700 Subject: [PATCH 52/54] Fixes #1838: don't append imports where no imports are present --- isort/core.py | 2 +- tests/unit/test_ticketed_features.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/isort/core.py b/isort/core.py index d91aec5f8..78e0a1c03 100644 --- a/isort/core.py +++ b/isort/core.py @@ -355,7 +355,7 @@ def process( next_import_section = "" if import_section: - if add_imports and not indent: + if add_imports and (contains_imports or not config.append_only) and not indent: import_section = ( line_separator.join(add_imports) + line_separator + import_section ) diff --git a/tests/unit/test_ticketed_features.py b/tests/unit/test_ticketed_features.py index dde08be6c..ca39c0f95 100644 --- a/tests/unit/test_ticketed_features.py +++ b/tests/unit/test_ticketed_features.py @@ -213,6 +213,19 @@ def test_isort_supports_append_only_imports_issue_727(): """ ) + # issue 1838: don't append in middle of class + assert isort.check_code( + '''class C: + """a + + """ + # comment +''', + append_only=True, + add_imports=["from __future__ import annotations"], + show_diff=True, + ) + def test_isort_supports_shared_profiles_issue_970(): """Test to ensure isort provides a way to use shared profiles. From 7a13f31eab7bcb692b1f5b537b124464018c1889 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Wed, 3 Nov 2021 00:44:55 -0700 Subject: [PATCH 53/54] Add changelog for 5.10 --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a06d4f7..84fa07dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,12 @@ Changelog NOTE: isort follows the [semver](https://semver.org/) versioning standard. Find out more about isort's release policy [here](https://pycqa.github.io/isort/docs/major_releases/release_policy). -### 5.10.0 TBD +### 5.10.0 November 3 2021 - Implemented #1796: Switch to `tomli` for pyproject.toml configuration loader. - Fixed #1801: CLI bug (--exend-skip-glob, overrides instead of extending). - Fixed #1802: respect PATH customization in nested calls to git. - - Added support for Python 3.10 + - Fixed #1838: Append only with certain code snippets incorrectly adds imports. + - Added official support for Python 3.10 #### Potentially breaking changes: - Fixed #1785: `_ast` module incorrectly excluded from stdlib definition. From c154ecff496bf9309eaf5d887f4aa4a0abba28a2 Mon Sep 17 00:00:00 2001 From: Timothy Crosley <timothy.crosley@gmail.com> Date: Wed, 3 Nov 2021 00:46:19 -0700 Subject: [PATCH 54/54] Bump version to 5.10.0 --- docs/configuration/pre-commit.md | 6 +++--- isort/_version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/configuration/pre-commit.md b/docs/configuration/pre-commit.md index 4238483bb..9d8054732 100644 --- a/docs/configuration/pre-commit.md +++ b/docs/configuration/pre-commit.md @@ -9,18 +9,18 @@ To use isort's official pre-commit integration add the following config: ```yaml - repo: https://github.com/pycqa/isort - rev: 5.9.3 + rev: 5.10.0 hooks: - id: isort name: isort (python) ``` -under the `repos` section of your projects `.pre-commit-config.yaml` file. Optionally if you want to have different hooks +under the `repos` section of your projects `.pre-commit-config.yaml` file. Optionally if you want to have different hooks over different file types (ex: python vs cython vs pyi) you can do so with the following config: ```yaml - repo: https://github.com/pycqa/isort - rev: 5.9.3 + rev: 5.10.0 hooks: - id: isort name: isort (python) diff --git a/isort/_version.py b/isort/_version.py index 34de50acb..1b1e67f64 100644 --- a/isort/_version.py +++ b/isort/_version.py @@ -1 +1 @@ -__version__ = "5.9.3" +__version__ = "5.10.0" diff --git a/pyproject.toml b/pyproject.toml index 5fad868f7..76b6d5a62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ line-length = 100 [tool.poetry] name = "isort" -version = "5.9.3" +version = "5.10.0" description = "A Python utility / library to sort Python imports." authors = ["Timothy Crosley <timothy.crosley@gmail.com>"] license = "MIT"