From 3eba19d359ee5144f0d21c643b8617fe3fafbe92 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 10:22:26 +0800 Subject: [PATCH 01/14] Improve toml parsing --- pipenv/project.py | 70 ++++++++++--------------------- tests/integration/test_project.py | 18 ++++++++ tests/unit/test_vendor.py | 6 --- 3 files changed, 40 insertions(+), 54 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index 26b4cf0ce6..4b90f4934d 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -8,7 +8,6 @@ import base64 import fnmatch import hashlib -import contoml from first import first from cached_property import cached_property import operator @@ -578,60 +577,31 @@ def clear_pipfile_cache(self): _pipfile_cache.clear() @staticmethod - def dump_dict(dictionary, write_to, inline=False): - """ - Perform a nested recursive translation of a dictionary structure to a toml object. - - :param dictionary: A base dictionary to translate - :param write_to: The root node which will be mutated by the operation - :param inline: Whether to create inline tables for dictionaries, defaults to False - :return: A new toml hierarchical document - """ - - - def gen_table(inline=False): - if inline: - return tomlkit.inline_table() - return tomlkit.table() - - for key, value in dictionary.items(): - if isinstance(value, dict): - table = gen_table(inline=inline) - for sub_key, sub_value in value.items(): - if isinstance(sub_value, dict): - table[sub_key] = Project.dump_dict( - sub_value, gen_table(inline), inline=inline - ) - else: - table[sub_key] = sub_value - write_to[key] = table - else: - write_to[key] = Project.dump_dict(value, gen_table(inline), inline=inline) + def convert_outline_table(parsed): + """Converts all outline to inline tables""" + if hasattr(parsed, "_body"): # Duck-type that implies tomlkit.api.Container. + empty_inline_table = tomlkit.inline_table else: - write_to[key] = value - return write_to + empty_inline_table = toml.TomlDecoder().get_empty_inline_table + for section in ("packages", "dev-packages"): + table_data = parsed.get(section, {}) + for package, value in table_data.items(): + if hasattr(value, "keys"): + table = empty_inline_table() + table.update(value) + table_data[package] = table + return parsed def _parse_pipfile(self, contents): - # If any outline tables are present... try: data = tomlkit.parse(contents) - # Convert all outline tables to inline tables. - for section in ("packages", "dev-packages"): - table_data = data.get(section, tomlkit.table()) - for package, value in table_data.items(): - if isinstance(value, dict): - table = tomlkit.inline_table() - table.update(value) - table_data[package] = table - else: - table_data[package] = value - data[section] = table_data - return data except Exception: # We lose comments here, but it's for the best.) # Fallback to toml parser, for large files. - toml_decoder = toml.decoder.TomlDecoder() - return toml.loads(contents, decoder=toml_decoder) + data = toml.loads(contents) + if "[packages." in contents or "[dev-packages." in contents: + data = self.convert_outline_table(data) + return data def _read_pyproject(self): pyproject = self.path_to("pyproject.toml") @@ -886,7 +856,11 @@ def write_toml(self, data, path=None): if path is None: path = self.pipfile_location try: - formatted_data = tomlkit.dumps(data).rstrip() + if hasattr(data, "_body"): + formatted_data = tomlkit.dumps(data).rstrip() + else: + encoder = toml.encoder.TomlPreserveInlineDictEncoder() + formatted_data = toml.dumps(data, encoder=encoder) except Exception: document = tomlkit.document() for section in ("packages", "dev-packages"): diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index 5deccc84fa..1e00bbb70b 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -143,3 +143,21 @@ def test_many_indexes(PipenvInstance, pypi): f.write(contents) c = p.pipenv('install') assert c.return_code == 0 + + +@pytest.mark.install +@pytest.mark.project +def test_rewrite_outline_table(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi, chdir=True) as p: + with open(p.pipfile_path, 'w') as f: + contents = """ +[packages.requests] +version = "*" + """.strip() + f.write(contents) + c = p.pipenv('install click') + assert c.return_code == 0 + with open(p.pipfile_path) as f: + contents = f.read() + assert "[packages.requests]" not in contents + assert 'requests = { version = "*" }' in contents diff --git a/tests/unit/test_vendor.py b/tests/unit/test_vendor.py index 1894b6fff5..704b37fb7f 100644 --- a/tests/unit/test_vendor.py +++ b/tests/unit/test_vendor.py @@ -106,9 +106,3 @@ def test_inject_environment_variables(self): def test_token_date(dt, content): token = create_primitive_token(dt) assert token == tokens.Token(tokens.TYPE_DATE, content) - - -def test_dump_nonascii_string(): - content = 'name = "Stažené"\n' - toml_content = contoml.dumps(contoml.loads(content)) - assert toml_content == content From e147dc3ade4040e2b59c170c752f080839845264 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 10:57:20 +0800 Subject: [PATCH 02/14] Drops prettytoml/contoml form vendors --- news/3191.vendor.rst | 1 + pipenv/patched/contoml/LICENSE | 22 - pipenv/patched/contoml/__init__.py | 48 --- pipenv/patched/contoml/_version.py | 1 - pipenv/patched/contoml/file/__init__.py | 3 - pipenv/patched/contoml/file/array.py | 40 -- pipenv/patched/contoml/file/cascadedict.py | 56 --- pipenv/patched/contoml/file/file.py | 293 -------------- pipenv/patched/contoml/file/freshtable.py | 45 --- pipenv/patched/contoml/file/peekableit.py | 30 -- pipenv/patched/contoml/file/raw.py | 16 - pipenv/patched/contoml/file/structurer.py | 116 ------ .../patched/contoml/file/test_cascadedict.py | 25 -- pipenv/patched/contoml/file/test_entries.py | 20 - .../patched/contoml/file/test_peekableit.py | 12 - .../patched/contoml/file/test_structurer.py | 41 -- pipenv/patched/contoml/file/toplevels.py | 142 ------- pipenv/patched/patched.txt | 1 - pipenv/patched/prettytoml/LICENSE | 22 - pipenv/patched/prettytoml/__init__.py | 25 -- pipenv/patched/prettytoml/_version.py | 1 - .../patched/prettytoml/elements/__init__.py | 13 - .../prettytoml/elements/abstracttable.py | 92 ----- pipenv/patched/prettytoml/elements/array.py | 136 ------- pipenv/patched/prettytoml/elements/atomic.py | 52 --- pipenv/patched/prettytoml/elements/common.py | 101 ----- pipenv/patched/prettytoml/elements/errors.py | 13 - pipenv/patched/prettytoml/elements/factory.py | 152 ------- .../prettytoml/elements/inlinetable.py | 78 ---- .../patched/prettytoml/elements/metadata.py | 80 ---- pipenv/patched/prettytoml/elements/table.py | 122 ------ .../prettytoml/elements/tableheader.py | 95 ----- .../patched/prettytoml/elements/test_array.py | 67 ---- .../prettytoml/elements/test_atomic.py | 9 - .../prettytoml/elements/test_common.py | 89 ----- .../prettytoml/elements/test_factory.py | 22 - .../prettytoml/elements/test_inlinetable.py | 52 --- .../prettytoml/elements/test_metadata.py | 25 -- .../patched/prettytoml/elements/test_table.py | 59 --- .../prettytoml/elements/test_tableheader.py | 12 - .../prettytoml/elements/test_traversal.py | 18 - .../prettytoml/elements/traversal/__init__.py | 175 -------- .../elements/traversal/predicates.py | 48 --- pipenv/patched/prettytoml/errors.py | 32 -- pipenv/patched/prettytoml/lexer/__init__.py | 123 ------ pipenv/patched/prettytoml/lexer/test_lexer.py | 153 ------- pipenv/patched/prettytoml/parser/__init__.py | 34 -- .../prettytoml/parser/elementsanitizer.py | 58 --- pipenv/patched/prettytoml/parser/errors.py | 17 - pipenv/patched/prettytoml/parser/parser.py | 376 ------------------ pipenv/patched/prettytoml/parser/recdesc.py | 114 ------ .../patched/prettytoml/parser/test_parser.py | 156 -------- .../patched/prettytoml/parser/tokenstream.py | 39 -- .../patched/prettytoml/prettifier/__init__.py | 39 -- .../prettytoml/prettifier/commentspace.py | 35 -- .../patched/prettytoml/prettifier/common.py | 54 --- .../prettifier/deindentanonymoustable.py | 43 -- .../prettytoml/prettifier/linelength.py | 62 --- .../prettytoml/prettifier/tableassignment.py | 40 -- .../prettytoml/prettifier/tableentrysort.py | 38 -- .../prettytoml/prettifier/tableindent.py | 49 --- .../patched/prettytoml/prettifier/tablesep.py | 31 -- .../prettifier/test_commentspace.py | 28 -- .../prettifier/test_deindentanonymoustable.py | 22 - .../prettytoml/prettifier/test_linelength.py | 39 -- .../prettifier/test_tableassignment.py | 29 -- .../prettifier/test_tableentrysort.py | 45 --- .../prettytoml/prettifier/test_tableindent.py | 25 -- .../prettytoml/prettifier/test_tablesep.py | 34 -- pipenv/patched/prettytoml/test_prettifier.py | 12 - pipenv/patched/prettytoml/test_util.py | 22 - pipenv/patched/prettytoml/tokens/__init__.py | 136 ------- pipenv/patched/prettytoml/tokens/errors.py | 13 - pipenv/patched/prettytoml/tokens/py2toml.py | 154 ------- .../patched/prettytoml/tokens/test_py2toml.py | 69 ---- .../patched/prettytoml/tokens/test_toml2py.py | 86 ---- pipenv/patched/prettytoml/tokens/toml2py.py | 130 ------ pipenv/patched/prettytoml/util.py | 141 ------- pipenv/project.py | 8 +- tasks/vendoring/patches/patched/contoml.patch | 28 -- .../patched/prettytoml-newlinefix.patch | 13 - .../patches/patched/prettytoml-python37.patch | 32 -- .../patched/prettytoml-table-iter.patch | 29 -- .../patches/patched/prettytoml-unicode.patch | 132 ------ .../patches/patched/prettytoml.patch | 78 ---- tests/integration/test_project.py | 2 +- tests/unit/test_vendor.py | 70 +--- 87 files changed, 5 insertions(+), 5335 deletions(-) create mode 100644 news/3191.vendor.rst delete mode 100644 pipenv/patched/contoml/LICENSE delete mode 100644 pipenv/patched/contoml/__init__.py delete mode 100644 pipenv/patched/contoml/_version.py delete mode 100644 pipenv/patched/contoml/file/__init__.py delete mode 100644 pipenv/patched/contoml/file/array.py delete mode 100644 pipenv/patched/contoml/file/cascadedict.py delete mode 100644 pipenv/patched/contoml/file/file.py delete mode 100644 pipenv/patched/contoml/file/freshtable.py delete mode 100644 pipenv/patched/contoml/file/peekableit.py delete mode 100644 pipenv/patched/contoml/file/raw.py delete mode 100644 pipenv/patched/contoml/file/structurer.py delete mode 100644 pipenv/patched/contoml/file/test_cascadedict.py delete mode 100644 pipenv/patched/contoml/file/test_entries.py delete mode 100644 pipenv/patched/contoml/file/test_peekableit.py delete mode 100644 pipenv/patched/contoml/file/test_structurer.py delete mode 100644 pipenv/patched/contoml/file/toplevels.py delete mode 100644 pipenv/patched/prettytoml/LICENSE delete mode 100644 pipenv/patched/prettytoml/__init__.py delete mode 100644 pipenv/patched/prettytoml/_version.py delete mode 100644 pipenv/patched/prettytoml/elements/__init__.py delete mode 100644 pipenv/patched/prettytoml/elements/abstracttable.py delete mode 100644 pipenv/patched/prettytoml/elements/array.py delete mode 100644 pipenv/patched/prettytoml/elements/atomic.py delete mode 100644 pipenv/patched/prettytoml/elements/common.py delete mode 100644 pipenv/patched/prettytoml/elements/errors.py delete mode 100644 pipenv/patched/prettytoml/elements/factory.py delete mode 100644 pipenv/patched/prettytoml/elements/inlinetable.py delete mode 100644 pipenv/patched/prettytoml/elements/metadata.py delete mode 100644 pipenv/patched/prettytoml/elements/table.py delete mode 100644 pipenv/patched/prettytoml/elements/tableheader.py delete mode 100644 pipenv/patched/prettytoml/elements/test_array.py delete mode 100644 pipenv/patched/prettytoml/elements/test_atomic.py delete mode 100644 pipenv/patched/prettytoml/elements/test_common.py delete mode 100644 pipenv/patched/prettytoml/elements/test_factory.py delete mode 100644 pipenv/patched/prettytoml/elements/test_inlinetable.py delete mode 100644 pipenv/patched/prettytoml/elements/test_metadata.py delete mode 100644 pipenv/patched/prettytoml/elements/test_table.py delete mode 100644 pipenv/patched/prettytoml/elements/test_tableheader.py delete mode 100644 pipenv/patched/prettytoml/elements/test_traversal.py delete mode 100644 pipenv/patched/prettytoml/elements/traversal/__init__.py delete mode 100644 pipenv/patched/prettytoml/elements/traversal/predicates.py delete mode 100644 pipenv/patched/prettytoml/errors.py delete mode 100644 pipenv/patched/prettytoml/lexer/__init__.py delete mode 100644 pipenv/patched/prettytoml/lexer/test_lexer.py delete mode 100644 pipenv/patched/prettytoml/parser/__init__.py delete mode 100644 pipenv/patched/prettytoml/parser/elementsanitizer.py delete mode 100644 pipenv/patched/prettytoml/parser/errors.py delete mode 100644 pipenv/patched/prettytoml/parser/parser.py delete mode 100644 pipenv/patched/prettytoml/parser/recdesc.py delete mode 100644 pipenv/patched/prettytoml/parser/test_parser.py delete mode 100644 pipenv/patched/prettytoml/parser/tokenstream.py delete mode 100644 pipenv/patched/prettytoml/prettifier/__init__.py delete mode 100644 pipenv/patched/prettytoml/prettifier/commentspace.py delete mode 100644 pipenv/patched/prettytoml/prettifier/common.py delete mode 100644 pipenv/patched/prettytoml/prettifier/deindentanonymoustable.py delete mode 100644 pipenv/patched/prettytoml/prettifier/linelength.py delete mode 100644 pipenv/patched/prettytoml/prettifier/tableassignment.py delete mode 100644 pipenv/patched/prettytoml/prettifier/tableentrysort.py delete mode 100644 pipenv/patched/prettytoml/prettifier/tableindent.py delete mode 100644 pipenv/patched/prettytoml/prettifier/tablesep.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_commentspace.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_deindentanonymoustable.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_linelength.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_tableassignment.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_tableentrysort.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_tableindent.py delete mode 100644 pipenv/patched/prettytoml/prettifier/test_tablesep.py delete mode 100644 pipenv/patched/prettytoml/test_prettifier.py delete mode 100644 pipenv/patched/prettytoml/test_util.py delete mode 100644 pipenv/patched/prettytoml/tokens/__init__.py delete mode 100644 pipenv/patched/prettytoml/tokens/errors.py delete mode 100644 pipenv/patched/prettytoml/tokens/py2toml.py delete mode 100644 pipenv/patched/prettytoml/tokens/test_py2toml.py delete mode 100644 pipenv/patched/prettytoml/tokens/test_toml2py.py delete mode 100644 pipenv/patched/prettytoml/tokens/toml2py.py delete mode 100644 pipenv/patched/prettytoml/util.py delete mode 100644 tasks/vendoring/patches/patched/contoml.patch delete mode 100644 tasks/vendoring/patches/patched/prettytoml-newlinefix.patch delete mode 100644 tasks/vendoring/patches/patched/prettytoml-python37.patch delete mode 100644 tasks/vendoring/patches/patched/prettytoml-table-iter.patch delete mode 100644 tasks/vendoring/patches/patched/prettytoml-unicode.patch delete mode 100644 tasks/vendoring/patches/patched/prettytoml.patch diff --git a/news/3191.vendor.rst b/news/3191.vendor.rst new file mode 100644 index 0000000000..3806b68fbc --- /dev/null +++ b/news/3191.vendor.rst @@ -0,0 +1 @@ +Switch to ``tomlkit`` for parsing and writing. Drop ``prettytoml`` and ``contoml`` from vendors. diff --git a/pipenv/patched/contoml/LICENSE b/pipenv/patched/contoml/LICENSE deleted file mode 100644 index 116fa4e558..0000000000 --- a/pipenv/patched/contoml/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Jumpscale - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -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 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. - diff --git a/pipenv/patched/contoml/__init__.py b/pipenv/patched/contoml/__init__.py deleted file mode 100644 index 9dba5e206c..0000000000 --- a/pipenv/patched/contoml/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -from ._version import VERSION - -__version__ = VERSION - - -def loads(text): - """ - Parses TOML text into a dict-like object and returns it. - """ - from prettytoml.parser import parse_tokens - from prettytoml.lexer import tokenize as lexer - from .file import TOMLFile - - tokens = tuple(lexer(text, is_top_level=True)) - elements = parse_tokens(tokens) - return TOMLFile(elements) - - -def load(file_path): - """ - Parses a TOML file into a dict-like object and returns it. - """ - return loads(open(file_path).read()) - - -def dumps(value): - """ - Dumps a data structure to TOML source code. - - The given value must be either a dict of dict values, a dict, or a TOML file constructed by this module. - """ - - from contoml.file.file import TOMLFile - - if not isinstance(value, TOMLFile): - raise RuntimeError("Can only dump a TOMLFile instance loaded by load() or loads()") - - return value.dumps() - - -def dump(obj, file_path, prettify=False): - """ - Dumps a data structure to the filesystem as TOML. - - The given value must be either a dict of dict values, a dict, or a TOML file constructed by this module. - """ - with open(file_path, 'w') as fp: - fp.write(dumps(obj)) diff --git a/pipenv/patched/contoml/_version.py b/pipenv/patched/contoml/_version.py deleted file mode 100644 index e0f154708e..0000000000 --- a/pipenv/patched/contoml/_version.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = 'master' diff --git a/pipenv/patched/contoml/file/__init__.py b/pipenv/patched/contoml/file/__init__.py deleted file mode 100644 index 1aba5121c2..0000000000 --- a/pipenv/patched/contoml/file/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ - - -from .file import TOMLFile diff --git a/pipenv/patched/contoml/file/array.py b/pipenv/patched/contoml/file/array.py deleted file mode 100644 index 40e5acb3ec..0000000000 --- a/pipenv/patched/contoml/file/array.py +++ /dev/null @@ -1,40 +0,0 @@ -from prettytoml.elements.table import TableElement -from prettytoml.errors import InvalidValueError -from contoml.file.freshtable import FreshTable -from prettytoml import util - - -class ArrayOfTables(list): - - def __init__(self, toml_file, name, iterable=None): - if iterable: - list.__init__(self, iterable) - self._name = name - self._toml_file = toml_file - - def append(self, value): - if isinstance(value, dict): - table = FreshTable(parent=self, name=self._name, is_array=True) - table._append_to_parent() - index = len(self._toml_file[self._name]) - 1 - for key_seq, value in util.flatten_nested(value).items(): - # self._toml_file._setitem_with_key_seq((self._name, index) + key_seq, value) - self._toml_file._array_setitem_with_key_seq(self._name, index, key_seq, value) - # for k, v in value.items(): - # table[k] = v - else: - raise InvalidValueError('Can only append a dict to an array of tables') - - def __getitem__(self, item): - try: - return list.__getitem__(self, item) - except IndexError: - if item == len(self): - return FreshTable(parent=self, name=self._name, is_array=True) - else: - raise - - def append_fresh_table(self, fresh_table): - list.append(self, fresh_table) - if self._toml_file: - self._toml_file.append_fresh_table(fresh_table) diff --git a/pipenv/patched/contoml/file/cascadedict.py b/pipenv/patched/contoml/file/cascadedict.py deleted file mode 100644 index 4e97c0600d..0000000000 --- a/pipenv/patched/contoml/file/cascadedict.py +++ /dev/null @@ -1,56 +0,0 @@ -import operator -from functools import reduce -from contoml.file import raw - - -class CascadeDict: - """ - A dict-like object made up of one or more other dict-like objects where querying for an item cascade-gets - it from all the internal dicts in order of their listing, and setting an item sets it on the first dict listed. - """ - - def __init__(self, *internal_dicts): - assert internal_dicts, 'internal_dicts cannot be empty' - self._internal_dicts = tuple(internal_dicts) - - def cascaded_with(self, one_more_dict): - """ - Returns another instance with one more dict cascaded at the end. - """ - return CascadeDict(self._internal_dicts, one_more_dict,) - - def __getitem__(self, item): - for d in self._internal_dicts: - try: - return d[item] - except KeyError: - pass - raise KeyError - - def __setitem__(self, key, value): - self._internal_dicts[0][key] = value - - def keys(self): - return set(reduce(operator.or_, (set(d.keys()) for d in self._internal_dicts))) - - def items(self): - all_items = reduce(operator.add, (list(d.items()) for d in reversed(self._internal_dicts))) - unique_items = {k: v for k, v in all_items}.items() - return tuple(unique_items) - - def __contains__(self, item): - for d in self._internal_dicts: - if item in d: - return True - return False - - @property - def neutralized(self): - return {k: raw.to_raw(v) for k, v in self.items()} - - @property - def primitive_value(self): - return self.neutralized - - def __repr__(self): - return repr(self.primitive_value) diff --git a/pipenv/patched/contoml/file/file.py b/pipenv/patched/contoml/file/file.py deleted file mode 100644 index 99ce1483e6..0000000000 --- a/pipenv/patched/contoml/file/file.py +++ /dev/null @@ -1,293 +0,0 @@ -from prettytoml.errors import NoArrayFoundError, DuplicateKeysError, DuplicateTablesError -from contoml.file import structurer, toplevels, raw -from contoml.file.array import ArrayOfTables -from contoml.file.freshtable import FreshTable -import prettytoml.elements.factory as element_factory -import prettytoml.util as util - - -class TOMLFile: - """ - A TOMLFile object that tries its best to prserve formatting and order of mappings of the input source. - - Raises InvalidTOMLFileError on invalid input elements. - - Raises DuplicateKeysError, DuplicateTableError when appropriate. - """ - - def __init__(self, _elements): - self._elements = [] - self._navigable = {} - self.append_elements(_elements) - - def __getitem__(self, item): - try: - value = self._navigable[item] - if isinstance(value, (list, tuple)): - return ArrayOfTables(toml_file=self, name=item, iterable=value) - else: - return value - except KeyError: - return FreshTable(parent=self, name=item, is_array=False) - - def get(self, item, default=None): - """This was not here for who knows why.""" - - if item not in self: - return default - else: - return self.__getitem__(item) - - def __contains__(self, item): - return item in self.keys() - - def _setitem_with_key_seq(self, key_seq, value): - """ - Sets a the value in the TOML file located by the given key sequence. - - Example: - self._setitem(('key1', 'key2', 'key3'), 'text_value') - is equivalent to doing - self['key1']['key2']['key3'] = 'text_value' - """ - table = self - key_so_far = tuple() - for key in key_seq[:-1]: - key_so_far += (key,) - self._make_sure_table_exists(key_so_far) - table = table[key] - table[key_seq[-1]] = value - - def _array_setitem_with_key_seq(self, array_name, index, key_seq, value): - """ - Sets a the array value in the TOML file located by the given key sequence. - - Example: - self._array_setitem(array_name, index, ('key1', 'key2', 'key3'), 'text_value') - is equivalent to doing - self.array(array_name)[index]['key1']['key2']['key3'] = 'text_value' - """ - table = self.array(array_name)[index] - key_so_far = tuple() - for key in key_seq[:-1]: - key_so_far += (key,) - new_table = self._array_make_sure_table_exists(array_name, index, key_so_far) - if new_table is not None: - table = new_table - else: - table = table[key] - table[key_seq[-1]] = value - - def _make_sure_table_exists(self, name_seq): - """ - Makes sure the table with the full name comprising of name_seq exists. - """ - t = self - for key in name_seq[:-1]: - t = t[key] - name = name_seq[-1] - if name not in t: - self.append_elements([element_factory.create_table_header_element(name_seq), - element_factory.create_table({})]) - - def _array_make_sure_table_exists(self, array_name, index, name_seq): - """ - Makes sure the table with the full name comprising of name_seq exists. - """ - t = self[array_name][index] - for key in name_seq[:-1]: - t = t[key] - name = name_seq[-1] - if name not in t: - new_table = element_factory.create_table({}) - self.append_elements([element_factory.create_table_header_element((array_name,) + name_seq), new_table]) - return new_table - - def __delitem__(self, key): - table_element_index = self._elements.index(self._navigable[key]) - self._elements[table_element_index] = element_factory.create_table({}) - self._on_element_change() - - def __setitem__(self, key, value): - - # Setting an array-of-tables - if key and isinstance(value, (tuple, list)) and value and all(isinstance(v, dict) for v in value): - for table in value: - self.array(key).append(table) - - # Or setting a whole single table - elif isinstance(value, dict): - - if key and key in self: - del self[key] - - for key_seq, child_value in util.flatten_nested({key: value}).items(): - self._setitem_with_key_seq(key_seq, child_value) - - # if key in self._navigable: - # del self[key] - # index = self._elements.index(self._navigable[key]) - # self._elements = self._elements[:index] + [element_factory.create_table(value)] + self._elements[index+1:] - # else: - # if key: - # self._elements.append(element_factory.create_table_header_element(key)) - # self._elements.append(element_factory.create_table(value)) - - - # Or updating the anonymous section table - else: - # It's mea - self[''][key] = value - - self._on_element_change() - - def _detect_toplevels(self): - """ - Returns a sequence of TopLevel instances for the current state of this table. - """ - return tuple(e for e in toplevels.identify(self.elements) if isinstance(e, toplevels.Table)) - - def _update_table_fallbacks(self, table_toplevels): - """ - Updates the fallbacks on all the table elements to make relative table access possible. - - Raises DuplicateKeysError if appropriate. - """ - - if len(self.elements) <= 1: - return - - def parent_of(toplevel): - # Returns an TopLevel parent of the given entry, or None. - for parent_toplevel in table_toplevels: - if toplevel.name.sub_names[:-1] == parent_toplevel.name.sub_names: - return parent_toplevel - - for entry in table_toplevels: - if entry.name.is_qualified: - parent = parent_of(entry) - if parent: - child_name = entry.name.without_prefix(parent.name) - parent.table_element.set_fallback({child_name.sub_names[0]: entry.table_element}) - - def _recreate_navigable(self): - if self._elements: - self._navigable = structurer.structure(toplevels.identify(self._elements)) - - def array(self, name): - """ - Returns the array of tables with the given name. - """ - if name in self._navigable: - if isinstance(self._navigable[name], (list, tuple)): - return self[name] - else: - raise NoArrayFoundError - else: - return ArrayOfTables(toml_file=self, name=name) - - def _on_element_change(self): - self._recreate_navigable() - - table_toplevels = self._detect_toplevels() - self._update_table_fallbacks(table_toplevels) - - def append_elements(self, elements): - """ - Appends more elements to the contained internal elements. - """ - self._elements = self._elements + list(elements) - self._on_element_change() - - def prepend_elements(self, elements): - """ - Prepends more elements to the contained internal elements. - """ - self._elements = list(elements) + self._elements - self._on_element_change() - - def dumps(self): - """ - Returns the TOML file serialized back to str. - """ - return ''.join(element.serialized() for element in self._elements) - - def dump(self, file_path): - with open(file_path, mode='w') as fp: - fp.write(self.dumps()) - - def keys(self): - return set(self._navigable.keys()) | {''} - - def values(self): - return self._navigable.values() - - def items(self): - items = self._navigable.items() - - def has_anonymous_entry(): - return any(key == '' for (key, _) in items) - - if has_anonymous_entry(): - return items - else: - return list(items) + [('', self[''])] - - @property - def primitive(self): - """ - Returns a primitive object representation for this container (which is a dict). - - WARNING: The returned container does not contain any markup or formatting metadata. - """ - raw_container = raw.to_raw(self._navigable) - - # Collapsing the anonymous table onto the top-level container is present - if '' in raw_container: - raw_container.update(raw_container['']) - del raw_container[''] - - return raw_container - - def append_fresh_table(self, fresh_table): - """ - Gets called by FreshTable instances when they get written to. - """ - if fresh_table.name: - elements = [] - if fresh_table.is_array: - elements += [element_factory.create_array_of_tables_header_element(fresh_table.name)] - else: - elements += [element_factory.create_table_header_element(fresh_table.name)] - - elements += [fresh_table, element_factory.create_newline_element()] - self.append_elements(elements) - - else: - # It's an anonymous table - self.prepend_elements([fresh_table, element_factory.create_newline_element()]) - - @property - def elements(self): - return self._elements - - def __str__(self): - - is_empty = (not self['']) and (not tuple(k for k in self.keys() if k)) - - def key_name(key): - return '[ANONYMOUS]' if not key else key - - def pair(key, value): - return '%s = %s' % (key_name(key), str(value)) - - content_text = '' if is_empty else \ - '\n\t' + ',\n\t'.join(pair(k, v) for (k, v) in self.items() if v) + '\n' - - return "TOMLFile{%s}" % content_text - - def __repr__(self): - return str(self) - - - diff --git a/pipenv/patched/contoml/file/freshtable.py b/pipenv/patched/contoml/file/freshtable.py deleted file mode 100644 index f28e2f74d2..0000000000 --- a/pipenv/patched/contoml/file/freshtable.py +++ /dev/null @@ -1,45 +0,0 @@ -from prettytoml.elements.table import TableElement - - -class FreshTable(TableElement): - """ - A fresh TableElement that appended itself to each of parents when it first gets written to at most once. - - parents is a sequence of objects providing an append_fresh_table(TableElement) method - """ - - def __init__(self, parent, name, is_array=False): - TableElement.__init__(self, sub_elements=[]) - - self._parent = parent - self._name = name - self._is_array = is_array - - # As long as this flag is false, setitem() operations will append the table header and this table - # to the toml_file's elements - self.__appended = False - - @property - def name(self): - return self._name - - @property - def is_array(self): - return self._is_array - - def _append_to_parent(self): - """ - Causes this ephemeral table to be persisted on the TOMLFile. - """ - - if self.__appended: - return - - if self._parent is not None: - self._parent.append_fresh_table(self) - - self.__appended = True - - def __setitem__(self, key, value): - TableElement.__setitem__(self, key, value) - self._append_to_parent() diff --git a/pipenv/patched/contoml/file/peekableit.py b/pipenv/patched/contoml/file/peekableit.py deleted file mode 100644 index b5658a71c5..0000000000 --- a/pipenv/patched/contoml/file/peekableit.py +++ /dev/null @@ -1,30 +0,0 @@ -import itertools - - -class PeekableIterator: - - # Returned by peek() when the iterator is exhausted. Truthiness is False. - Nothing = tuple() - - def __init__(self, iter): - self._iter = iter - - def __next__(self): - return next(self._iter) - - def next(self): - return self.__next__() - - def __iter__(self): - return self - - def peek(self): - """ - Returns PeekableIterator.Nothing when the iterator is exhausted. - """ - try: - v = next(self._iter) - self._iter = itertools.chain((v,), self._iter) - return v - except StopIteration: - return PeekableIterator.Nothing diff --git a/pipenv/patched/contoml/file/raw.py b/pipenv/patched/contoml/file/raw.py deleted file mode 100644 index 8cffdb6e67..0000000000 --- a/pipenv/patched/contoml/file/raw.py +++ /dev/null @@ -1,16 +0,0 @@ -from prettytoml.elements.abstracttable import AbstractTable - - -def to_raw(x): - from contoml.file.cascadedict import CascadeDict - - if isinstance(x, AbstractTable): - return x.primitive_value - elif isinstance(x, CascadeDict): - return x.neutralized - elif isinstance(x, (list, tuple)): - return [to_raw(y) for y in x] - elif isinstance(x, dict): - return {k: to_raw(v) for (k, v) in x.items()} - else: - return x diff --git a/pipenv/patched/contoml/file/structurer.py b/pipenv/patched/contoml/file/structurer.py deleted file mode 100644 index 72d002cde2..0000000000 --- a/pipenv/patched/contoml/file/structurer.py +++ /dev/null @@ -1,116 +0,0 @@ -from contoml.file import toplevels -from contoml.file.cascadedict import CascadeDict - - -class NamedDict(dict): - """ - A dict that can use Name instances as keys. - """ - - def __init__(self, other_dict=None): - dict.__init__(self) - if other_dict: - for k, v in other_dict.items(): - self[k] = v - - def __setitem__(self, key, value): - """ - key can be an Name instance. - - When key is a path in the form of an Name instance, all the parents and grandparents of the value are - created along the way as instances of NamedDict. If the parent of the value exists, it is replaced with a - CascadeDict() that cascades the old parent value with a new NamedDict that contains the given child name - and value. - """ - if isinstance(key, toplevels.Name): - - if len(key.sub_names) == 1: - name = key.sub_names[0] - if name in self: - self[name] = CascadeDict(self[name], value) - else: - self[name] = value - - elif len(key.sub_names) > 1: - name = key.sub_names[0] - rest_of_key = key.drop(1) - if name in self: - named_dict = NamedDict() - named_dict[rest_of_key] = value - self[name] = CascadeDict(self[name], named_dict) - else: - self[name] = NamedDict() - self[name][rest_of_key] = value - else: - return dict.__setitem__(self, key, value) - - def __contains__(self, item): - try: - _ = self[item] - return True - except KeyError: - return False - - def append(self, key, value): - """ - Makes sure the value pointed to by key exists and is a list and appends the given value to it. - """ - if key in self: - self[key].append(value) - else: - self[key] = [value] - - def __getitem__(self, item): - - if isinstance(item, toplevels.Name): - d = self - for name in item.sub_names: - d = d[name] - return d - else: - return dict.__getitem__(self, item) - - -def structure(table_toplevels): - """ - Accepts an ordered sequence of TopLevel instances and returns a navigable object structure representation of the - TOML file. - """ - - table_toplevels = tuple(table_toplevels) - obj = NamedDict() - - last_array_of_tables = None # The Name of the last array-of-tables header - - for toplevel in table_toplevels: - - if isinstance(toplevel, toplevels.AnonymousTable): - obj[''] = toplevel.table_element - - elif isinstance(toplevel, toplevels.Table): - if last_array_of_tables and toplevel.name.is_prefixed_with(last_array_of_tables): - seq = obj[last_array_of_tables] - unprefixed_name = toplevel.name.without_prefix(last_array_of_tables) - - seq[-1] = CascadeDict(seq[-1], NamedDict({unprefixed_name: toplevel.table_element})) - else: - obj[toplevel.name] = toplevel.table_element - else: # It's an ArrayOfTables - - if last_array_of_tables and toplevel.name != last_array_of_tables and \ - toplevel.name.is_prefixed_with(last_array_of_tables): - - seq = obj[last_array_of_tables] - unprefixed_name = toplevel.name.without_prefix(last_array_of_tables) - - if unprefixed_name in seq[-1]: - seq[-1][unprefixed_name].append(toplevel.table_element) - else: - cascaded_with = NamedDict({unprefixed_name: [toplevel.table_element]}) - seq[-1] = CascadeDict(seq[-1], cascaded_with) - - else: - obj.append(toplevel.name, toplevel.table_element) - last_array_of_tables = toplevel.name - - return obj diff --git a/pipenv/patched/contoml/file/test_cascadedict.py b/pipenv/patched/contoml/file/test_cascadedict.py deleted file mode 100644 index d692711e7d..0000000000 --- a/pipenv/patched/contoml/file/test_cascadedict.py +++ /dev/null @@ -1,25 +0,0 @@ -from contoml.file.cascadedict import CascadeDict - - -def test_cascadedict(): - - d1 = {'a': 1, 'b': 2, 'c': 3} - d2 = {'b': 12, 'e': 4, 'f': 5} - - cascade = CascadeDict(d1, d2) - - # Test querying - assert cascade['a'] == 1 - assert cascade['b'] == 2 - assert cascade['c'] == 3 - assert cascade['e'] == 4 - assert cascade.keys() == {'a', 'b', 'c', 'e', 'f'} - assert set(cascade.items()) == {('a', 1), ('b', 2), ('c', 3), ('e', 4), ('f', 5)} - - # Test mutating - cascade['a'] = 11 - cascade['f'] = 'fff' - cascade['super'] = 'man' - assert d1['a'] == 11 - assert d1['super'] == 'man' - assert d1['f'] == 'fff' diff --git a/pipenv/patched/contoml/file/test_entries.py b/pipenv/patched/contoml/file/test_entries.py deleted file mode 100644 index 25584e8298..0000000000 --- a/pipenv/patched/contoml/file/test_entries.py +++ /dev/null @@ -1,20 +0,0 @@ -from prettytoml import parser, lexer -from contoml.file import toplevels - - -def test_entry_extraction(): - text = open('sample.toml').read() - elements = parser.parse_tokens(lexer.tokenize(text)) - - e = tuple(toplevels.identify(elements)) - - assert len(e) == 13 - assert isinstance(e[0], toplevels.AnonymousTable) - - -def test_entry_names(): - name_a = toplevels.Name(('super', 'sub1')) - name_b = toplevels.Name(('super', 'sub1', 'sub2', 'sub3')) - - assert name_b.is_prefixed_with(name_a) - assert name_b.without_prefix(name_a).sub_names == ('sub2', 'sub3') diff --git a/pipenv/patched/contoml/file/test_peekableit.py b/pipenv/patched/contoml/file/test_peekableit.py deleted file mode 100644 index 5c053a384c..0000000000 --- a/pipenv/patched/contoml/file/test_peekableit.py +++ /dev/null @@ -1,12 +0,0 @@ -from contoml.file.peekableit import PeekableIterator - - -def test_peekable_iterator(): - - peekable = PeekableIterator(i for i in (1, 2, 3, 4)) - - assert peekable.peek() == 1 - assert peekable.peek() == 1 - assert peekable.peek() == 1 - - assert [next(peekable), next(peekable), next(peekable), next(peekable)] == [1, 2, 3, 4] diff --git a/pipenv/patched/contoml/file/test_structurer.py b/pipenv/patched/contoml/file/test_structurer.py deleted file mode 100644 index b3ea4b4ef4..0000000000 --- a/pipenv/patched/contoml/file/test_structurer.py +++ /dev/null @@ -1,41 +0,0 @@ -from prettytoml import lexer, parser -from contoml.file import toplevels -from prettytoml.parser import elementsanitizer -from contoml.file.structurer import NamedDict, structure -from prettytoml.parser.tokenstream import TokenStream - - -def test_NamedDict(): - - d = NamedDict() - - d[toplevels.Name(('super', 'sub1', 'sub2'))] = {'sub3': 12} - d[toplevels.Name(('super', 'sub1', 'sub2'))]['sub4'] = 42 - - assert d[toplevels.Name(('super', 'sub1', 'sub2', 'sub3'))] == 12 - assert d[toplevels.Name(('super', 'sub1', 'sub2', 'sub4'))] == 42 - - -def test_structure(): - tokens = lexer.tokenize(open('sample.toml').read()) - elements = elementsanitizer.sanitize(parser.parse_tokens(tokens)) - entries_ = tuple(toplevels.identify(elements)) - - s = structure(entries_) - - assert s['']['title'] == 'TOML Example' - assert s['owner']['name'] == 'Tom Preston-Werner' - assert s['database']['ports'][1] == 8001 - assert s['servers']['alpha']['dc'] == 'eqdc10' - assert s['clients']['data'][1][0] == 1 - assert s['clients']['key3'] == 'The quick brown fox jumps over the lazy dog.' - - assert s['fruit'][0]['name'] == 'apple' - assert s['fruit'][0]['physical']['color'] == 'red' - assert s['fruit'][0]['physical']['shape'] == 'round' - assert s['fruit'][0]['variety'][0]['name'] == 'red delicious' - assert s['fruit'][0]['variety'][1]['name'] == 'granny smith' - - assert s['fruit'][1]['name'] == 'banana' - assert s['fruit'][1]['variety'][0]['name'] == 'plantain' - assert s['fruit'][1]['variety'][0]['points'][2]['y'] == 4 diff --git a/pipenv/patched/contoml/file/toplevels.py b/pipenv/patched/contoml/file/toplevels.py deleted file mode 100644 index 640380726d..0000000000 --- a/pipenv/patched/contoml/file/toplevels.py +++ /dev/null @@ -1,142 +0,0 @@ -""" - Top-level entries in a TOML file. -""" - -from prettytoml import elements -from prettytoml.elements import TableElement, TableHeaderElement -from .peekableit import PeekableIterator - - -class TopLevel: - """ - A abstract top-level entry. - """ - - def __init__(self, names, table_element): - self._table_element = table_element - self._names = Name(names) - - @property - def table_element(self): - return self._table_element - - @property - def name(self): - """ - The distinct name of a table entry as an Name instance. - """ - return self._names - - -class Name: - - def __init__(self, names): - self._names = names - - @property - def sub_names(self): - return self._names - - def drop(self, n=0): - """ - Returns the name after dropping the first n entries of it. - """ - return Name(names=self._names[n:]) - - def is_prefixed_with(self, names): - if isinstance(names, Name): - return self.is_prefixed_with(names.sub_names) - - for i, name in enumerate(names): - if self._names[i] != name: - return False - return True - - def without_prefix(self, names): - if isinstance(names, Name): - return self.without_prefix(names.sub_names) - - for i, name in enumerate(names): - if name != self._names[i]: - return Name(self._names[i:]) - return Name(names=self.sub_names[len(names):]) - - @property - def is_qualified(self): - return len(self._names) > 1 - - def __str__(self): - return '.'.join(self.sub_names) - - def __hash__(self): - return hash(str(self)) - - def __eq__(self, other): - return str(self) == str(other) - - def __ne__(self, other): - return not self.__eq__(other) - - -class AnonymousTable(TopLevel): - - def __init__(self, table_element): - TopLevel.__init__(self, ('',), table_element) - - -class Table(TopLevel): - - def __init__(self, names, table_element): - TopLevel.__init__(self, names=names, table_element=table_element) - - -class ArrayOfTables(TopLevel): - - def __init__(self, names, table_element): - TopLevel.__init__(self, names=names, table_element=table_element) - - -def _validate_file_elements(file_elements): - pass - - -def identify(file_elements): - """ - Outputs an ordered sequence of instances of TopLevel types. - - Elements start with an optional TableElement, followed by zero or more pairs of (TableHeaderElement, TableElement). - """ - - if not file_elements: - return - - _validate_file_elements(file_elements) - - # An iterator over enumerate(the non-metadata) elements - iterator = PeekableIterator((element_i, element) for (element_i, element) in enumerate(file_elements) - if element.type != elements.TYPE_METADATA) - - try: - _, first_element = iterator.peek() - if isinstance(first_element, TableElement): - iterator.next() - yield AnonymousTable(first_element) - except KeyError: - pass - except StopIteration: - return - - for element_i, element in iterator: - - if not isinstance(element, TableHeaderElement): - continue - - # If TableHeader of a regular table, return Table following it - if not element.is_array_of_tables: - table_element_i, table_element = next(iterator) - yield Table(names=element.names, table_element=table_element) - - # If TableHeader of an array of tables, do your thing - else: - table_element_i, table_element = next(iterator) - yield ArrayOfTables(names=element.names, table_element=table_element) diff --git a/pipenv/patched/patched.txt b/pipenv/patched/patched.txt index f73ed5a6e2..4f3ee409d7 100644 --- a/pipenv/patched/patched.txt +++ b/pipenv/patched/patched.txt @@ -3,5 +3,4 @@ git+https://github.com/jumpscale7/python-consistent-toml.git#egg=contoml crayons==0.1.2 pipfile==0.0.2 pip-tools==3.1.0 -prettytoml==0.3 pip==18.1 diff --git a/pipenv/patched/prettytoml/LICENSE b/pipenv/patched/prettytoml/LICENSE deleted file mode 100644 index 116fa4e558..0000000000 --- a/pipenv/patched/prettytoml/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Jumpscale - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -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 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. - diff --git a/pipenv/patched/prettytoml/__init__.py b/pipenv/patched/prettytoml/__init__.py deleted file mode 100644 index d731074832..0000000000 --- a/pipenv/patched/prettytoml/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -from ._version import VERSION - -__version__ = VERSION - - -def prettify(toml_text): - """ - Prettifies and returns the TOML file content provided. - """ - from .parser import parse_tokens - from .lexer import tokenize - from .prettifier import prettify as element_prettify - - tokens = tokenize(toml_text, is_top_level=True) - elements = parse_tokens(tokens) - prettified = element_prettify(elements) - return ''.join(pretty_element.serialized() for pretty_element in prettified) - - -def prettify_from_file(file_path): - """ - Reads, prettifies and returns the TOML file specified by the file_path. - """ - with open(file_path, 'r') as fp: - return prettify(fp.read()) diff --git a/pipenv/patched/prettytoml/_version.py b/pipenv/patched/prettytoml/_version.py deleted file mode 100644 index e0f154708e..0000000000 --- a/pipenv/patched/prettytoml/_version.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = 'master' diff --git a/pipenv/patched/prettytoml/elements/__init__.py b/pipenv/patched/prettytoml/elements/__init__.py deleted file mode 100644 index ece2112396..0000000000 --- a/pipenv/patched/prettytoml/elements/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ - -""" - TOML file elements (a higher abstraction layer than individual lexical tokens). -""" - -from .traversal import TraversalMixin -from .errors import InvalidElementError -from .table import TableElement -from .tableheader import TableHeaderElement -from .common import TYPE_METADATA, TYPE_ATOMIC, TYPE_CONTAINER, TYPE_MARKUP - -from . import traversal -from . import factory diff --git a/pipenv/patched/prettytoml/elements/abstracttable.py b/pipenv/patched/prettytoml/elements/abstracttable.py deleted file mode 100644 index 6a2c174aec..0000000000 --- a/pipenv/patched/prettytoml/elements/abstracttable.py +++ /dev/null @@ -1,92 +0,0 @@ -try: - from collections.abc import Mapping -except ImportError: - from collections import Mapping - -from prettytoml.elements.common import ContainerElement -from prettytoml.elements import traversal - - -class AbstractTable(ContainerElement, traversal.TraversalMixin, Mapping): - """ - Common code for handling tables as key-value pairs with metadata elements sprinkled all over. - - Assumes input sub_elements are correct. - """ - - def __init__(self, sub_elements): - ContainerElement.__init__(self, sub_elements) - self._fallback = None - - def _enumerate_items(self): - """ - Returns ((key_index, key_element), (value_index, value_element)) for all the element key-value pairs. - """ - non_metadata = self._enumerate_non_metadata_sub_elements() - while True: - try: - yield next(non_metadata), next(non_metadata) - except StopIteration: - return - - def items(self): - for (key_i, key), (value_i, value) in self._enumerate_items(): - yield key.value, value.value - if self._fallback: - for key, value in self._fallback.items(): - yield key, value - - def keys(self): - return tuple(key for (key, _) in self.items()) - - def values(self): - return tuple(value for (_, value) in self.items()) - - def __len__(self): - return len(tuple(self._enumerate_items())) - - def __iter__(self): - return (key for key, _ in self.items()) - - def __contains__(self, item): - return item in self.keys() - - def _find_key_and_value(self, key): - """ - Returns (key_i, value_i) corresponding to the given key value. - - Raises KeyError if no matching key found. - """ - for (key_i, key_element), (value_i, value_element) in self._enumerate_items(): - if key_element.value == key: - return key_i, value_i - raise KeyError - - def __getitem__(self, item): - for key, value in self.items(): - if key == item: - return value - raise KeyError - - def get(self, key, default=None): - try: - return self[key] - except KeyError: - return default - - def set_fallback(self, fallback): - """ - Sets a fallback dict-like instance to be used to look up values after they are not found - in this instance. - """ - self._fallback = fallback - - @property - def primitive_value(self): - """ - Returns a primitive Python value without any formatting or markup metadata. - """ - return { - key: - value.primitive_value if hasattr(value, 'primitive_value') else value for key, value in self.items() - } diff --git a/pipenv/patched/prettytoml/elements/array.py b/pipenv/patched/prettytoml/elements/array.py deleted file mode 100644 index 36c648b972..0000000000 --- a/pipenv/patched/prettytoml/elements/array.py +++ /dev/null @@ -1,136 +0,0 @@ -from prettytoml.elements import common, factory, traversal -from prettytoml.elements.common import Element, ContainerElement -from prettytoml.elements.factory import create_element -from prettytoml.elements.metadata import NewlineElement -from prettytoml.elements.errors import InvalidElementError - - -class ArrayElement(ContainerElement, traversal.TraversalMixin): - """ - A sequence-like container element containing other atomic elements or other containers. - - Implements list-like interface. - - Assumes input sub_elements are correct for an array element. - - Raises an InvalidElementError if contains heterogeneous values. - """ - - def __init__(self, sub_elements): - common.ContainerElement.__init__(self, sub_elements) - self._check_homogeneity() - - def _check_homogeneity(self): - if len(set(type(v) for v in self.primitive_value)) > 1: - raise InvalidElementError('Array should be homogeneous') - - def __len__(self): - return len(tuple(self._enumerate_non_metadata_sub_elements())) - - def __getitem__(self, i): - """ - Returns the ith entry, which can be a primitive value, a seq-lie, or a dict-like object. - """ - return self._find_value(i)[1].value - - def __setitem__(self, i, value): - value_i, _ = self._find_value(i) - new_element = value if isinstance(value, Element) else factory.create_element(value) - self._sub_elements = self.sub_elements[:value_i] + [new_element] + self.sub_elements[value_i+1:] - - @property - def value(self): - return self # self is a sequence-like value - - @property - def primitive_value(self): - """ - Returns a primitive Python value without any formatting or markup metadata. - """ - return list( - self[i].primitive_value if hasattr(self[i], 'primitive_value') - else self[i] - for i in range(len(self))) - - def __str__(self): - return "Array{}".format(self.primitive_value) - - def append(self, v): - new_entry = [create_element(v)] - - if self: # If not empty, we need a comma and whitespace prefix! - new_entry = [ - factory.create_operator_element(','), - factory.create_whitespace_element(), - ] + new_entry - - insertion_index = self._find_closing_square_bracket() - self._sub_elements = self._sub_elements[:insertion_index] + new_entry + \ - self._sub_elements[insertion_index:] - - def _find_value(self, i): - """ - Returns (value_index, value) of ith value in this sequence. - - Raises IndexError if not found. - """ - return tuple(self._enumerate_non_metadata_sub_elements())[i] - - def __delitem__(self, i): - value_i, value = self._find_value(i) - - begin, end = value_i, value_i+1 - - # Rules: - # 1. begin should be index to the preceding comma to the value - # 2. end should be index to the following comma, or the closing bracket - # 3. If no preceding comma found but following comma found then end should be the index of the following value - - preceding_comma = self._find_preceding_comma(value_i) - found_preceding_comma = preceding_comma >= 0 - if found_preceding_comma: - begin = preceding_comma - - following_comma = self._find_following_comma(value_i) - if following_comma >= 0: - if not found_preceding_comma: - end = self._find_following_non_metadata(following_comma) - else: - end = following_comma - else: - end = self._find_following_closing_square_bracket() - - self._sub_elements = self.sub_elements[:begin] + self._sub_elements[end:] - - @property - def is_multiline(self): - return any(isinstance(e, (NewlineElement)) for e in self.elements) - - def turn_into_multiline(self): - """ - Turns this array into a multi-line array with each element lying on its own line. - """ - if self.is_multiline: - return - - i = self._find_following_comma(-1) - - def next_entry_i(): - return self._find_following_non_metadata(i) - - def next_newline_i(): - return self._find_following_newline(i) - - def next_closing_bracket_i(): - return self._find_following_closing_square_bracket(i) - - def next_comma_i(): - return self._find_following_comma(i) - - while i < len(self.elements)-1: - if next_newline_i() < next_entry_i(): - self.elements.insert(i+1, factory.create_newline_element()) - if float('-inf') < next_comma_i() < next_closing_bracket_i(): - i = next_comma_i() - else: - i = next_closing_bracket_i() diff --git a/pipenv/patched/prettytoml/elements/atomic.py b/pipenv/patched/prettytoml/elements/atomic.py deleted file mode 100644 index 571810d9d8..0000000000 --- a/pipenv/patched/prettytoml/elements/atomic.py +++ /dev/null @@ -1,52 +0,0 @@ -from ..tokens import py2toml, toml2py -from . import common -from prettytoml.util import is_dict_like, is_sequence_like -from .errors import InvalidElementError - - -class AtomicElement(common.TokenElement): - """ - An element containing a sequence of tokens representing a single atomic value that can be updated in place. - - Raises: - InvalidElementError: when passed an invalid sequence of tokens. - """ - - def __init__(self, _tokens): - common.TokenElement.__init__(self, _tokens, common.TYPE_ATOMIC) - - def _validate_tokens(self, _tokens): - if len([token for token in _tokens if not token.type.is_metadata]) != 1: - raise InvalidElementError('Tokens making up an AtomicElement must contain only one non-metadata token') - - def serialized(self): - return ''.join(token.source_substring for token in self.tokens) - - def _value_token_index(self): - """ - Finds the token where the value is stored. - """ - # TODO: memoize this value - for i, token in enumerate(self.tokens): - if not token.type.is_metadata: - return i - raise RuntimeError('could not find a value token') - - @property - def value(self): - """ - Returns a Python value contained in this atomic element. - """ - return toml2py.deserialize(self._tokens[self._value_token_index()]) - - @property - def primitive_value(self): - return self.value - - def set(self, value): - """ - Sets the contained value to the given one. - """ - assert (not is_sequence_like(value)) and (not is_dict_like(value)), 'the value must be an atomic primitive' - token_index = self._value_token_index() - self._tokens[token_index] = py2toml.create_primitive_token(value) diff --git a/pipenv/patched/prettytoml/elements/common.py b/pipenv/patched/prettytoml/elements/common.py deleted file mode 100644 index 7508047ae9..0000000000 --- a/pipenv/patched/prettytoml/elements/common.py +++ /dev/null @@ -1,101 +0,0 @@ -from abc import abstractmethod - -TYPE_METADATA = 'element-metadata' -TYPE_ATOMIC = 'element-atomic' -TYPE_CONTAINER = 'element-container' -TYPE_MARKUP = 'element-markup' - -class Element: - """ - An Element: - - is one or more Token instances, or one or more other Element instances. Not both. - - knows how to serialize its value back to valid TOML code. - - A non-metadata Element is an Element that: - - knows how to deserialize its content into usable Python primitive, seq-like, or dict-like value. - - knows how to update its content from a Python primitive, seq-like, or dict-like value - while maintaining its formatting. - """ - - def __init__(self, _type): - self._type = _type - - @property - def type(self): - return self._type - - @abstractmethod - def serialized(self): - """ - TOML serialization of this element as str. - """ - raise NotImplementedError - - -class TokenElement(Element): - """ - An Element made up of tokens - """ - - def __init__(self, _tokens, _type): - Element.__init__(self, _type) - self._validate_tokens(_tokens) - self._tokens = list(_tokens) - - @property - def tokens(self): - return self._tokens - - @property - def first_token(self): - return self._tokens[0] - - @abstractmethod - def _validate_tokens(self, _tokens): - raise NotImplementedError - - def serialized(self): - return ''.join(token.source_substring for token in self._tokens) - - def __repr__(self): - return repr(self.tokens) - - @property - def primitive_value(self): - """ - Returns a primitive Python value without any formatting or markup metadata. - """ - raise NotImplementedError - - -class ContainerElement(Element): - """ - An Element containing exclusively other elements. - """ - - def __init__(self, sub_elements): - Element.__init__(self, TYPE_CONTAINER) - self._sub_elements = list(sub_elements) - - @property - def sub_elements(self): - return self._sub_elements - - @property - def elements(self): - return self.sub_elements - - def serialized(self): - return ''.join(element.serialized() for element in self.sub_elements) - - def __repr__(self): - return repr(self.primitive_value) - - @property - def primitive_value(self): - """ - Returns a primitive Python value without any formatting or markup metadata. - """ - raise NotImplementedError - - diff --git a/pipenv/patched/prettytoml/elements/errors.py b/pipenv/patched/prettytoml/elements/errors.py deleted file mode 100644 index 0fcf2e998d..0000000000 --- a/pipenv/patched/prettytoml/elements/errors.py +++ /dev/null @@ -1,13 +0,0 @@ - -class InvalidElementError(Exception): - """ - Raised by Element factories when the given sequence of tokens or sub-elements are invalid for the - specific type of Element being created. - """ - - def __init__(self, message): - self.message = message - - def __repr__(self): - return "InvalidElementError: {}".format(self.message) - diff --git a/pipenv/patched/prettytoml/elements/factory.py b/pipenv/patched/prettytoml/elements/factory.py deleted file mode 100644 index 177738dbd0..0000000000 --- a/pipenv/patched/prettytoml/elements/factory.py +++ /dev/null @@ -1,152 +0,0 @@ -import datetime -import functools -import six -from prettytoml import tokens -from prettytoml.tokens import py2toml -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import PunctuationElement, WhitespaceElement, NewlineElement -from prettytoml.elements.tableheader import TableHeaderElement -from prettytoml.util import join_with, is_sequence_like - - -def create_element(value, multiline_strings_allowed=True): - """ - Creates and returns the appropriate elements.Element instance from the given Python primitive, sequence-like, - or dict-like value. - """ - from prettytoml.elements.array import ArrayElement - - if isinstance(value, (int, float, bool, datetime.datetime, datetime.date) + six.string_types) or value is None: - primitive_token = py2toml.create_primitive_token(value, multiline_strings_allowed=multiline_strings_allowed) - return AtomicElement((primitive_token,)) - - elif isinstance(value, (list, tuple)): - preamble = [create_operator_element('[')] - postable = [create_operator_element(']')] - stuffing_elements = [create_element(v) for v in value] - spaced_stuffing = join_with(stuffing_elements, - separator=[create_operator_element(','), create_whitespace_element()]) - - return ArrayElement(preamble + spaced_stuffing + postable) - - elif isinstance(value, dict): - return create_inline_table(value, multiline_table=False, multiline_strings_allowed=multiline_strings_allowed) - - else: - raise RuntimeError('Value type unaccounted for: {} of type {}'.format(value, type(value))) - - -def create_inline_table(from_dict, multiline_table=False, multiline_strings_allowed=True): - """ - Creates an InlineTable element from the given dict instance. - """ - - from prettytoml.elements.inlinetable import InlineTableElement - - preamble = [create_operator_element('{')] - postable = [create_operator_element('}')] - - stuffing_elements = ( - ( - create_string_element(k, bare_allowed=True), - create_whitespace_element(), - create_operator_element('='), - create_whitespace_element(), - create_element(v, multiline_strings_allowed=False) - ) for (k, v) in from_dict.items()) - - pair_separator = [create_operator_element(','), - create_newline_element() if multiline_table else create_whitespace_element()] - spaced_elements = join_with(stuffing_elements, separator=pair_separator) - - return InlineTableElement(preamble + spaced_elements + postable) - - -def create_string_element(value, bare_allowed=False): - """ - Creates and returns an AtomicElement wrapping a string value. - """ - return AtomicElement((py2toml.create_string_token(value, bare_allowed),)) - - -def create_operator_element(operator): - """ - Creates a PunctuationElement instance containing an operator token of the specified type. The operator - should be a TOML source str. - """ - operator_type_map = { - ',': tokens.TYPE_OP_COMMA, - '=': tokens.TYPE_OP_ASSIGNMENT, - '[': tokens.TYPE_OP_SQUARE_LEFT_BRACKET, - ']': tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, - '[[': tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, - ']]': tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, - '{': tokens.TYPE_OP_CURLY_LEFT_BRACKET, - '}': tokens.TYPE_OP_CURLY_RIGHT_BRACKET, - } - - ts = (tokens.Token(operator_type_map[operator], operator),) - return PunctuationElement(ts) - - -def create_newline_element(): - """ - Creates and returns a single NewlineElement. - """ - ts = (tokens.Token(tokens.TYPE_NEWLINE, '\n'),) - return NewlineElement(ts) - - -def create_whitespace_element(length=1, char=' '): - """ - Creates and returns a WhitespaceElement containing spaces. - """ - ts = (tokens.Token(tokens.TYPE_WHITESPACE, char),) * length - return WhitespaceElement(ts) - - -def create_table_header_element(names): - - name_elements = [] - - if isinstance(names, six.string_types): - name_elements = [py2toml.create_string_token(names, bare_string_allowed=True)] - else: - for (i, name) in enumerate(names): - name_elements.append(py2toml.create_string_token(name, bare_string_allowed=True)) - if i < (len(names)-1): - name_elements.append(py2toml.operator_token(tokens.TYPE_OPT_DOT)) - - return TableHeaderElement( - [py2toml.operator_token(tokens.TYPE_OP_SQUARE_LEFT_BRACKET)] + name_elements + - [py2toml.operator_token(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET), py2toml.operator_token(tokens.TYPE_NEWLINE)], - ) - - -def create_array_of_tables_header_element(name): - return TableHeaderElement(( - py2toml.operator_token(tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET), - py2toml.create_string_token(name, bare_string_allowed=True), - py2toml.operator_token(tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET), - py2toml.operator_token(tokens.TYPE_NEWLINE), - )) - - -def create_table(dict_value): - """ - Creates a TableElement out of a dict instance. - """ - from prettytoml.elements.table import TableElement - - if not isinstance(dict_value, dict): - raise ValueError('input must be a dict instance.') - - table_element = TableElement([create_newline_element()]) - for k, v in dict_value.items(): - table_element[k] = create_element(v) - - return table_element - - -def create_multiline_string(text, maximum_line_length): - return AtomicElement(_tokens=[py2toml.create_multiline_string(text, maximum_line_length)]) diff --git a/pipenv/patched/prettytoml/elements/inlinetable.py b/pipenv/patched/prettytoml/elements/inlinetable.py deleted file mode 100644 index 7b985fc150..0000000000 --- a/pipenv/patched/prettytoml/elements/inlinetable.py +++ /dev/null @@ -1,78 +0,0 @@ -from prettytoml.elements import factory, abstracttable -from prettytoml.elements.common import Element - - -class InlineTableElement(abstracttable.AbstractTable): - """ - An Element containing key-value pairs, representing an inline table. - - Implements dict-like interface. - - Assumes input sub_elements are correct for an inline table element. - """ - - def __init__(self, sub_elements): - abstracttable.AbstractTable.__init__(self, sub_elements) - - def __setitem__(self, key, value): - - new_element = value if isinstance(value, Element) else factory.create_element(value) - - try: - - key_i, value_i = self._find_key_and_value(key) - # Found, then replace the value element with a new one - self._sub_elements = self.sub_elements[:value_i] + [new_element] + self.sub_elements[value_i+1:] - - except KeyError: # Key does not exist, adding anew! - - new_entry = [ - factory.create_string_element(key, bare_allowed=True), - factory.create_whitespace_element(), - factory.create_operator_element('='), - factory.create_whitespace_element(), - new_element, - ] - - if self: # If not empty - new_entry = [ - factory.create_operator_element(','), - factory.create_whitespace_element(), - ] + new_entry - - insertion_index = self._find_closing_curly_bracket() - self._sub_elements = self.sub_elements[:insertion_index] + new_entry + self.sub_elements[insertion_index:] - - def __delitem__(self, key): - - key_i, value_i = self._find_key_and_value(key) - - begin, end = key_i, value_i+1 - - # Rules: - # 1. begin should be index to the preceding comma to the key - # 2. end should be index to the following comma, or the closing bracket - # 3. If no preceding comma found but following comma found then end should be the index of the following key - - preceding_comma = self._find_preceding_comma(begin) - found_preceding_comma = preceding_comma >= 0 - if found_preceding_comma: - begin = preceding_comma - - following_comma = self._find_following_comma(value_i) - if following_comma >= 0: - if not found_preceding_comma: - end = self._find_following_non_metadata(following_comma) - else: - end = following_comma - else: - end = self._find_closing_curly_bracket() - - self._sub_elements = self.sub_elements[:begin] + self.sub_elements[end:] - - def multiline_equivalent(self): - return factory.create_inline_table(self.primitive_value, multiline_table=True, multiline_strings_allowed=True) - - @property - def value(self): - return self # self is a dict-like value that is perfectly usable diff --git a/pipenv/patched/prettytoml/elements/metadata.py b/pipenv/patched/prettytoml/elements/metadata.py deleted file mode 100644 index d5ee1061b1..0000000000 --- a/pipenv/patched/prettytoml/elements/metadata.py +++ /dev/null @@ -1,80 +0,0 @@ -from prettytoml import tokens -from prettytoml.elements import common -from .errors import InvalidElementError - - -class WhitespaceElement(common.TokenElement): - """ - An element that contains tokens of whitespace - """ - - def __init__(self, _tokens): - common.TokenElement.__init__(self, _tokens, common.TYPE_METADATA) - - def _validate_tokens(self, _tokens): - for token in _tokens: - if token.type != tokens.TYPE_WHITESPACE: - raise InvalidElementError('Tokens making up a WhitespaceElement must all be whitespace') - - @property - def length(self): - """ - The whitespace length of this element - """ - return len(self.tokens) - - -class NewlineElement(common.TokenElement): - """ - An element containing newline tokens - - Raises: - InvalidElementError: when passed an invalid sequence of tokens. - """ - - def __init__(self, _tokens): - common.TokenElement.__init__(self, _tokens, common.TYPE_METADATA) - - def _validate_tokens(self, _tokens): - for token in _tokens: - if token.type != tokens.TYPE_NEWLINE: - raise InvalidElementError('Tokens making a NewlineElement must all be newlines') - - -class CommentElement(common.TokenElement): - """ - An element containing a single comment token followed by a newline. - - Raises: - InvalidElementError: when passed an invalid sequence of tokens. - """ - - def __init__(self, _tokens): - common.TokenElement.__init__(self, _tokens, common.TYPE_METADATA) - - def _validate_tokens(self, _tokens): - if len(_tokens) != 2 or _tokens[0].type != tokens.TYPE_COMMENT or _tokens[1].type != tokens.TYPE_NEWLINE: - raise InvalidElementError('CommentElement needs one comment token followed by one newline token') - - -class PunctuationElement(common.TokenElement): - """ - An element containing a single punctuation token. - - Raises: - InvalidElementError: when passed an invalid sequence of tokens. - """ - - def __init__(self, _tokens): - common.TokenElement.__init__(self, _tokens, common.TYPE_METADATA) - - @property - def token(self): - """ - Returns the token contained in this Element. - """ - return self.tokens[0] - - def _validate_tokens(self, _tokens): - if not _tokens or not tokens.is_operator(_tokens[0]): - raise InvalidElementError('PunctuationElement must be made of only a single operator token') diff --git a/pipenv/patched/prettytoml/elements/table.py b/pipenv/patched/prettytoml/elements/table.py deleted file mode 100644 index cdc3ed4c51..0000000000 --- a/pipenv/patched/prettytoml/elements/table.py +++ /dev/null @@ -1,122 +0,0 @@ -from prettytoml.elements import abstracttable, factory -from prettytoml.elements.errors import InvalidElementError -from prettytoml.elements.common import Element -from prettytoml.elements.metadata import CommentElement, NewlineElement, WhitespaceElement -from . import common - - -class TableElement(abstracttable.AbstractTable): - """ - An Element containing an unnamed top-level table. - - Implements dict-like interface. - - Assumes input sub_elements are correct. - - Raises InvalidElementError on duplicate keys. - """ - - def __init__(self, sub_elements): - abstracttable.AbstractTable.__init__(self, sub_elements) - - self._check_for_duplicate_keys() - - def _check_for_duplicate_keys(self): - if len(set(self.keys())) < len(self.keys()): - raise InvalidElementError('Duplicate keys found') - - def __setitem__(self, key, value): - if key in self: - self._update(key, value) - else: - self._insert(key, value) - - def _update(self, key, value): - _, value_i = self._find_key_and_value(key) - self._sub_elements[value_i] = value if isinstance(value, Element) else factory.create_element(value) - - def _find_insertion_index(self): - """ - Returns the self.sub_elements index in which new entries should be inserted. - """ - - non_metadata_elements = tuple(self._enumerate_non_metadata_sub_elements()) - - if not non_metadata_elements: - return 0 - - last_entry_i = non_metadata_elements[-1][0] - following_newline_i = self._find_following_line_terminator(last_entry_i) - - return following_newline_i + 1 - - def _detect_indentation_size(self): - """ - Detects the level of indentation used in this table. - """ - - def lines(): - # Returns a sequence of sequences of elements belonging to each line - start = 0 - for i, element in enumerate(self.elements): - if isinstance(element, (CommentElement, NewlineElement)): - yield self.elements[start:i+1] - start = i+1 - - def indentation(line): - # Counts the number of whitespace tokens at the beginning of this line - try: - first_non_whitespace_i = next(i for (i, e) in enumerate(line) if not isinstance(e, WhitespaceElement)) - return sum(space.length for space in line[:first_non_whitespace_i]) - except StopIteration: - return 0 - - def is_empty_line(line): - return all(e.type == common.TYPE_METADATA for e in line) - - try: - return min(indentation(line) for line in lines() if len(line) > 1 and not is_empty_line(line)) - except ValueError: # Raised by ValueError when no matching lines found - return 0 - - def _insert(self, key, value): - - value_element = value if isinstance(value, Element) else factory.create_element(value) - - indentation_size = self._detect_indentation_size() - indentation = [factory.create_whitespace_element(self._detect_indentation_size())] if indentation_size else [] - - inserted_elements = indentation + [ - factory.create_string_element(key, bare_allowed=True), - factory.create_whitespace_element(), - factory.create_operator_element('='), - factory.create_whitespace_element(), - value_element, - factory.create_newline_element(), - ] - - insertion_index = self._find_insertion_index() - - self._sub_elements = \ - self.sub_elements[:insertion_index] + inserted_elements + self.sub_elements[insertion_index:] - - def __delitem__(self, key): - begin, _ = self._find_key_and_value(key) - preceding_newline = self._find_preceding_newline(begin) - if preceding_newline >= 0: - begin = preceding_newline - end = self._find_following_line_terminator(begin) - if end < 0: - end = len(tuple(self._sub_elements)) - self._sub_elements = self.sub_elements[:begin] + self.sub_elements[end:] - - def pop(self, key): - v = self[key] - del self[key] - return v - - def value(self): - return self - - def __str__(self): - return str(self.primitive_value) diff --git a/pipenv/patched/prettytoml/elements/tableheader.py b/pipenv/patched/prettytoml/elements/tableheader.py deleted file mode 100644 index eacd88b90f..0000000000 --- a/pipenv/patched/prettytoml/elements/tableheader.py +++ /dev/null @@ -1,95 +0,0 @@ -from prettytoml import tokens -from prettytoml.tokens import toml2py -from prettytoml.elements import common -from prettytoml.elements.common import Element, TokenElement -from prettytoml.elements.errors import InvalidElementError - -_opening_bracket_types = (tokens.TYPE_OP_SQUARE_LEFT_BRACKET, tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET) -_closing_bracket_types = (tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET) -_name_types = ( - tokens.TYPE_BARE_STRING, - tokens.TYPE_LITERAL_STRING, - tokens.TYPE_STRING, -) - - -class TableHeaderElement(TokenElement): - """ - An element containing opening and closing single and double square brackets, strings and dots and ending with - a newline. - - Raises InvalidElementError. - """ - - def __init__(self, _tokens): - TokenElement.__init__(self, _tokens, common.TYPE_MARKUP) - self._names = tuple(toml2py.deserialize(token) for token in self._tokens if token.type in _name_types) - - @property - def is_array_of_tables(self): - opening_bracket = next(token for i, token in enumerate(self._tokens) if token.type in _opening_bracket_types) - return opening_bracket.type == tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET - - @property - def names(self): - """ - Returns a sequence of string names making up this table header name. - """ - return self._names - - def has_name_prefix(self, names): - """ - Returns True if the header names is prefixed by the given sequence of names. - """ - for i, name in enumerate(names): - if self.names[i] != name: - return False - return True - - def serialized(self): - return ''.join(token.source_substring for token in self._tokens) - - def is_named(self, names): - """ - Returns True if the given name sequence matches the full name of this header. - """ - return tuple(names) == self.names - - def _validate_tokens(self, _tokens): - - opening_bracket_i = next((i for i, token in enumerate(_tokens) - if token.type in _opening_bracket_types), float('-inf')) - - if opening_bracket_i < 0: - raise InvalidElementError('Expected an opening bracket') - - _tokens = _tokens[opening_bracket_i+1:] - first_name_i = next((i for i, token in enumerate(_tokens) if token.type in _name_types), float('-inf')) - if first_name_i < 0: - raise InvalidElementError('Expected a table header name') - - _tokens = _tokens[first_name_i+1:] - - while True: - - next_dot_i = next((i for i, token in enumerate(_tokens) if token.type == tokens.TYPE_OPT_DOT), - float('-inf')) - if next_dot_i < 0: - break - - _tokens = _tokens[next_dot_i+1:] - - next_name_i = next((i for i, token in enumerate(_tokens) if token.type in _name_types), float('-inf')) - if next_name_i < 0: - raise InvalidElementError('Expected a name after the dot') - - _tokens = _tokens[next_name_i+1:] - - closing_bracket_i = next((i for i, token in enumerate(_tokens) if token.type in _closing_bracket_types), - float('-inf')) - - if closing_bracket_i < 0: - raise InvalidElementError('Expected a closing bracket') - - if _tokens[-1].type != tokens.TYPE_NEWLINE: - raise InvalidElementError('Must end with a newline') diff --git a/pipenv/patched/prettytoml/elements/test_array.py b/pipenv/patched/prettytoml/elements/test_array.py deleted file mode 100644 index 3ccc98b525..0000000000 --- a/pipenv/patched/prettytoml/elements/test_array.py +++ /dev/null @@ -1,67 +0,0 @@ -import pytest -from prettytoml import lexer -from prettytoml.elements.array import ArrayElement -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import PunctuationElement, WhitespaceElement, NewlineElement - - -def test_array_element(): - tokens = tuple(lexer.tokenize('[4, 8, 42, \n 23, 15]')) - assert len(tokens) == 17 - sub_elements = ( - PunctuationElement(tokens[:1]), - - AtomicElement(tokens[1:2]), - PunctuationElement(tokens[2:3]), - WhitespaceElement(tokens[3:4]), - - AtomicElement(tokens[4:5]), - PunctuationElement(tokens[5:6]), - WhitespaceElement(tokens[6:7]), - - AtomicElement(tokens[7:8]), - PunctuationElement(tokens[8:9]), - WhitespaceElement(tokens[9:10]), - NewlineElement(tokens[10:11]), - WhitespaceElement(tokens[11:12]), - - AtomicElement(tokens[12:13]), - PunctuationElement(tokens[13:14]), - - WhitespaceElement(tokens[14:15]), - AtomicElement(tokens[15:16]), - PunctuationElement(tokens[16:17]) - ) - - array_element = ArrayElement(sub_elements) - - # Test length - assert len(array_element) == 5 - - # Test getting a value - assert array_element[0] == 4 - assert array_element[1] == 8 - assert array_element[2] == 42 - assert array_element[3] == 23 - assert array_element[-1] == 15 - - # Test assignment with a negative index - array_element[-1] = 12 - - # Test persistence of formatting - assert '[4, 8, 42, \n 23, 12]' == array_element.serialized() - - # Test raises IndexError on invalid index - with pytest.raises(IndexError) as _: - print(array_element[5]) - - # Test appending a new value - array_element.append(77) - assert '[4, 8, 42, \n 23, 12, 77]' == array_element.serialized() - - # Test deleting a value - del array_element[3] - assert '[4, 8, 42, 12, 77]' == array_element.serialized() - - # Test primitive_value - assert [4, 8, 42, 12, 77] == array_element.primitive_value diff --git a/pipenv/patched/prettytoml/elements/test_atomic.py b/pipenv/patched/prettytoml/elements/test_atomic.py deleted file mode 100644 index 940ddd2757..0000000000 --- a/pipenv/patched/prettytoml/elements/test_atomic.py +++ /dev/null @@ -1,9 +0,0 @@ -from prettytoml import lexer -from prettytoml.elements.atomic import AtomicElement - - -def test_atomic_element(): - element = AtomicElement(tuple(lexer.tokenize(' \t 42 '))) - assert element.value == 42 - element.set(23) - assert element.serialized() == ' \t 23 ' diff --git a/pipenv/patched/prettytoml/elements/test_common.py b/pipenv/patched/prettytoml/elements/test_common.py deleted file mode 100644 index 9f5dd4c8f9..0000000000 --- a/pipenv/patched/prettytoml/elements/test_common.py +++ /dev/null @@ -1,89 +0,0 @@ -from prettytoml import tokens, lexer -from prettytoml.elements import traversal -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import NewlineElement, PunctuationElement, WhitespaceElement, CommentElement -from prettytoml.elements.table import TableElement -from prettytoml.elements.tableheader import TableHeaderElement - -atomic_token_types = ( - tokens.TYPE_INTEGER, - tokens.TYPE_FLOAT, - tokens.TYPE_BARE_STRING, - tokens.TYPE_STRING, - tokens.TYPE_LITERAL_STRING, - tokens.TYPE_MULTILINE_STRING, - tokens.TYPE_MULTILINE_LITERAL_STRING, -) - -punctuation_token_types = ( - tokens.TYPE_OPT_DOT, - tokens.TYPE_OP_CURLY_LEFT_BRACKET, - tokens.TYPE_OP_SQUARE_LEFT_BRACKET, - tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, - tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, - tokens.TYPE_OP_CURLY_RIGHT_BRACKET, - tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, - tokens.TYPE_OP_ASSIGNMENT, -) - -def primitive_token_to_primitive_element(token): - if token.type == tokens.TYPE_NEWLINE: - return NewlineElement((token,)) - elif token.type in atomic_token_types: - return AtomicElement((token,)) - elif token.type == tokens.TYPE_NEWLINE: - return NewlineElement((token,)) - elif token.type in punctuation_token_types: - return PunctuationElement((token,)) - elif token.type == tokens.TYPE_WHITESPACE: - return WhitespaceElement((token,)) - elif token.type == tokens.TYPE_COMMENT: - return CommentElement((token,)) - else: - raise RuntimeError("{} has no mapped primitive element".format(token)) - - -def primitive_tokens_to_primitive_elements(tokens): - return list(map(primitive_token_to_primitive_element, tokens)) - - -def dummy_file_elements(): - tokens_ = tuple(lexer.tokenize(""" -name = fawzy -another_name=another_fawzy - -[details] -id= 42 -section =fourth - -[[person]] -personname= lefawzy -dest=north - -[[person]] -dest=south -personname=lafawzy - -[details.extended] -number = 313 -type =complex""")) - - elements = \ - [TableElement(primitive_tokens_to_primitive_elements(tokens_[:12]))] + \ - [TableHeaderElement(tokens_[12:16])] + \ - [TableElement(primitive_tokens_to_primitive_elements(tokens_[16:25]))] + \ - [TableHeaderElement(tokens_[25:31])] + \ - [TableElement(primitive_tokens_to_primitive_elements(tokens_[31:39]))] + \ - [TableHeaderElement(tokens_[39:45])] + \ - [TableElement(primitive_tokens_to_primitive_elements(tokens_[45:53]))] + \ - [TableHeaderElement(tokens_[53:60])] + \ - [TableElement(primitive_tokens_to_primitive_elements(tokens_[60:]))] - - return elements - - -class DummyFile(traversal.TraversalMixin): - - @property - def elements(self): - return dummy_file_elements() diff --git a/pipenv/patched/prettytoml/elements/test_factory.py b/pipenv/patched/prettytoml/elements/test_factory.py deleted file mode 100644 index 08a4288301..0000000000 --- a/pipenv/patched/prettytoml/elements/test_factory.py +++ /dev/null @@ -1,22 +0,0 @@ -from collections import OrderedDict -from prettytoml.elements import factory -from prettytoml.elements.array import ArrayElement -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.inlinetable import InlineTableElement - - -def test_creating_elements(): - - atomic = factory.create_element(42) - assert isinstance(atomic, AtomicElement) - assert atomic.value == 42 - - seq = factory.create_element(['a', 'p', 'p', 'l', 'e']) - assert isinstance(seq, ArrayElement) - assert seq.serialized() == '["a", "p", "p", "l", "e"]' - assert ''.join(seq.primitive_value) == 'apple' - - mapping = factory.create_element(OrderedDict((('one', 1), ('two', 2)))) - assert isinstance(mapping, InlineTableElement) - assert mapping.serialized() == '{one = 1, two = 2}' - diff --git a/pipenv/patched/prettytoml/elements/test_inlinetable.py b/pipenv/patched/prettytoml/elements/test_inlinetable.py deleted file mode 100644 index 3c663873ed..0000000000 --- a/pipenv/patched/prettytoml/elements/test_inlinetable.py +++ /dev/null @@ -1,52 +0,0 @@ -from prettytoml import lexer -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.inlinetable import InlineTableElement -from prettytoml.elements.metadata import PunctuationElement, WhitespaceElement - - -def test_inline_table(): - tokens = tuple(lexer.tokenize('{ name= "first", id=42}')) - - elements = ( - PunctuationElement(tokens[:1]), - WhitespaceElement(tokens[1:2]), - AtomicElement(tokens[2:3]), - PunctuationElement(tokens[3:4]), - WhitespaceElement(tokens[4:5]), - AtomicElement(tokens[5:6]), - PunctuationElement(tokens[6:7]), - WhitespaceElement(tokens[7:8]), - AtomicElement(tokens[8:9]), - PunctuationElement(tokens[9:10]), - AtomicElement(tokens[10:11]), - PunctuationElement(tokens[11:12]) - ) - - table = InlineTableElement(elements) - - assert table['name'] == 'first' - assert table['id'] == 42 - - table['name'] = 'fawzy' - table['nickname'] = 'nickfawzy' - - assert set(table.items()) == {('name', 'fawzy'), ('id', 42), ('nickname', 'nickfawzy')} - - assert table.serialized() == '{ name= "fawzy", id=42, nickname = "nickfawzy"}' - - del table['name'] - - assert table.serialized() == '{ id=42, nickname = "nickfawzy"}' - - del table['nickname'] - - assert table.serialized() == '{ id=42}' - - del table['id'] - - assert table.serialized() == '{ }' - - table['item1'] = 11 - table['item2'] = 22 - - assert table.serialized() == '{ item1 = 11, item2 = 22}' diff --git a/pipenv/patched/prettytoml/elements/test_metadata.py b/pipenv/patched/prettytoml/elements/test_metadata.py deleted file mode 100644 index 6e49fedd72..0000000000 --- a/pipenv/patched/prettytoml/elements/test_metadata.py +++ /dev/null @@ -1,25 +0,0 @@ -from prettytoml import lexer -from prettytoml.elements.metadata import WhitespaceElement, NewlineElement, CommentElement, PunctuationElement - - -def test_whitespace_element(): - element = WhitespaceElement(tuple(lexer.tokenize(' \t '))) - assert element.serialized() == ' \t ' - - -def test_newline_element(): - element = NewlineElement(tuple(lexer.tokenize('\n\n\n'))) - assert element.serialized() == '\n\n\n' - - -def test_comment_element(): - element = CommentElement(tuple(lexer.tokenize('# This is my insightful remark\n'))) - assert element.serialized() == '# This is my insightful remark\n' - - -def test_punctuation_element(): - PunctuationElement(tuple(lexer.tokenize('['))) - PunctuationElement(tuple(lexer.tokenize('[['))) - PunctuationElement(tuple(lexer.tokenize('.'))) - PunctuationElement(tuple(lexer.tokenize(']'))) - PunctuationElement(tuple(lexer.tokenize(']]'))) diff --git a/pipenv/patched/prettytoml/elements/test_table.py b/pipenv/patched/prettytoml/elements/test_table.py deleted file mode 100644 index ef0dba8132..0000000000 --- a/pipenv/patched/prettytoml/elements/test_table.py +++ /dev/null @@ -1,59 +0,0 @@ -from prettytoml import lexer -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import WhitespaceElement, PunctuationElement, NewlineElement, CommentElement -from prettytoml.elements.table import TableElement - - -def test_table(): - - initial_toml = """name = "first" -id=42 # My id - - -""" - - tokens = tuple(lexer.tokenize(initial_toml)) - - elements = ( - AtomicElement(tokens[:1]), - WhitespaceElement(tokens[1:2]), - PunctuationElement(tokens[2:3]), - WhitespaceElement(tokens[3:4]), - AtomicElement(tokens[4:5]), - NewlineElement(tokens[5:6]), - - AtomicElement(tokens[6:7]), - PunctuationElement(tokens[7:8]), - AtomicElement(tokens[8:9]), - WhitespaceElement(tokens[9:10]), - CommentElement(tokens[10:12]), - - NewlineElement(tokens[12:13]), - NewlineElement(tokens[13:14]), - ) - - table = TableElement(elements) - - assert set(table.items()) == {('name', 'first'), ('id', 42)} - - assert table['name'] == 'first' - assert table['id'] == 42 - - table['relation'] = 'another' - - assert set(table.items()) == {('name', 'first'), ('id', 42), ('relation', 'another')} - - table['name'] = 'fawzy' - - assert set(table.items()) == {('name', 'fawzy'), ('id', 42), ('relation', 'another')} - - expected_toml = """name = "fawzy" -id=42 # My id -relation = "another" - - -""" - - assert table.serialized() == expected_toml - - diff --git a/pipenv/patched/prettytoml/elements/test_tableheader.py b/pipenv/patched/prettytoml/elements/test_tableheader.py deleted file mode 100644 index 67b1ded49c..0000000000 --- a/pipenv/patched/prettytoml/elements/test_tableheader.py +++ /dev/null @@ -1,12 +0,0 @@ -from prettytoml import lexer -from prettytoml.elements.tableheader import TableHeaderElement - - -def test_tableheader(): - tokens = tuple(lexer.tokenize('\n\t [[personal. information.details]] \n')) - element = TableHeaderElement(tokens) - - assert element.is_array_of_tables - assert ('personal', 'information', 'details') == element.names - - assert element.has_name_prefix(('personal', 'information')) diff --git a/pipenv/patched/prettytoml/elements/test_traversal.py b/pipenv/patched/prettytoml/elements/test_traversal.py deleted file mode 100644 index 2f00257165..0000000000 --- a/pipenv/patched/prettytoml/elements/test_traversal.py +++ /dev/null @@ -1,18 +0,0 @@ -from prettytoml.elements.test_common import DummyFile - - -def test_traversal(): - dummy_file = DummyFile() - - assert dummy_file._find_following_table_header(-1) == 1 - assert dummy_file._find_following_table_header(1) == 3 - assert dummy_file._find_following_table_header(3) == 5 - assert dummy_file._find_following_table_header(5) == 7 - assert dummy_file._find_following_table_header(7) < 0 - - assert dummy_file._find_preceding_table(30) == 8 - assert dummy_file._find_preceding_table(8) == 6 - assert dummy_file._find_preceding_table(6) == 4 - assert dummy_file._find_preceding_table(4) == 2 - assert dummy_file._find_preceding_table(2) == 0 - assert dummy_file._find_preceding_table(0) < 0 diff --git a/pipenv/patched/prettytoml/elements/traversal/__init__.py b/pipenv/patched/prettytoml/elements/traversal/__init__.py deleted file mode 100644 index c93506e2ed..0000000000 --- a/pipenv/patched/prettytoml/elements/traversal/__init__.py +++ /dev/null @@ -1,175 +0,0 @@ -from prettytoml import tokens -from prettytoml.elements import common -from prettytoml.elements.metadata import PunctuationElement, NewlineElement -from prettytoml.elements.traversal import predicates - - -class TraversalMixin: - """ - A mix-in that provides convenient sub-element traversal to any class with - an `elements` member that is a sequence of Element instances - """ - - def __find_following_element(self, index, predicate): - """ - Finds and returns the index of element in self.elements that evaluates the given predicate to True - and whose index is higher than the given index, or returns -Infinity on failure. - """ - return find_following(self.elements, predicate, index) - - def __find_preceding_element(self, index, predicate): - """ - Finds and returns the index of the element in self.elements that evaluates the given predicate to True - and whose index is lower than the given index. - """ - i = find_previous(self.elements, predicate, index) - if i == float('inf'): - return float('-inf') - return i - - def __must_find_following_element(self, predicate): - """ - Finds and returns the index to the element in self.elements that evaluatest the predicate to True, or raises - an error. - """ - i = self.__find_following_element(-1, predicate) - if i < 0: - raise RuntimeError('Could not find non-optional element') - return i - - def _enumerate_non_metadata_sub_elements(self): - """ - Returns a sequence of of (index, sub_element) of the non-metadata sub-elements. - """ - return ((i, element) for i, element in enumerate(self.elements) if element.type != common.TYPE_METADATA) - - def _find_preceding_comma(self, index): - """ - Returns the index of the preceding comma element to the given index, or -Infinity. - """ - return self.__find_preceding_element(index, predicates.op_comma) - - def _find_following_comma(self, index): - """ - Returns the index of the following comma element after the given index, or -Infinity. - """ - def predicate(element): - return isinstance(element, PunctuationElement) and element.token.type == tokens.TYPE_OP_COMMA - return self.__find_following_element(index, predicate) - - def _find_following_newline(self, index): - """ - Returns the index of the following newline element after the given index, or -Infinity. - """ - return self.__find_following_element(index, lambda e: isinstance(e, NewlineElement)) - - def _find_following_comment(self, index): - """ - Returns the index of the following comment element after the given index, or -Infinity. - """ - return self.__find_following_element(index, predicates.comment) - - def _find_following_line_terminator(self, index): - """ - Returns the index of the following comment or newline element after the given index, or -Infinity. - """ - following_comment = self._find_following_comment(index) - following_newline = self._find_following_newline(index) - - if following_comment == float('-inf'): - return following_newline - if following_newline == float('-inf'): - return following_comment - - if following_newline < following_comment: - return following_newline - else: - return following_comment - - def _find_preceding_newline(self, index): - """ - Returns the index of the preceding newline element to the given index, or -Infinity. - """ - return self.__find_preceding_element(index, predicates.newline) - - def _find_following_non_metadata(self, index): - """ - Returns the index to the following non-metadata element after the given index, or -Infinity. - """ - return self.__find_following_element(index, predicates.non_metadata) - - def _find_closing_square_bracket(self): - """ - Returns the index to the closing square bracket, or raises an Error. - """ - - return self.__must_find_following_element(predicates.closing_square_bracket) - - def _find_following_opening_square_bracket(self, index): - """ - Returns the index to the opening square bracket, or -Infinity. - """ - return self.__find_following_element(index, predicates.opening_square_bracket) - - def _find_following_closing_square_bracket(self, index): - """ - Returns the index to the closing square bracket, or -Infinity. - """ - return self.__find_following_element(index, predicates.closing_square_bracket) - - def _find_following_table(self, index): - """ - Returns the index to the next TableElement after the specified index, or -Infinity. - """ - return self.__find_following_element(index, predicates.table) - - def _find_preceding_table(self, index): - """ - Returns the index to the preceding TableElement to the specified index, or -Infinity. - """ - return self.__find_preceding_element(index,predicates.table) - - def _find_closing_curly_bracket(self): - """ - Returns the index to the closing curly bracket, or raises an Error. - """ - def predicate(element): - return isinstance(element, PunctuationElement) and element.token.type == tokens.TYPE_OP_CURLY_RIGHT_BRACKET - return self.__must_find_following_element(predicate) - - def _find_following_table_header(self, index): - """ - Returns the index to the table header after the given element index, or -Infinity. - """ - return self.__find_following_element(index, predicates.table_header) - - -def find_following(element_seq, predicate, index=None): - """ - Finds and returns the index of the next element fulfilling the specified predicate after the specified - index, or -Infinity. - - Starts searching linearly from the start_from index. - """ - - if isinstance(index, (int, float)) and index < 0: - index = None - - for i, element in tuple(enumerate(element_seq))[index+1 if index is not None else index:]: - if predicate(element): - return i - return float('-inf') - - -def find_previous(element_seq, predicate, index=None): - """ - Finds and returns the index of the previous element fulfilling the specified predicate preceding to the specified - index, or Infinity. - """ - if isinstance(index, (int, float)) and index >= len(element_seq): - index = None - - for i, element in reversed(tuple(enumerate(element_seq))[:index]): - if predicate(element): - return i - return float('inf') diff --git a/pipenv/patched/prettytoml/elements/traversal/predicates.py b/pipenv/patched/prettytoml/elements/traversal/predicates.py deleted file mode 100644 index f18616bfda..0000000000 --- a/pipenv/patched/prettytoml/elements/traversal/predicates.py +++ /dev/null @@ -1,48 +0,0 @@ - -""" - The following predicates can be used in the traversal functions directly. -""" - -from ..atomic import AtomicElement -from ..metadata import PunctuationElement, CommentElement, NewlineElement, WhitespaceElement -from prettytoml import tokens -from .. import common - - -atomic = lambda e: isinstance(e, AtomicElement) - - -op_assignment = lambda e: isinstance(e, PunctuationElement) and e.token.type == tokens.TYPE_OP_ASSIGNMENT - - -op_comma = lambda e: isinstance(e, PunctuationElement) and e.token.type == tokens.TYPE_OP_COMMA - - -comment = lambda e: isinstance(e, CommentElement) - - -newline = lambda e: isinstance(e, NewlineElement) - - -non_metadata = lambda e: e.type != common.TYPE_METADATA - - -closing_square_bracket = \ - lambda e: isinstance(e, PunctuationElement) and e.token.type == tokens.TYPE_OP_SQUARE_RIGHT_BRACKET - - -opening_square_bracket = \ - lambda e: isinstance(e, PunctuationElement) and e.token.type == tokens.TYPE_OP_SQUARE_LEFT_BRACKET - - -def table(e): - from ..table import TableElement - return isinstance(e, TableElement) - - -def table_header(e): - from prettytoml.elements.tableheader import TableHeaderElement - return isinstance(e, TableHeaderElement) - - -whitespace = lambda e: isinstance(e, WhitespaceElement) diff --git a/pipenv/patched/prettytoml/errors.py b/pipenv/patched/prettytoml/errors.py deleted file mode 100644 index 23e69eb583..0000000000 --- a/pipenv/patched/prettytoml/errors.py +++ /dev/null @@ -1,32 +0,0 @@ - - -class TOMLError(Exception): - """ - All errors raised by this module are descendants of this type. - """ - - -class InvalidTOMLFileError(TOMLError): - pass - - -class NoArrayFoundError(TOMLError): - """ - An array of tables was requested but none exist by the given name. - """ - - -class InvalidValueError(TOMLError): - pass - - -class DuplicateKeysError(TOMLError): - """ - Duplicate keys detected in the parsed file. - """ - - -class DuplicateTablesError(TOMLError): - """ - Duplicate tables detected in the parsed file. - """ diff --git a/pipenv/patched/prettytoml/lexer/__init__.py b/pipenv/patched/prettytoml/lexer/__init__.py deleted file mode 100644 index da32963a14..0000000000 --- a/pipenv/patched/prettytoml/lexer/__init__.py +++ /dev/null @@ -1,123 +0,0 @@ - -""" -A regular expression based Lexer/tokenizer for TOML. -""" - -from collections import namedtuple -import re -from prettytoml import tokens -from prettytoml.errors import TOMLError - -TokenSpec = namedtuple('TokenSpec', ('type', 're')) - -# Specs of all the valid tokens -_LEXICAL_SPECS = ( - TokenSpec(tokens.TYPE_COMMENT, re.compile(r'^(#.*)\n')), - TokenSpec(tokens.TYPE_STRING, re.compile(r'^("(([^"]|\\")+?[^\\]|([^"]|\\")|)")')), # Single line only - TokenSpec(tokens.TYPE_MULTILINE_STRING, re.compile(r'^(""".*?""")', re.DOTALL)), - TokenSpec(tokens.TYPE_LITERAL_STRING, re.compile(r"^('.*?')")), - TokenSpec(tokens.TYPE_MULTILINE_LITERAL_STRING, re.compile(r"^('''.*?''')", re.DOTALL)), - TokenSpec(tokens.TYPE_BARE_STRING, re.compile(r'^([A-Za-z0-9_-]+)')), - TokenSpec(tokens.TYPE_DATE, re.compile( - r'^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]*)?)?(([zZ])|((\+|-)[0-9]{2}:[0-9]{2}))?)')), - TokenSpec(tokens.TYPE_WHITESPACE, re.compile(r'^( |\t)', re.DOTALL)), - TokenSpec(tokens.TYPE_INTEGER, re.compile(r'^(((\+|-)[0-9_]+)|([0-9][0-9_]*))')), - TokenSpec(tokens.TYPE_FLOAT, - re.compile(r'^((((\+|-)[0-9_]+)|([1-9][0-9_]*))(\.[0-9_]+)?([eE](\+|-)?[0-9_]+)?)')), - TokenSpec(tokens.TYPE_BOOLEAN, re.compile(r'^(true|false)')), - TokenSpec(tokens.TYPE_OP_SQUARE_LEFT_BRACKET, re.compile(r'^(\[)')), - TokenSpec(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, re.compile(r'^(\])')), - TokenSpec(tokens.TYPE_OP_CURLY_LEFT_BRACKET, re.compile(r'^(\{)')), - TokenSpec(tokens.TYPE_OP_CURLY_RIGHT_BRACKET, re.compile(r'^(\})')), - TokenSpec(tokens.TYPE_OP_ASSIGNMENT, re.compile(r'^(=)')), - TokenSpec(tokens.TYPE_OP_COMMA, re.compile(r'^(,)')), - TokenSpec(tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, re.compile(r'^(\[\[)')), - TokenSpec(tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, re.compile(r'^(\]\])')), - TokenSpec(tokens.TYPE_OPT_DOT, re.compile(r'^(\.)')), - TokenSpec(tokens.TYPE_NEWLINE, re.compile('^(\n|\r\n)')), -) - - -def _next_token_candidates(source): - matches = [] - for token_spec in _LEXICAL_SPECS: - match = token_spec.re.search(source) - if match: - matches.append(tokens.Token(token_spec.type, match.group(1))) - return matches - - -def _choose_from_next_token_candidates(candidates): - - if len(candidates) == 1: - return candidates[0] - elif len(candidates) > 1: - # Return the maximal-munch with ties broken by natural order of token type. - maximal_munch_length = max(len(token.source_substring) for token in candidates) - maximal_munches = [token for token in candidates if len(token.source_substring) == maximal_munch_length] - return sorted(maximal_munches)[0] # Return the first in sorting by priority - - -def _munch_a_token(source): - """ - Munches a single Token instance if it could recognize one at the beginning of the - given source text, or None if no token type could be recognized. - """ - candidates = _next_token_candidates(source) - return _choose_from_next_token_candidates(candidates) - - -class LexerError(TOMLError): - - def __init__(self, message): - self._message = message - - def __repr__(self): - return self._message - - def __str__(self): - return self._message - - -def tokenize(source, is_top_level=False): - """ - Tokenizes the input TOML source into a stream of tokens. - - If is_top_level is set to True, will make sure that the input source has a trailing newline character - before it is tokenized. - - Raises a LexerError when it fails recognize another token while not at the end of the source. - """ - - # Newlines are going to be normalized to UNIX newlines. - source = source.replace('\r\n', '\n') - - if is_top_level and source and source[-1] != '\n': - source += '\n' - - next_row = 1 - next_col = 1 - next_index = 0 - - while next_index < len(source): - - new_token = _munch_a_token(source[next_index:]) - - if not new_token: - raise LexerError("failed to read the next token at ({}, {}): {}".format( - next_row, next_col, source[next_index:])) - - # Set the col and row on the new token - new_token = tokens.Token(new_token.type, new_token.source_substring, next_col, next_row) - - # Advance the index, row and col count - next_index += len(new_token.source_substring) - for c in new_token.source_substring: - if c == '\n': - next_row += 1 - next_col = 1 - else: - next_col += 1 - - yield new_token - diff --git a/pipenv/patched/prettytoml/lexer/test_lexer.py b/pipenv/patched/prettytoml/lexer/test_lexer.py deleted file mode 100644 index df10b46dfd..0000000000 --- a/pipenv/patched/prettytoml/lexer/test_lexer.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- - -from prettytoml.lexer import _munch_a_token -from prettytoml.lexer import * - -# A mapping from token types to a sequence of pairs of (source_text, expected_matched_text) -valid_tokens = { - tokens.TYPE_COMMENT: ( - ( - '# My very insightful comment about the state of the universe\n# And now for something completely different!', - '# My very insightful comment about the state of the universe', - ), - ), - tokens.TYPE_STRING: ( - ('"a valid hug3 text" "some other string" = 42', '"a valid hug3 text"'), - ( - r'"I\'m a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." "some other string" = 42', - r'"I\'m a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."' - ), - ('"ʎǝʞ" key', '"ʎǝʞ"'), - ('""', '""'), - ('"t"', '"t"'), - ), - tokens.TYPE_MULTILINE_STRING: ( - ('"""\nRoses are red\nViolets are blue""" """other text"""', '"""\nRoses are red\nViolets are blue"""'), - ), - tokens.TYPE_LITERAL_STRING: ( - (r"'This is \ \n a \\ literal string' 'another \ literal string'", r"'This is \ \n a \\ literal string'"), - ), - tokens.TYPE_MULTILINE_LITERAL_STRING: ( - ( - "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n''' '''some other\n\n\t string'''", - "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''" - ), - ), - tokens.TYPE_DATE: ( - ('1979-05-27 5345', '1979-05-27'), - ('1979-05-27T07:32:00Z something', '1979-05-27T07:32:00Z'), - ('1979-05-27T00:32:00-07:00 ommm', '1979-05-27T00:32:00-07:00'), - ('1979-05-27T00:32:00.999999-07:00 2346', '1979-05-27T00:32:00.999999-07:00'), - ), - tokens.TYPE_WHITESPACE: ( - (' \t\n \r some_text', ' '), - ), - tokens.TYPE_INTEGER: ( - ('+99 "number"', "+99"), - ('42 fwfwef', "42"), - ('-17 fh34g34g', "-17"), - ('5_349_221 apples', "5_349_221"), - ('-1_2_3_4_5 steps', '-1_2_3_4_5') - ), - tokens.TYPE_FLOAT: ( - ('1.0 fwef', '1.0'), - ('3.1415 g4g', '3.1415'), - ('-0.01 433re', '-0.01'), - ('5e+2_2 ersdvf', '5e+2_2'), - ('1e6 ewe23', '1e6'), - ('-2E-2.2 3 rf23', '-2E-2'), - ('6.626e-34 +234f', '6.626e-34'), - ('9_224_617.445_991_228_313 f1ewer 23f4h = nonesense', '9_224_617.445_991_228_313'), - ('1e1_000 2346f,ef2!!', '1e1_000'), - ), - tokens.TYPE_BOOLEAN: ( - ('false business = true', 'false'), - ('true true', 'true'), - ), - tokens.TYPE_OP_SQUARE_LEFT_BRACKET: ( - ('[table_name]', '['), - ), - tokens.TYPE_OP_SQUARE_RIGHT_BRACKET: ( - (']\nbusiness = awesome', ']'), - ), - tokens.TYPE_OP_CURLY_LEFT_BRACKET: ( - ('{item_exists = no}', '{'), - ), - tokens.TYPE_OP_CURLY_RIGHT_BRACKET: ( - ('} moving on', '}'), - ), - tokens.TYPE_OP_COMMA: ( - (',item2,item4', ','), - ), - tokens.TYPE_OP_ASSIGNMENT: ( - ('== 42', '='), - ), - tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET: ( - ('[[array.of.tables]]', '[['), - ), - tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET: ( - (']] item=3', ']]'), - ), - tokens.TYPE_BARE_STRING: ( - ('key another', 'key'), - ('bare_key 2fews', 'bare_key'), - ('bare-key kfcw', 'bare-key'), - ), - tokens.TYPE_OPT_DOT: ( - ('."another key"', '.'), - ('.subname', '.'), - ), - tokens.TYPE_NEWLINE: ( - ('\n\r \n', '\n'), - ) -} - -# A mapping from a token type to a sequence of (source, matched_text) pairs that shouldn't result from consuming the -# source text. -invalid_tokens = { - tokens.TYPE_INTEGER: ( - ('_234_423', ''), - ('0446234234', ''), - ), - tokens.TYPE_STRING: ( - ('"""', '"""'), - ), - tokens.TYPE_BOOLEAN: ( - ('True', 'True'), - ('True', 'true'), - ), - tokens.TYPE_FLOAT: ( - ('', ''), - ) -} - - -def test_valid_tokenizing(): - for token_type in valid_tokens: - for (source, expected_match) in valid_tokens[token_type]: - - token = _munch_a_token(source) - assert token, "Failed to tokenize: {}\nExpected: {}\nOut of: {}\nGot nothing!".format( - token_type, expected_match, source) - - assert token.type == token_type, \ - "Expected type: {}\nOut of: {}\nThat matched: {}\nOf type: {}".format( - token_type, source, token.source_substring, token.type) - assert token.source_substring == expected_match - - -def test_invalid_tokenizing(): - for token_type in invalid_tokens: - for source, expected_match in invalid_tokens[token_type]: - token = _munch_a_token(source) - if token: - assert not (token.type == token_type and token.source_substring == expected_match) - - -def test_token_type_order(): - type_a = tokens.TokenType('a', 5, is_metadata=False) - type_b = tokens.TokenType('b', 0, is_metadata=False) - type_c = tokens.TokenType('c', 3, is_metadata=False) - - assert type_b < type_c < type_a - assert type_a > type_c > type_b diff --git a/pipenv/patched/prettytoml/parser/__init__.py b/pipenv/patched/prettytoml/parser/__init__.py deleted file mode 100644 index 4cf600c08e..0000000000 --- a/pipenv/patched/prettytoml/parser/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ - -""" - A parser for TOML tokens into TOML elements. -""" - - -from prettytoml.parser.errors import ParsingError - - -def parse_tokens(tokens): - """ - Parses the given token sequence into a sequence of top-level TOML elements. - - Raises ParserError on invalid TOML input. - """ - from .tokenstream import TokenStream - return _parse_token_stream(TokenStream(tokens)) - - -def _parse_token_stream(token_stream): - """ - Parses the given token_stream into a sequence of top-level TOML elements. - - Raises ParserError on invalid input TOML. - """ - from .parser import toml_file_elements - from .elementsanitizer import sanitize - - elements, pending = toml_file_elements(token_stream) - - if not pending.at_end: - raise ParsingError('Failed to parse line {}'.format(pending.head.row)) - - return sanitize(elements) diff --git a/pipenv/patched/prettytoml/parser/elementsanitizer.py b/pipenv/patched/prettytoml/parser/elementsanitizer.py deleted file mode 100644 index bec4893a98..0000000000 --- a/pipenv/patched/prettytoml/parser/elementsanitizer.py +++ /dev/null @@ -1,58 +0,0 @@ -from prettytoml import elements -from prettytoml.elements.table import TableElement -from prettytoml.elements.tableheader import TableHeaderElement -from prettytoml.errors import InvalidTOMLFileError -from prettytoml.util import PeekableIterator - - -def sanitize(_elements): - """ - Finds TableHeader elements that are not followed by TableBody elements and inserts empty TableElement - right after those. - """ - - output = list(_elements) - - def find_next_table_header(after=-1): - return next((i for (i, element) in enumerate(output) - if i > after and isinstance(element, TableHeaderElement)), float('-inf')) - - def find_next_table_body(after=-1): - return next((i for (i, element) in enumerate(output) - if i > after and isinstance(element, TableElement)), float('-inf')) - - next_table_header_i = find_next_table_header() - while next_table_header_i >= 0: - - following_table_header_i = find_next_table_header(next_table_header_i) - following_table_body_i = find_next_table_body(next_table_header_i) - - if (following_table_body_i < 0) or \ - (following_table_header_i >= 0 and (following_table_header_i < following_table_body_i)): - output.insert(next_table_header_i+1, TableElement(tuple())) - - next_table_header_i = find_next_table_header(next_table_header_i) - - return output - - -def validate_sanitized(_elements): - - # Non-metadata elements must start with an optional TableElement, followed by - # zero or more (TableHeaderElement, TableElement) pairs. - - if not _elements: - return - - it = PeekableIterator(e for e in _elements if e.type != elements.TYPE_METADATA) - - if isinstance(it.peek(), TableElement): - it.next() - - while it.peek(): - if not isinstance(it.peek(), TableHeaderElement): - raise InvalidTOMLFileError - it.next() - if not isinstance(it.peek(), TableElement): - raise InvalidTOMLFileError - it.next() diff --git a/pipenv/patched/prettytoml/parser/errors.py b/pipenv/patched/prettytoml/parser/errors.py deleted file mode 100644 index eca12f3259..0000000000 --- a/pipenv/patched/prettytoml/parser/errors.py +++ /dev/null @@ -1,17 +0,0 @@ -from prettytoml.errors import TOMLError - - -class ParsingError(TOMLError): - - def __init__(self, message='', token=None): - self.message = message - self.token = token - - def __repr__(self): - if self.message and self.token: - return "{} at row {} and col {}".format(self.message, self.token.row, self.token.col) - else: - return self.message - - def __str__(self): - return repr(self) diff --git a/pipenv/patched/prettytoml/parser/parser.py b/pipenv/patched/prettytoml/parser/parser.py deleted file mode 100644 index e61c0db5a4..0000000000 --- a/pipenv/patched/prettytoml/parser/parser.py +++ /dev/null @@ -1,376 +0,0 @@ - -""" - A Recursive Descent implementation of a lexical parser for TOML. - - Grammar: - -------- - - Newline -> NEWLINE - Comment -> COMMENT Newline - LineTerminator -> Comment | Newline - Space -> WHITESPACE Space | WHITESPACE | EMPTY - TableHeader -> Space [ Space TableHeaderName Space ] Space LineTerminator | - Space [[ Space TableHeaderName Space ]] Space LineTerminator - TableHeaderName -> STRING Space '.' Space TableHeaderName | STRING - Atomic -> STRING | INTEGER | FLOAT | DATE | BOOLEAN - - Array -> '[' Space ArrayInternal Space ']' | '[' Space ArrayInternal Space LineTerminator Space ']' - ArrayInternal -> LineTerminator Space ArrayInternal | Value Space ',' Space LineTerminator Space ArrayInternal | - Value Space ',' Space ArrayInternal | LineTerminator | Value | EMPTY - - InlineTable -> '{' Space InlineTableInternal Space '}' - InlineTableKeyValuePair = STRING Space '=' Space Value - InlineTableInternal -> InlineTableKeyValuePair Space ',' Space InlineTableInternal | - InlineTableKeyValuePair | Empty - - Value -> Atomic | InlineTable | Array - KeyValuePair -> Space STRING Space '=' Space Value Space LineTerminator - - TableBody -> KeyValuePair TableBody | EmptyLine TableBody | EmptyLine | KeyValuePair - - EmptyLine -> Space LineTerminator - FileEntry -> TableHeader | TableBody - - TOMLFileElements -> FileEntry TOMLFileElements | FileEntry | EmptyLine | EMPTY -""" - -from prettytoml import tokens -from prettytoml.elements.array import ArrayElement -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.inlinetable import InlineTableElement -from prettytoml.elements.metadata import NewlineElement, CommentElement, WhitespaceElement, PunctuationElement -from prettytoml.elements.table import TableElement -from prettytoml.elements.tableheader import TableHeaderElement - -from prettytoml.parser.recdesc import capture_from -from prettytoml.parser.errors import ParsingError -from prettytoml.parser.tokenstream import TokenStream - -""" - Non-terminals are represented as functions which return (RESULT, pending_token_stream), or raise ParsingError. -""" - - -def token(token_type): - def factory(ts): - t = ts.head - if t.type != token_type: - raise ParsingError('Expected a token of type {}'.format(token_type)) - return t, ts.tail - return factory - - -def newline_element(token_stream): - """ - Returns NewlineElement, pending_token_stream or raises ParsingError. - """ - captured = capture_from(token_stream).find(token(tokens.TYPE_NEWLINE)) - return NewlineElement(captured.value()), captured.pending_tokens - - -def comment_tokens(ts1): - c1 = capture_from(ts1).find(token(tokens.TYPE_COMMENT)).and_find(token(tokens.TYPE_NEWLINE)) - return c1.value(), c1.pending_tokens - - -def comment_element(token_stream): - """ - Returns CommentElement, pending_token_stream or raises ParsingError. - """ - captured = capture_from(token_stream).find(comment_tokens) - return CommentElement(captured.value()), captured.pending_tokens - - -def line_terminator_tokens(token_stream): - captured = capture_from(token_stream).find(comment_tokens).or_find(token(tokens.TYPE_NEWLINE)) - return captured.value(), captured.pending_tokens - - -def line_terminator_element(token_stream): - captured = capture_from(token_stream).find(comment_element).or_find(newline_element) - return captured.value('Expected a comment or a newline')[0], captured.pending_tokens - - -def zero_or_more_tokens(token_type): - - def factory(token_stream): - def more(ts): - c = capture_from(ts).find(token(token_type)).and_find(zero_or_more_tokens(token_type)) - return c.value(), c.pending_tokens - - def two(ts): - c = capture_from(ts).find(token(tokens.TYPE_WHITESPACE)) - return c.value(), c.pending - - def zero(ts): - return tuple(), ts - - captured = capture_from(token_stream).find(more).or_find(two).or_find(zero) - return captured.value(), captured.pending_tokens - - return factory - - -def space_element(token_stream): - captured = capture_from(token_stream).find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)) - return WhitespaceElement([t for t in captured.value() if t]), captured.pending_tokens - - -def string_token(token_stream): - captured = capture_from(token_stream).\ - find(token(tokens.TYPE_BARE_STRING)).\ - or_find(token(tokens.TYPE_STRING)).\ - or_find(token(tokens.TYPE_LITERAL_STRING)).\ - or_find(token(tokens.TYPE_MULTILINE_STRING)).\ - or_find(token(tokens.TYPE_MULTILINE_LITERAL_STRING)) - return captured.value('Expected a string'), captured.pending_tokens - - -def string_element(token_stream): - captured = capture_from(token_stream).find(string_token) - return AtomicElement(captured.value()), captured.pending_tokens - - -def table_header_name_tokens(token_stream): - - def one(ts): - c = capture_from(ts).\ - find(string_token).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(token(tokens.TYPE_OPT_DOT)).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(table_header_name_tokens) - return c.value(), c.pending_tokens - - captured = capture_from(token_stream).find(one).or_find(string_token) - return captured.value(), captured.pending_tokens - - -def table_header_element(token_stream): - - def single(ts1): - c1 = capture_from(ts1).\ - find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(token(tokens.TYPE_OP_SQUARE_LEFT_BRACKET)).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(table_header_name_tokens).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(token(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET)).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(line_terminator_tokens) - - return c1.value(), c1.pending_tokens - - def double(ts2): - c2 = capture_from(ts2).\ - find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(token(tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET)).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(table_header_name_tokens).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(token(tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET)).\ - and_find(zero_or_more_tokens(tokens.TYPE_WHITESPACE)).\ - and_find(line_terminator_tokens) - - return c2.value(), c2.pending_tokens - - captured = capture_from(token_stream).find(single).or_find(double) - return TableHeaderElement(captured.value()), captured.pending_tokens - - -def atomic_element(token_stream): - captured = capture_from(token_stream).\ - find(string_token).\ - or_find(token(tokens.TYPE_INTEGER)).\ - or_find(token(tokens.TYPE_FLOAT)).\ - or_find(token(tokens.TYPE_DATE)).\ - or_find(token(tokens.TYPE_BOOLEAN)) - return AtomicElement(captured.value('Expected an atomic primitive value')), captured.pending_tokens - - -def punctuation_element(token_type): - def factory(ts): - c = capture_from(ts).find(token(token_type)) - return PunctuationElement(c.value('Expected the punctuation element: {}'.format(token_type))), c.pending_tokens - return factory - - -def value(token_stream): - captured = capture_from(token_stream).\ - find(atomic_element).\ - or_find(array_element).\ - or_find(inline_table_element) - return captured.value('Expected a primitive value, array or an inline table'), captured.pending_tokens - - -def array_internal(ts): - - def zero(ts0): - c = capture_from(ts0).\ - and_find(line_terminator_element).\ - and_find(space_element).\ - and_find(array_internal) - return c.value(), c.pending_tokens - - def one(ts1): - c = capture_from(ts1).\ - find(value).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_COMMA)).\ - and_find(space_element).\ - and_find(line_terminator_element).\ - and_find(space_element).\ - and_find(array_internal) - return c.value(), c.pending_tokens - - def two(ts2): - c = capture_from(ts2).\ - find(value).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_COMMA)).\ - and_find(space_element).\ - and_find(array_internal) - return c.value(), c.pending_tokens - - def three(ts3): - c = capture_from(ts3).\ - find(space_element).\ - and_find(line_terminator_element) - return c.value(), c.pending_tokens - - captured = capture_from(ts).find(zero).or_find(one).or_find(two).or_find(three).or_find(value).or_empty() - return captured.value(), captured.pending_tokens - - -def array_element(token_stream): - - def one(ts1): - ca = capture_from(ts1).\ - find(punctuation_element(tokens.TYPE_OP_SQUARE_LEFT_BRACKET)).\ - and_find(space_element).\ - and_find(array_internal).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET)) - return ca.value(), ca.pending_tokens - - def two(ts2): - ca = capture_from(ts2).\ - find(punctuation_element(tokens.TYPE_OP_SQUARE_LEFT_BRACKET)).\ - and_find(space_element).\ - and_find(array_internal).\ - and_find(space_element).\ - and_find(line_terminator_element).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET)) - return ca.value(), ca.pending_tokens - - captured = capture_from(token_stream).find(one).or_find(two) - return ArrayElement(captured.value()), captured.pending_tokens - - -def inline_table_element(token_stream): - - # InlineTableElement -> '{' Space InlineTableInternal Space '}' - # InlineTableKeyValuePair = STRING Space '=' Space Value - # InlineTableInternal -> InlineTableKeyValuePair Space ',' Space InlineTableInternal | - # InlineTableKeyValuePair | Empty - - def key_value(ts): - ca = capture_from(ts).\ - find(string_element).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_ASSIGNMENT)).\ - and_find(space_element).\ - and_find(value) - return ca.value(), ca.pending_tokens - - def internal(ts): - def one(ts1): - c1 = capture_from(ts1).\ - find(key_value).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_COMMA)).\ - and_find(space_element).\ - and_find(internal) - return c1.value(), c1.pending_tokens - - c = capture_from(ts).find(one).or_find(key_value).or_empty() - return c.value(), c.pending_tokens - - captured = capture_from(token_stream).\ - find(punctuation_element(tokens.TYPE_OP_CURLY_LEFT_BRACKET)).\ - and_find(space_element).\ - and_find(internal).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_CURLY_RIGHT_BRACKET)) - - return InlineTableElement(captured.value()), captured.pending_tokens - - -def key_value_pair(token_stream): - captured = capture_from(token_stream).\ - find(space_element).\ - and_find(string_element).\ - and_find(space_element).\ - and_find(punctuation_element(tokens.TYPE_OP_ASSIGNMENT)).\ - and_find(space_element).\ - and_find(value).\ - and_find(space_element).\ - and_find(line_terminator_element) - return captured.value(), captured.pending_tokens - - -def table_body_elements(token_stream): - - # TableBody -> KeyValuePair TableBody | EmptyLine TableBody | EmptyLine | KeyValuePair - - def one(ts1): - c = capture_from(ts1).\ - find(key_value_pair).\ - and_find(table_body_elements) - return c.value(), c.pending_tokens - - def two(ts2): - c = capture_from(ts2).\ - find(empty_line_elements).\ - and_find(table_body_elements) - return c.value(), c.pending_tokens - - captured = capture_from(token_stream).\ - find(one).\ - or_find(two).\ - or_find(empty_line_elements).\ - or_find(key_value_pair) - - return captured.value(), captured.pending_tokens - - -def table_body_element(token_stream): - captured = capture_from(token_stream).find(table_body_elements) - return TableElement(captured.value()), captured.pending_tokens - - -def empty_line_tokens(ts1): - c1 = capture_from(ts1).find(space_element).and_find(line_terminator_element) - return c1.value(), c1.pending_tokens - - -def empty_line_elements(token_stream): - captured = capture_from(token_stream).find(empty_line_tokens) - return captured.value(), captured.pending_tokens - - -def file_entry_element(token_stream): - captured = capture_from(token_stream).find(table_header_element).\ - or_find(table_body_element) - return captured.value(), captured.pending_tokens - - -def toml_file_elements(token_stream): - - def one(ts1): - c1 = capture_from(ts1).find(file_entry_element).and_find(toml_file_elements) - return c1.value(), c1.pending_tokens - - captured = capture_from(token_stream).find(one).or_find(file_entry_element).or_empty() - return captured.value(), captured.pending_tokens diff --git a/pipenv/patched/prettytoml/parser/recdesc.py b/pipenv/patched/prettytoml/parser/recdesc.py deleted file mode 100644 index 8731dba3ba..0000000000 --- a/pipenv/patched/prettytoml/parser/recdesc.py +++ /dev/null @@ -1,114 +0,0 @@ -from prettytoml.parser.errors import ParsingError -from prettytoml.parser.tokenstream import TokenStream - - -class Capturer: - """ - Recursive-descent matching DSL. Yeah.. - """ - - def __init__(self, token_stream, value=tuple(), dormant_error=None): - self._token_stream = token_stream - self._value = value - self._dormant_error = dormant_error - - def find(self, finder): - """ - Searches the token stream using the given finder. - - `finder(ts)` is a function that accepts a `TokenStream` instance and returns `(element, pending_ts)` - where `element` is the found "something" or a sequence of "somethings", and `pending_ts` the unconsumed - `TokenStream`. - - `finder(ts)` can raise `ParsingError` to indicate that it couldn't find anything, or - a `TokenStream.EndOfStream` to indicate a premature end of the TokenStream. - - This method returns a Capturer instance that can be further used to find more and more "somethings". The value - at any given moment can be retrieved via the `Capturer.value()` method. - """ - - try: - - # Execute finder! - element, pending_ts = finder(self._token_stream) - - # If result is not a sequence, make it so - if not isinstance(element, (tuple, list)): - element = (element,) - - # Return a Capturer with accumulated findings - return Capturer(pending_ts, value=self.value() + element) - - except ParsingError as e: - - # Failed to find, store error in returned value - return Capturer(self._token_stream, dormant_error=e) - - except TokenStream.EndOfStream as e: - - # Premature end of stream, store error in returned value - return Capturer(self._token_stream, dormant_error=e) - - def value(self, parsing_expectation_msg=None): - """ - Returns the accumulated values found as a sequence of values, or raises an encountered dormant error. - - If parsing_expectation_msg is specified and a dormant_error is a ParsingError, the expectation message is used - instead in it. - """ - - if self._dormant_error: - if parsing_expectation_msg and isinstance(self._dormant_error, ParsingError): - raise ParsingError(parsing_expectation_msg, token=self._token_stream.head) - else: - raise self._dormant_error - return self._value - - @property - def pending_tokens(self): - """ - Returns a TokenStream with the pending tokens yet to be processed. - """ - return self._token_stream - - def or_find(self, finder): - """ - If a dormant_error is present, try this new finder instead. If not, does nothing. - """ - if self._dormant_error: - return Capturer(self._token_stream).find(finder) - else: - return self - - def or_end_of_file(self): - """ - Discards any errors if at end of the stream. - """ - if isinstance(self._dormant_error, TokenStream.EndOfStream): - return Capturer(self.pending_tokens, value=self._value) - else: - return self - - def or_empty(self): - """ - Discards any previously-encountered dormant error. - """ - if self._dormant_error: - return Capturer(self.pending_tokens, value=self._value) - else: - return self - - def and_find(self, finder): - """ - Accumulate new "somethings" to the stored value using the given finder. - """ - - if self._dormant_error: - return Capturer(self.pending_tokens, dormant_error=self._dormant_error) - - return Capturer(self.pending_tokens, self.value()).find(finder) - - -def capture_from(token_stream): - return Capturer(token_stream) - diff --git a/pipenv/patched/prettytoml/parser/test_parser.py b/pipenv/patched/prettytoml/parser/test_parser.py deleted file mode 100644 index 40dd3dba77..0000000000 --- a/pipenv/patched/prettytoml/parser/test_parser.py +++ /dev/null @@ -1,156 +0,0 @@ -from prettytoml.elements.array import ArrayElement -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import CommentElement, NewlineElement, WhitespaceElement -from prettytoml.elements.tableheader import TableHeaderElement -from prettytoml.lexer import tokenize -from prettytoml.parser import parser -from prettytoml.parser.tokenstream import TokenStream - - -def test_line_terminator_1(): - tokens = tokenize('# Sup\n') - ts = TokenStream(tokens) - element, pending_ts = parser.line_terminator_element(ts) - - assert isinstance(element, CommentElement) - assert pending_ts.offset == 2 - assert ts.offset == 0 - - -def test_line_terminator_2(): - tokens = tokenize('\n') - ts = TokenStream(tokens) - element, pending_ts = parser.line_terminator_element(ts) - - assert isinstance(element, NewlineElement) - assert pending_ts.offset == 1 - assert ts.offset == 0 - - -def test_space_1(): - ts = TokenStream(tokenize(' noo')) - space_element, pending_ts = parser.space_element(ts) - - assert isinstance(space_element, WhitespaceElement) - assert len(space_element.tokens) == 2 - assert pending_ts.offset == 2 - assert ts.offset == 0 - - -def test_space_2(): - ts = TokenStream(tokenize(' noo')) - space_element, pending_ts = parser.space_element(ts) - - assert isinstance(space_element, WhitespaceElement) - assert len(space_element.tokens) == 1 - assert pending_ts.offset == 1 - assert ts.offset == 0 - - -def test_space_3(): - ts = TokenStream(tokenize('noo')) - space_element, pending_ts = parser.space_element(ts) - - assert isinstance(space_element, WhitespaceElement) - assert len(space_element.tokens) == 0 - assert pending_ts.offset == 0 - assert ts.offset == 0 - - -def test_table_header(): - ts = TokenStream(tokenize(" [ namez . namey . namex ] \n other things")) - table_header_element, pending_tokens = parser.table_header_element(ts) - - assert isinstance(table_header_element, TableHeaderElement) - assert len(pending_tokens) == 4 - - -def test_atomic_element(): - e1, p1 = parser.atomic_element(TokenStream(tokenize('42 not'))) - assert isinstance(e1, AtomicElement) and e1.value == 42 - assert len(p1) == 2 - - e2, p2 = parser.atomic_element(TokenStream(tokenize('not 42'))) - assert isinstance(e2, AtomicElement) and e2.value == 'not' - assert len(p2) == 2 - - -def test_array(): - array_element, pending_ts = parser.array_element(TokenStream(tokenize('[ 3, 4, 5,6,7] '))) - - assert isinstance(array_element, ArrayElement) - assert len(array_element) == 5 - assert len(pending_ts) == 1 - - -def test_array_2(): - - text = """[ - "alpha", - "omega" -]""" - - array_element, pending_ts = parser.array_element(TokenStream(tokenize(text))) - - assert array_element[0] == 'alpha' - assert array_element[1] == 'omega' - - -def test_empty_array(): - - text = '[]' - - array_element, pending_ts = parser.array_element(TokenStream(tokenize(text))) - - assert isinstance(array_element, ArrayElement) - assert pending_ts.at_end - - -def test_inline_table(): - inline_table, pending_ts = parser.inline_table_element(TokenStream(tokenize('{ "id"= 42,test = name} vroom'))) - - assert set(inline_table.keys()) == {'id', 'test'} - assert len(pending_ts) == 2 - assert inline_table['id'] == 42 - assert inline_table['test'] == 'name' - - -def test_table_body(): - table_body, pending_ts = parser.table_body_element(TokenStream(tokenize(' name= "test" # No way man!\nid =42\n vvv'))) - assert set(table_body.keys()) == {'name', 'id'} - assert len(pending_ts) == 2 - assert table_body['name'] == 'test' - assert table_body['id'] == 42 - - -def test_key_value_pair(): - text = """hosts = [ - "alpha", - "omega" -] -""" - - parsed, pending_ts = parser.key_value_pair(TokenStream(tokenize(text))) - - assert isinstance(parsed[1], AtomicElement) - assert isinstance(parsed[5], ArrayElement) - - -def test_table_body_2(): - - text = """ -data = [ ["gamma", "delta"], [1, 2] ] - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] - -str_multiline = wohoo -""" - - table_body, pending_ts = parser.table_body_element(TokenStream(tokenize(text))) - - assert len(pending_ts) == 0 - diff --git a/pipenv/patched/prettytoml/parser/tokenstream.py b/pipenv/patched/prettytoml/parser/tokenstream.py deleted file mode 100644 index 2a2fdc25f7..0000000000 --- a/pipenv/patched/prettytoml/parser/tokenstream.py +++ /dev/null @@ -1,39 +0,0 @@ - -class TokenStream: - """ - An immutable subset of a token sequence - """ - - class EndOfStream(Exception): - pass - - Nothing = tuple() - - def __init__(self, _tokens, offset=0): - if isinstance(_tokens, tuple): - self._tokens = _tokens - else: - self._tokens = tuple(_tokens) - self._head_index = offset - - def __len__(self): - return len(self._tokens) - self.offset - - @property - def head(self): - try: - return self._tokens[self._head_index] - except IndexError: - raise TokenStream.EndOfStream - - @property - def tail(self): - return TokenStream(self._tokens, offset=self._head_index+1) - - @property - def offset(self): - return self._head_index - - @property - def at_end(self): - return self.offset >= len(self._tokens) diff --git a/pipenv/patched/prettytoml/prettifier/__init__.py b/pipenv/patched/prettytoml/prettifier/__init__.py deleted file mode 100644 index 97ac161930..0000000000 --- a/pipenv/patched/prettytoml/prettifier/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -from . import deindentanonymoustable, tableindent, tableassignment -from prettytoml.prettifier import tablesep, commentspace, linelength, tableentrysort - -""" - TOMLFile prettifiers - - Each prettifier is a function that accepts a sequence of Element instances that make up a - TOML file and it is allowed to modify it as it pleases. -""" - - -UNIFORM_TABLE_INDENTATION = tableindent.table_entries_should_be_uniformly_indented -UNIFORM_TABLE_ASSIGNMENT_SPACING = tableassignment.table_assignment_spacing -ANONYMOUS_TABLE_INDENTATION = deindentanonymoustable.deindent_anonymous_table -COMMENT_SPACING = commentspace.comment_space -TABLE_SPACING = tablesep.table_separation -LINE_LENGTH_ENFORCERS = linelength.line_length_limiter -TABLE_ENTRY_SORTING = tableentrysort.sort_table_entries - - -ALL = ( - TABLE_SPACING, # Must be before COMMENT_SPACING - COMMENT_SPACING, # Must be after TABLE_SPACING - UNIFORM_TABLE_INDENTATION, - UNIFORM_TABLE_ASSIGNMENT_SPACING, - ANONYMOUS_TABLE_INDENTATION, - LINE_LENGTH_ENFORCERS, - TABLE_ENTRY_SORTING, -) - - -def prettify(toml_file_elements, prettifiers=ALL): - """ - Prettifies a sequence of element instances according to pre-defined set of formatting rules. - """ - elements = toml_file_elements[:] - for prettifier in prettifiers: - elements = prettifier(elements) - return elements diff --git a/pipenv/patched/prettytoml/prettifier/commentspace.py b/pipenv/patched/prettytoml/prettifier/commentspace.py deleted file mode 100644 index fd54934917..0000000000 --- a/pipenv/patched/prettytoml/prettifier/commentspace.py +++ /dev/null @@ -1,35 +0,0 @@ - -from prettytoml.elements import traversal as t, factory as element_factory -from prettytoml.elements.table import TableElement - - -def comment_space(toml_file_elements): - """ - Rule: Line-terminating comments should always be prefixed by a single tab character whitespace only. - """ - elements = toml_file_elements[:] - for element in elements: - if isinstance(element, TableElement): - _do_table(element.sub_elements) - return elements - - -def _do_table(table_elements): - - # Iterator index - i = float('-inf') - - def next_newline(): - return t.find_following(table_elements, t.predicates.newline, i) - - def next_comment(): - return t.find_following(table_elements, t.predicates.comment, i) - - def last_non_metadata(): - return t.find_previous(table_elements, t.predicates.non_metadata, next_comment()) - - while next_comment() >= 0: - if i < last_non_metadata() < next_comment() < next_newline(): - del table_elements[last_non_metadata()+1:next_comment()] - table_elements.insert(next_comment(), element_factory.create_whitespace_element(char='\t', length=1)) - i = next_newline() diff --git a/pipenv/patched/prettytoml/prettifier/common.py b/pipenv/patched/prettytoml/prettifier/common.py deleted file mode 100644 index dd1e01a216..0000000000 --- a/pipenv/patched/prettytoml/prettifier/common.py +++ /dev/null @@ -1,54 +0,0 @@ - -from itertools import * -from prettytoml.elements.common import TokenElement -from prettytoml.elements.metadata import NewlineElement - - -def text_to_elements(toml_text): - from ..lexer import tokenize - from ..parser import parse_tokens - return parse_tokens(tokenize(toml_text)) - - -def elements_to_text(toml_elements): - return ''.join(e.serialized() for e in toml_elements) - - -def assert_prettifier_works(source_text, expected_text, prettifier_func): - assert expected_text == elements_to_text(prettifier_func(text_to_elements(source_text))) - - -def lines(elements): - """ - Splits a sequence of elements into a sub-sequence of each line. - - A line is defined as a sequence of elements terminated by a NewlineElement. - """ - - def __next_line(es): - # Returns the next line and the remaining sequence of elements - line = tuple(takewhile(lambda e: not isinstance(e, NewlineElement), es)) - line += (es[len(line)],) - return line, es[len(line):] - - left_elements = tuple(elements) - while left_elements: - line, left_elements = __next_line(left_elements) - yield line - - -def non_empty_elements(elements): - """ - Filters out TokenElement instances with zero tokens. - """ - return filter(lambda e: not (isinstance(e, TokenElement) and not e.tokens), elements) - - -def index(predicate, seq): - """ - Returns the index of the element satisfying the given predicate, or None. - """ - try: - return next(i for (i, e) in enumerate(seq) if predicate(e)) - except StopIteration: - return None diff --git a/pipenv/patched/prettytoml/prettifier/deindentanonymoustable.py b/pipenv/patched/prettytoml/prettifier/deindentanonymoustable.py deleted file mode 100644 index a661f70452..0000000000 --- a/pipenv/patched/prettytoml/prettifier/deindentanonymoustable.py +++ /dev/null @@ -1,43 +0,0 @@ -import operator -from prettytoml.elements import traversal as t, traversal -from itertools import * -from functools import * -from prettytoml.elements.metadata import WhitespaceElement -from prettytoml.elements.table import TableElement -from prettytoml.prettifier import common - - -def deindent_anonymous_table(toml_file_elements): - """ - Rule: Anonymous table should never be indented. - """ - - anonymous_table_index = _find_anonymous_table(toml_file_elements) - if anonymous_table_index is None: - return toml_file_elements - - return toml_file_elements[:anonymous_table_index] + \ - [_unindent_table(toml_file_elements[anonymous_table_index])] + \ - toml_file_elements[anonymous_table_index+1:] - - -def _unindent_table(table_element): - table_lines = tuple(common.lines(table_element.sub_elements)) - unindented_lines = tuple(tuple(dropwhile(lambda e: isinstance(e, WhitespaceElement), line)) for line in table_lines) - return TableElement(reduce(operator.concat, unindented_lines)) - - -def _find_anonymous_table(toml_file_elements): - """ - Finds and returns the index of the TableElement comprising the anonymous table or None. - """ - - first_table_index = common.index(t.predicates.table, toml_file_elements) - first_table_header_index = common.index(t.predicates.table_header, toml_file_elements) - - if first_table_header_index is None: - return first_table_index - elif first_table_index < first_table_header_index: - return first_table_index - - diff --git a/pipenv/patched/prettytoml/prettifier/linelength.py b/pipenv/patched/prettytoml/prettifier/linelength.py deleted file mode 100644 index 67d3a1127d..0000000000 --- a/pipenv/patched/prettytoml/prettifier/linelength.py +++ /dev/null @@ -1,62 +0,0 @@ -import operator -from prettytoml import tokens -from prettytoml.prettifier import common -from prettytoml.elements import traversal as t, factory as element_factory -from prettytoml.elements.array import ArrayElement -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.inlinetable import InlineTableElement -from prettytoml.elements.table import TableElement -from functools import * - - -MAXIMUM_LINE_LENGTH = 120 - - -def line_length_limiter(toml_file_elements): - """ - Rule: Lines whose lengths exceed 120 characters whose values are strings, arrays should have the array or - string value broken onto multiple lines - """ - return tuple(_fixed_table(e) if isinstance(e, TableElement) else e for e in toml_file_elements) - - -def _fixed_table(table_element): - """ - Returns a new TableElement. - """ - assert isinstance(table_element, TableElement) - lines = tuple(common.lines(table_element.sub_elements)) - fixed_lines = tuple(_fixed_line(l) if _line_length(l) > MAXIMUM_LINE_LENGTH else l for l in lines) - return TableElement(sub_elements=tuple(reduce(operator.concat, fixed_lines))) - - -def _line_length(line_elements): - """ - Returns the character length of the serialized elements of the given line. - """ - return sum(len(e.serialized()) for e in line_elements) - - -def _fixed_line(line_elements): - - def line_value_index(): - # Returns index of value element in the line - key_index = t.find_following(line_elements, t.predicates.non_metadata) - return t.find_following(line_elements, t.predicates.non_metadata, key_index) - - def multiline_equivalent(element): - if isinstance(element, AtomicElement) and tokens.is_string(element.first_token): - return element_factory.create_multiline_string(element.value, MAXIMUM_LINE_LENGTH) - elif isinstance(element, ArrayElement): - element.turn_into_multiline() - return element - else: - return element - - line_elements = tuple(line_elements) - value_index = line_value_index() - if value_index >= 0: - return line_elements[:value_index] + (multiline_equivalent(line_elements[value_index]),) + \ - line_elements[value_index+1:] - else: - return line_elements diff --git a/pipenv/patched/prettytoml/prettifier/tableassignment.py b/pipenv/patched/prettytoml/prettifier/tableassignment.py deleted file mode 100644 index 1d35d698b8..0000000000 --- a/pipenv/patched/prettytoml/prettifier/tableassignment.py +++ /dev/null @@ -1,40 +0,0 @@ - -from prettytoml.elements import traversal as t, factory as element_factory - - -def table_assignment_spacing(toml_file_elements): - """ - Rule: Every key and value pair in any table should be separated the triplet - (single space character, an assignment character =, single space character) - """ - elements = toml_file_elements[:] - for table_element in (e for e in elements if t.predicates.table(e)): - _do_table(table_element) - return elements - - -def _do_table(table_element): - - elements = table_element.sub_elements - - # Our iterator index - i = float('-inf') - - def next_key(): - return t.find_following(elements, t.predicates.non_metadata, i) - - def next_assignment(): - return t.find_following(elements, t.predicates.op_assignment, next_key()) - - def next_value(): - return t.find_following(elements, t.predicates.non_metadata, next_assignment()) - - while next_key() >= 0: - - del elements[next_key()+1:next_assignment()] - del elements[next_assignment()+1:next_value()] - - elements.insert(next_assignment(), element_factory.create_whitespace_element(1)) - elements.insert(next_value(), element_factory.create_whitespace_element(1)) - - i = t.find_following(elements, t.predicates.newline, i) diff --git a/pipenv/patched/prettytoml/prettifier/tableentrysort.py b/pipenv/patched/prettytoml/prettifier/tableentrysort.py deleted file mode 100644 index 8cbd307b49..0000000000 --- a/pipenv/patched/prettytoml/prettifier/tableentrysort.py +++ /dev/null @@ -1,38 +0,0 @@ -import operator -from prettytoml import tokens -from prettytoml.elements.common import TokenElement -from prettytoml.elements.table import TableElement -from prettytoml.prettifier import common -from functools import * - - -def sort_table_entries(toml_file_elements): - """ - Rule: Entries within a single table should be ordered lexicographically by key - """ - return [_sorted_table(element) if isinstance(element, TableElement) else element for element in toml_file_elements] - - -def _line_key(line_elements): - """ - Given a sequence of elements comprising a single line, returns an orderable value to use in ordering lines. - """ - for e in line_elements: - if isinstance(e, TokenElement) and tokens.is_string(e.first_token): - return e.primitive_value - return 'z' * 10 # Metadata lines should be at the end - - -def _sorted_table(table): - """ - Returns another TableElement where the table entries are sorted lexicographically by key. - """ - assert isinstance(table, TableElement) - - # Discarding TokenElements with no tokens in them - table_elements = common.non_empty_elements(table.sub_elements) - lines = tuple(common.lines(table_elements)) - sorted_lines = sorted(lines, key=_line_key) - sorted_elements = reduce(operator.concat, sorted_lines) - - return TableElement(sorted_elements) diff --git a/pipenv/patched/prettytoml/prettifier/tableindent.py b/pipenv/patched/prettytoml/prettifier/tableindent.py deleted file mode 100644 index 3b60883d56..0000000000 --- a/pipenv/patched/prettytoml/prettifier/tableindent.py +++ /dev/null @@ -1,49 +0,0 @@ -from prettytoml import tokens -from prettytoml.elements import traversal as t, factory as element_factory -from prettytoml.tokens import py2toml - - -def table_entries_should_be_uniformly_indented(toml_file_elements): - """ - Rule: Nth-level table sections should be indented by (N-1)*2 spaces - """ - elements = toml_file_elements[:] - for (i, e) in enumerate(elements): - if t.predicates.table_header(e): - table = elements[t.find_following(elements, t.predicates.table, i)] - _do_table_header(e) - _do_table(table, len(e.names)) - return elements - - -def _do_table_header(table_header): - indent_start = 0 - indent_end = next(i for (i, token) in enumerate(table_header.tokens) if token.type != tokens.TYPE_WHITESPACE) - - del table_header.tokens[indent_start:indent_end] - table_header.tokens.insert(0, py2toml.create_whitespace(' ' * ((len(table_header.names)-1) * 2))) - - -def _do_table(table_element, table_level): - - elements = table_element.sub_elements - - # Iterator index - i = float('-inf') - - def first_indent(): - return t.find_following(elements, t.predicates.whitespace, i) - - def next_non_metadata(): - return t.find_following(elements, t.predicates.non_metadata, i) - - def next_newline(): - return t.find_following(elements, t.predicates.newline, next_non_metadata()) - - while next_non_metadata() >= 0: - if first_indent() >= 0: - del elements[first_indent():next_non_metadata()] - - elements.insert(next_non_metadata(), element_factory.create_whitespace_element((table_level-1)*2)) - - i = next_newline() diff --git a/pipenv/patched/prettytoml/prettifier/tablesep.py b/pipenv/patched/prettytoml/prettifier/tablesep.py deleted file mode 100644 index 059007f328..0000000000 --- a/pipenv/patched/prettytoml/prettifier/tablesep.py +++ /dev/null @@ -1,31 +0,0 @@ - -from prettytoml.elements import traversal as t, factory as element_factory -from prettytoml.elements.metadata import WhitespaceElement, NewlineElement -from prettytoml.elements.table import TableElement - - -def table_separation(toml_file_elements): - """ - Rule: Tables should always be separated by an empty line. - """ - elements = toml_file_elements[:] - for element in elements: - if isinstance(element, TableElement): - _do_table(element.sub_elements) - return elements - - -def _do_table(table_elements): - - while table_elements and isinstance(table_elements[-1], WhitespaceElement): - del table_elements[-1] - - if not table_elements: - return - - if isinstance(table_elements[-1], NewlineElement): - last_non_metadata_i = t.find_previous(table_elements, t.predicates.non_metadata) - del table_elements[last_non_metadata_i+1:] - - table_elements.append(element_factory.create_newline_element()) - table_elements.append(element_factory.create_newline_element()) diff --git a/pipenv/patched/prettytoml/prettifier/test_commentspace.py b/pipenv/patched/prettytoml/prettifier/test_commentspace.py deleted file mode 100644 index 53d96d76b1..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_commentspace.py +++ /dev/null @@ -1,28 +0,0 @@ - -from .common import assert_prettifier_works -from .commentspace import comment_space - - -def test_comment_space(): - - toml_text = """ -my_key = string -id = 12 # My special ID - -[section.name] -headerk = false -# Own-line comment should stay the same -other_key = "value" -""" - - expected_toml_text = """ -my_key = string -id = 12\t# My special ID - -[section.name] -headerk = false -# Own-line comment should stay the same -other_key = "value" -""" - - assert_prettifier_works(toml_text, expected_toml_text, comment_space) diff --git a/pipenv/patched/prettytoml/prettifier/test_deindentanonymoustable.py b/pipenv/patched/prettytoml/prettifier/test_deindentanonymoustable.py deleted file mode 100644 index 10a6d2c800..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_deindentanonymoustable.py +++ /dev/null @@ -1,22 +0,0 @@ - -""" - This testing module depends on all the other modules. -""" - -from .deindentanonymoustable import deindent_anonymous_table -from .common import assert_prettifier_works - - -def test_anon_table_indent(): - toml_text = """ - key=value - another_key =44 -noname = me -""" - - expected_toml_text = """ -key=value -another_key =44 -noname = me -""" - assert_prettifier_works(toml_text, expected_toml_text, deindent_anonymous_table) diff --git a/pipenv/patched/prettytoml/prettifier/test_linelength.py b/pipenv/patched/prettytoml/prettifier/test_linelength.py deleted file mode 100644 index e4ab8fcbaf..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_linelength.py +++ /dev/null @@ -1,39 +0,0 @@ -from .linelength import line_length_limiter -from .common import assert_prettifier_works, elements_to_text, text_to_elements -import pytoml - - -def test_splitting_string(): - toml_text = """ -k = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et lectus nec erat condimentum scelerisque gravida sed ipsum. Mauris non orci tincidunt, viverra enim eget, tincidunt orci. Sed placerat nibh vitae ante maximus egestas maximus eu quam. Praesent vehicula mauris vestibulum, mattis turpis sollicitudin, aliquam felis. Pellentesque volutpat pharetra purus vel finibus. Vestibulum sed tempus dui. Maecenas auctor sit amet diam et porta. Morbi id libero at elit ultricies porta vel vitae nullam. " -""" - - expected_toml_text = """ -k = \"\"\" -Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et lectus nec erat condimentum scelerisque gravida sed \\ -ipsum. Mauris non orci tincidunt, viverra enim eget, tincidunt orci. Sed placerat nibh vitae ante maximus egestas \\ -maximus eu quam. Praesent vehicula mauris vestibulum, mattis turpis sollicitudin, aliquam felis. Pellentesque volutpat \\ -pharetra purus vel finibus. Vestibulum sed tempus dui. Maecenas auctor sit amet diam et porta. Morbi id libero at elit \\ -ultricies porta vel vitae nullam. \"\"\" -""" - assert_prettifier_works(toml_text, expected_toml_text, line_length_limiter) - - -def test_splitting_array(): - toml_text = """ - -somethingweird = false - -[section] -k = [4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 42] - - -[data] -id = 12 - -""" - - prettified = elements_to_text(line_length_limiter(text_to_elements(toml_text))) - - assert pytoml.loads(prettified) == pytoml.loads(toml_text) - assert all(len(line) < 120 for line in prettified.split('\n')) diff --git a/pipenv/patched/prettytoml/prettifier/test_tableassignment.py b/pipenv/patched/prettytoml/prettifier/test_tableassignment.py deleted file mode 100644 index 82fcc174d5..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_tableassignment.py +++ /dev/null @@ -1,29 +0,0 @@ - -from .tableassignment import table_assignment_spacing -from .common import assert_prettifier_works - - -def test_table_assignment_spacing(): - toml_text = """ - key1= "my value" - key2 =42 - keys = [4, 5,1] - - [section] - key1= "my value" - key2 =42 - keys = [4, 5,1] -""" - - expected_prettified = """ - key1 = "my value" - key2 = 42 - keys = [4, 5,1] - - [section] - key1 = "my value" - key2 = 42 - keys = [4, 5,1] -""" - - assert_prettifier_works(toml_text, expected_prettified, table_assignment_spacing) diff --git a/pipenv/patched/prettytoml/prettifier/test_tableentrysort.py b/pipenv/patched/prettytoml/prettifier/test_tableentrysort.py deleted file mode 100644 index 0cc39f7885..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_tableentrysort.py +++ /dev/null @@ -1,45 +0,0 @@ - -from .tableentrysort import sort_table_entries -from .common import assert_prettifier_works - - -def test_table_sorting(): - toml_text = """description = "" -firstname = "adnan" -lastname = "fatayerji" -git_aydo = "" -groups = ["sales", "dubai", "mgmt"] -skype = "" -emails = ["adnan@incubaid.com", - "fatayera@incubaid.com", - "adnan.fatayerji@incubaid.com", - "adnan@greenitglobe.com", - "fatayera@greenitglobe.com", - "adnan.fatayerji@greenitglobe.com"] -# I really like this table -id = "fatayera" -git_github = "" -telegram = "971507192009" -mobiles = ["971507192009"] -""" - - prettified = """description = "" -emails = ["adnan@incubaid.com", - "fatayera@incubaid.com", - "adnan.fatayerji@incubaid.com", - "adnan@greenitglobe.com", - "fatayera@greenitglobe.com", - "adnan.fatayerji@greenitglobe.com"] -firstname = "adnan" -git_aydo = "" -git_github = "" -groups = ["sales", "dubai", "mgmt"] -# I really like this table -id = "fatayera" -lastname = "fatayerji" -mobiles = ["971507192009"] -skype = "" -telegram = "971507192009" -""" - - assert_prettifier_works(toml_text, prettified, sort_table_entries) diff --git a/pipenv/patched/prettytoml/prettifier/test_tableindent.py b/pipenv/patched/prettytoml/prettifier/test_tableindent.py deleted file mode 100644 index a37f73a721..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_tableindent.py +++ /dev/null @@ -1,25 +0,0 @@ - -from .tableindent import table_entries_should_be_uniformly_indented -from .common import assert_prettifier_works - - -def test_table_entries_should_be_uniformly_indented(): - toml_text = """ - [firstlevel] -hello = "my name" - my_id = 12 - - [firstlevel.secondlevel] - my_truth = False -""" - - expected_toml_text = """ -[firstlevel] -hello = "my name" -my_id = 12 - - [firstlevel.secondlevel] - my_truth = False -""" - - assert_prettifier_works(toml_text, expected_toml_text, table_entries_should_be_uniformly_indented) diff --git a/pipenv/patched/prettytoml/prettifier/test_tablesep.py b/pipenv/patched/prettytoml/prettifier/test_tablesep.py deleted file mode 100644 index a8a81d52a4..0000000000 --- a/pipenv/patched/prettytoml/prettifier/test_tablesep.py +++ /dev/null @@ -1,34 +0,0 @@ - -from .tablesep import table_separation -from .common import assert_prettifier_works - - -def test_table_separation(): - - toml_text = """key1 = "value1" -key2 = 22 -[section] -k = false -m= "true" - - - -[another.section] -l = "t" -creativity = "on vacation" -""" - - expected_toml_text = """key1 = "value1" -key2 = 22 - -[section] -k = false -m= "true" - -[another.section] -l = "t" -creativity = "on vacation" - -""" - - assert_prettifier_works(toml_text, expected_toml_text, table_separation) diff --git a/pipenv/patched/prettytoml/test_prettifier.py b/pipenv/patched/prettytoml/test_prettifier.py deleted file mode 100644 index f702fb01b8..0000000000 --- a/pipenv/patched/prettytoml/test_prettifier.py +++ /dev/null @@ -1,12 +0,0 @@ - -from .prettifier import prettify -from .prettifier.common import assert_prettifier_works -import pytoml - - -def test_prettifying_against_humanly_verified_sample(): - toml_source = open('sample.toml').read() - expected = open('sample-prettified.toml').read() - - assert_prettifier_works(toml_source, expected, prettify) - assert pytoml.loads(toml_source) == pytoml.loads(expected) diff --git a/pipenv/patched/prettytoml/test_util.py b/pipenv/patched/prettytoml/test_util.py deleted file mode 100644 index b741abfa63..0000000000 --- a/pipenv/patched/prettytoml/test_util.py +++ /dev/null @@ -1,22 +0,0 @@ -from prettytoml.util import is_sequence_like, is_dict_like, chunkate_string - - -def test_is_sequence_like(): - assert is_sequence_like([1, 3, 4]) - assert not is_sequence_like(42) - - -def test_is_dict_like(): - assert is_dict_like({'name': False}) - assert not is_dict_like(42) - assert not is_dict_like([4, 8, 15]) - - -def test_chunkate_string(): - - text = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et lectus nec erat condimentum scelerisque gravida sed ipsum. Mauris non orci tincidunt, viverra enim eget, tincidunt orci. Sed placerat nibh vitae ante maximus egestas maximus eu quam. Praesent vehicula mauris vestibulum, mattis turpis sollicitudin, aliquam felis. Pellentesque volutpat pharetra purus vel finibus. Vestibulum sed tempus dui. Maecenas auctor sit amet diam et porta. Morbi id libero at elit ultricies porta vel vitae nullam. """ - - chunks = chunkate_string(text, 50) - - assert ''.join(chunks) == text - assert all(len(chunk) <= 50 for chunk in chunks) diff --git a/pipenv/patched/prettytoml/tokens/__init__.py b/pipenv/patched/prettytoml/tokens/__init__.py deleted file mode 100644 index a5b2e9aef0..0000000000 --- a/pipenv/patched/prettytoml/tokens/__init__.py +++ /dev/null @@ -1,136 +0,0 @@ - -""" -TOML lexical tokens. -""" - -class TokenType: - """ - A TokenType is a concrete type of a source token along with a defined priority and a higher-order kind. - - The priority will be used in determining the tokenization behaviour of the lexer in the following manner: - whenever more than one token is recognizable as the next possible token and they are all of equal source - length, this priority is going to be used to break the tie by favoring the token type of the lowest priority - value. A TokenType instance is naturally ordered by its priority. - """ - - def __init__(self, name, priority, is_metadata): - self._priority = priority - self._name = name - self._is_metadata = is_metadata - - @property - def is_metadata(self): - return self._is_metadata - - @property - def priority(self): - return self._priority - - def __repr__(self): - return "{}-{}".format(self.priority, self._name) - - def __lt__(self, other): - return isinstance(other, TokenType) and self._priority < other.priority - -# Possible types of tokens -TYPE_BOOLEAN = TokenType('boolean', 0, is_metadata=False) -TYPE_INTEGER = TokenType('integer', 0, is_metadata=False) -TYPE_OP_COMMA = TokenType('comma', 0, is_metadata=True) -TYPE_OP_SQUARE_LEFT_BRACKET = TokenType('square_left_bracket', 0, is_metadata=True) -TYPE_OP_SQUARE_RIGHT_BRACKET = TokenType('square_right_bracket', 0, is_metadata=True) -TYPE_OP_CURLY_LEFT_BRACKET = TokenType('curly_left_bracket', 0, is_metadata=True) -TYPE_OP_CURLY_RIGHT_BRACKET = TokenType('curly_right_bracket', 0, is_metadata=True) -TYPE_OP_ASSIGNMENT = TokenType('assignment', 0, is_metadata=True) -TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET = TokenType('double_square_left_bracket', 0, is_metadata=True) -TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET = TokenType('double_square_right_bracket', 0, is_metadata=True) -TYPE_FLOAT = TokenType('float', 1, is_metadata=False) -TYPE_DATE = TokenType('date', 40, is_metadata=False) -TYPE_OPT_DOT = TokenType('dot', 40, is_metadata=True) -TYPE_BARE_STRING = TokenType('bare_string', 50, is_metadata=False) -TYPE_STRING = TokenType('string', 90, is_metadata=False) -TYPE_MULTILINE_STRING = TokenType('multiline_string', 90, is_metadata=False) -TYPE_LITERAL_STRING = TokenType('literal_string', 90, is_metadata=False) -TYPE_MULTILINE_LITERAL_STRING = TokenType('multiline_literal_string', 90, is_metadata=False) -TYPE_NEWLINE = TokenType('newline', 91, is_metadata=True) -TYPE_WHITESPACE = TokenType('whitespace', 93, is_metadata=True) -TYPE_COMMENT = TokenType('comment', 95, is_metadata=True) - - -def is_operator(token): - """ - Returns True if the given token is an operator token. - """ - return token.type in ( - TYPE_OP_COMMA, - TYPE_OP_SQUARE_LEFT_BRACKET, - TYPE_OP_SQUARE_RIGHT_BRACKET, - TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, - TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, - TYPE_OP_CURLY_LEFT_BRACKET, - TYPE_OP_CURLY_RIGHT_BRACKET, - TYPE_OP_ASSIGNMENT, - TYPE_OPT_DOT, - ) - - -def is_string(token): - return token.type in ( - TYPE_STRING, - TYPE_MULTILINE_STRING, - TYPE_LITERAL_STRING, - TYPE_BARE_STRING, - TYPE_MULTILINE_LITERAL_STRING - ) - - -class Token: - """ - A token/lexeme in a TOML source file. - - A Token instance is naturally ordered by its type. - """ - - def __init__(self, _type, source_substring, col=None, row=None): - self._source_substring = source_substring - self._type = _type - self._col = col - self._row = row - - def __eq__(self, other): - if not isinstance(other, Token): - return False - return self.source_substring == other.source_substring and self.type == other.type - - @property - def col(self): - """ - Column number (1-indexed). - """ - return self._col - - @property - def row(self): - """ - Row number (1-indexed). - """ - return self._row - - @property - def type(self): - """ - One of of the TOKEN_TYPE_* constants. - """ - return self._type - - @property - def source_substring(self): - """ - The substring of the initial source file containing this token. - """ - return self._source_substring - - def __lt__(self, other): - return isinstance(other, Token) and self.type < other.type - - def __repr__(self): - return "{}: {}".format(self.type, self.source_substring) diff --git a/pipenv/patched/prettytoml/tokens/errors.py b/pipenv/patched/prettytoml/tokens/errors.py deleted file mode 100644 index d40cb8e997..0000000000 --- a/pipenv/patched/prettytoml/tokens/errors.py +++ /dev/null @@ -1,13 +0,0 @@ -from prettytoml.errors import TOMLError - - -class DeserializationError(TOMLError): - pass - - -class BadEscapeCharacter(TOMLError): - pass - - -class MalformedDateError(DeserializationError): - pass diff --git a/pipenv/patched/prettytoml/tokens/py2toml.py b/pipenv/patched/prettytoml/tokens/py2toml.py deleted file mode 100644 index 2decd02102..0000000000 --- a/pipenv/patched/prettytoml/tokens/py2toml.py +++ /dev/null @@ -1,154 +0,0 @@ - -""" -A converter of python values to TOML Token instances. -""" -from __future__ import unicode_literals -import codecs -import datetime -import six -from prettytoml import tokens -import re -from prettytoml.errors import TOMLError -from prettytoml.tokens import Token -from prettytoml.util import chunkate_string - - -class NotPrimitiveError(TOMLError): - pass - - -_operator_tokens_by_type = { - tokens.TYPE_OP_SQUARE_LEFT_BRACKET: tokens.Token(tokens.TYPE_OP_SQUARE_LEFT_BRACKET, u'['), - tokens.TYPE_OP_SQUARE_RIGHT_BRACKET: tokens.Token(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, u']'), - tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET: tokens.Token(tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, u'[['), - tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET: tokens.Token(tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, u']]'), - tokens.TYPE_OP_COMMA: tokens.Token(tokens.TYPE_OP_COMMA, u','), - tokens.TYPE_NEWLINE: tokens.Token(tokens.TYPE_NEWLINE, u'\n'), - tokens.TYPE_OPT_DOT: tokens.Token(tokens.TYPE_OPT_DOT, u'.'), -} - - -def operator_token(token_type): - return _operator_tokens_by_type[token_type] - - -def create_primitive_token(value, multiline_strings_allowed=True): - """ - Creates and returns a single token for the given primitive atomic value. - - Raises NotPrimitiveError when the given value is not a primitive atomic value - """ - if value is None: - return create_primitive_token('') - elif isinstance(value, bool): - return tokens.Token(tokens.TYPE_BOOLEAN, u'true' if value else u'false') - elif isinstance(value, int): - return tokens.Token(tokens.TYPE_INTEGER, u'{}'.format(value)) - elif isinstance(value, float): - return tokens.Token(tokens.TYPE_FLOAT, u'{}'.format(value)) - elif isinstance(value, (datetime.datetime, datetime.date, datetime.time)): - s = value.isoformat() - if s.endswith('+00:00'): - s = s[:-6] + 'Z' - return tokens.Token(tokens.TYPE_DATE, s) - elif isinstance(value, six.string_types): - return create_string_token(value, multiline_strings_allowed=multiline_strings_allowed) - - raise NotPrimitiveError("{} of type {}".format(value, type(value))) - - -_bare_string_regex = re.compile('^[a-zA-Z_-]*$') - - -def create_string_token(text, bare_string_allowed=False, multiline_strings_allowed=True): - """ - Creates and returns a single string token. - - Raises ValueError on non-string input. - """ - - if not isinstance(text, six.string_types): - raise ValueError('Given value must be a string') - - if text == '': - return tokens.Token(tokens.TYPE_STRING, '""'.format(_escape_single_line_quoted_string(text))) - elif bare_string_allowed and _bare_string_regex.match(text): - return tokens.Token(tokens.TYPE_BARE_STRING, text) - elif multiline_strings_allowed and (len(tuple(c for c in text if c == '\n')) >= 2 or len(text) > 80): - # If containing two or more newlines or is longer than 80 characters we'll use the multiline string format - return _create_multiline_string_token(text) - else: - return tokens.Token(tokens.TYPE_STRING, '"{}"'.format(_escape_single_line_quoted_string(text))) - - -def _escape_single_line_quoted_string(text): - text = text.decode('utf-8') if isinstance(text, six.binary_type) else text - start = 0 - i = 0 - res = [] - _escapes = {'\n': '\\n', '\r': '\\r', '\\': '\\\\', '\t': '\\t', - '\b': '\\b', '\f': '\\f', '"': '\\"'} - - def flush(): - if start < i: - res.append(text[start:i]) - return i + 1 - - while i < len(text): - c = text[i] - if c in _escapes: - start = flush() - res.append(_escapes[c]) - elif ord(c) < 0x20: - start = flush() - res.append('\\u%04x' % ord(c)) - i += 1 - - flush() - return ''.join(res) - - -def _create_multiline_string_token(text): - escaped = text.replace(u'"""', u'\"\"\"') - if len(escaped) > 50: - return tokens.Token(tokens.TYPE_MULTILINE_STRING, u'"""\n{}\\\n"""'.format(_break_long_text(escaped))) - else: - return tokens.Token(tokens.TYPE_MULTILINE_STRING, u'"""{}"""'.format(escaped)) - - -def _break_long_text(text, maximum_length=75): - """ - Breaks into lines of 75 character maximum length that are terminated by a backslash. - """ - - def next_line(remaining_text): - - # Returns a line and the remaining text - - if '\n' in remaining_text and remaining_text.index('\n') < maximum_length: - i = remaining_text.index('\n') - return remaining_text[:i+1], remaining_text[i+2:] - elif len(remaining_text) > maximum_length and ' ' in remaining_text: - i = remaining_text[:maximum_length].rfind(' ') - return remaining_text[:i+1] + '\\\n', remaining_text[i+2:] - else: - return remaining_text, '' - - remaining_text = text - lines = [] - while remaining_text: - line, remaining_text = next_line(remaining_text) - lines += [line] - - return ''.join(lines) - - -def create_whitespace(source_substring): - return Token(tokens.TYPE_WHITESPACE, source_substring) - - -def create_multiline_string(text, maximum_line_length=120): - def escape(t): - return t.replace(u'"""', six.u(r'\"\"\"')) - source_substring = u'"""\n{}"""'.format(u'\\\n'.join(chunkate_string(escape(text), maximum_line_length))) - return Token(tokens.TYPE_MULTILINE_STRING, source_substring) diff --git a/pipenv/patched/prettytoml/tokens/test_py2toml.py b/pipenv/patched/prettytoml/tokens/test_py2toml.py deleted file mode 100644 index 0d029c5dc1..0000000000 --- a/pipenv/patched/prettytoml/tokens/test_py2toml.py +++ /dev/null @@ -1,69 +0,0 @@ -import datetime - -import strict_rfc3339 - -from prettytoml import tokens -from prettytoml.tokens import py2toml - - -def test_string(): - assert py2toml.create_string_token('fawzy', bare_string_allowed=True) == tokens.Token(tokens.TYPE_BARE_STRING, 'fawzy') - assert py2toml.create_primitive_token('I am a "cr\'azy" sentence.') == \ - tokens.Token(tokens.TYPE_STRING, '"I am a \\"cr\'azy\\" sentence."') - - -def test_multiline_string(): - text = 'The\nSuper\nT"""OML"""\n\nIs coming' - - primitive_token = py2toml.create_primitive_token(text) - - assert primitive_token.source_substring == '"""The\nSuper\nT\"\"\"OML\"\"\"\n\nIs coming"""' - - -def test_long_string(): - text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse faucibus nibh id urna euismod, " \ - "vitae blandit nisi blandit. Nam eu odio ex. Praesent iaculis sapien justo. Proin vehicula orci rhoncus " \ - "risus mattis cursus. Sed quis commodo diam. Morbi dictum fermentum ex. Ut augue lorem, facilisis eu " \ - "posuere ut, ullamcorper et quam. Donec porta neque eget erat lacinia, in convallis elit scelerisque. " \ - "Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent " \ - "felis metus, venenatis eu aliquam vel, fringilla in turpis. Praesent interdum pulvinar enim, et mattis " \ - "urna dapibus et. Sed ut egestas mauris. Etiam eleifend dui." - - primitive_token = py2toml.create_primitive_token(text) - - assert primitive_token.source_substring[3:-3] == r""" -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse \ -aucibus nibh id urna euismod, vitae blandit nisi blandit. Nam eu odio ex. \ -raesent iaculis sapien justo. Proin vehicula orci rhoncus risus mattis \ -ursus. Sed quis commodo diam. Morbi dictum fermentum ex. Ut augue lorem, \ -acilisis eu posuere ut, ullamcorper et quam. Donec porta neque eget erat \ -acinia, in convallis elit scelerisque. Class aptent taciti sociosqu ad \ -itora torquent per conubia nostra, per inceptos himenaeos. Praesent felis \ -etus, venenatis eu aliquam vel, fringilla in turpis. Praesent interdum \ -ulvinar enim, et mattis urna dapibus et. Sed ut egestas mauris. Etiam \ -leifend dui.\ -""" - - -def test_int(): - assert py2toml.create_primitive_token(42) == tokens.Token(tokens.TYPE_INTEGER, '42') - - -def test_float(): - assert py2toml.create_primitive_token(4.2) == tokens.Token(tokens.TYPE_FLOAT, '4.2') - - -def test_bool(): - assert py2toml.create_primitive_token(False) == tokens.Token(tokens.TYPE_BOOLEAN, 'false') - assert py2toml.create_primitive_token(True) == tokens.Token(tokens.TYPE_BOOLEAN, 'true') - - -def test_date(): - ts = strict_rfc3339.rfc3339_to_timestamp('1979-05-27T00:32:00-07:00') - dt = datetime.datetime.fromtimestamp(ts) - assert py2toml.create_primitive_token(dt) == tokens.Token(tokens.TYPE_DATE, '1979-05-27T07:32:00Z') - - -def test_none(): - t = py2toml.create_primitive_token(None) - assert t.type == tokens.TYPE_STRING and t.source_substring == '""' diff --git a/pipenv/patched/prettytoml/tokens/test_toml2py.py b/pipenv/patched/prettytoml/tokens/test_toml2py.py deleted file mode 100644 index ce1663654d..0000000000 --- a/pipenv/patched/prettytoml/tokens/test_toml2py.py +++ /dev/null @@ -1,86 +0,0 @@ -from datetime import datetime - -import pytz - -from prettytoml import tokens -from prettytoml.tokens import toml2py -from prettytoml.tokens.errors import BadEscapeCharacter, DeserializationError - - -def test_integer(): - t1 = tokens.Token(tokens.TYPE_INTEGER, '42') - t2 = tokens.Token(tokens.TYPE_INTEGER, '1_001_2') - - assert toml2py.deserialize(t1) == 42 - assert toml2py.deserialize(t2) == 10012 - - -def test_float(): - tokens_and_values = ( - ('4.2', 4.2), - ('12e2', 12e2), - ('1_000e2', 1e5), - ('314.1e-2', 3.141) - ) - for token_string, value in tokens_and_values: - token = tokens.Token(tokens.TYPE_FLOAT, token_string) - assert toml2py.deserialize(token) == value - - -def test_string(): - - t0 = tokens.Token(tokens.TYPE_BARE_STRING, 'fawzy') - assert toml2py.deserialize(t0) == 'fawzy' - - t1 = tokens.Token(tokens.TYPE_STRING, '"I\'m a string. \\"You can quote me\\". Name\\tJos\\u00E9\\nLocation\\tSF."') - assert toml2py.deserialize(t1) == u'I\'m a string. "You can quote me". Name\tJos\xe9\nLocation\tSF.' - - t2 = tokens.Token(tokens.TYPE_MULTILINE_STRING, '"""\nRoses are red\nViolets are blue"""') - assert toml2py.deserialize(t2) == 'Roses are red\nViolets are blue' - - t3_str = '"""\nThe quick brown \\\n\n\n fox jumps over \\\n the lazy dog."""' - t3 = tokens.Token(tokens.TYPE_MULTILINE_STRING, t3_str) - assert toml2py.deserialize(t3) == 'The quick brown fox jumps over the lazy dog.' - - t4_str = '"""\\\n The quick brown \\\n fox jumps over \\\n the lazy dog.\\\n """' - t4 = tokens.Token(tokens.TYPE_MULTILINE_STRING, t4_str) - assert toml2py.deserialize(t4) == 'The quick brown fox jumps over the lazy dog.' - - t5 = tokens.Token(tokens.TYPE_LITERAL_STRING, r"'C:\Users\nodejs\templates'") - assert toml2py.deserialize(t5) == r'C:\Users\nodejs\templates' - - t6_str = "'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''" - t6 = tokens.Token(tokens.TYPE_MULTILINE_LITERAL_STRING, t6_str) - assert toml2py.deserialize(t6) == 'The first newline is\ntrimmed in raw strings.\n All' \ - ' other whitespace\n is preserved.\n' - - -def test_date(): - t0 = tokens.Token(tokens.TYPE_DATE, '1979-05-27T07:32:00Z') - assert toml2py.deserialize(t0) == datetime(1979, 5, 27, 7, 32, tzinfo=pytz.utc) - - t1 = tokens.Token(tokens.TYPE_DATE, '1979-05-27T00:32:00-07:00') - assert toml2py.deserialize(t1) == datetime(1979, 5, 27, 7, 32, tzinfo=pytz.utc) - - t3 = tokens.Token(tokens.TYPE_DATE, '1987-07-05T17:45:00') - try: - toml2py.deserialize(t3) - assert False, 'Should detect malformed date' - except DeserializationError: - pass - - -def test_unescaping_a_string(): - - bad_escapes = ( - r"This string has a bad \a escape character.", - r'\x33', - ) - - for source in bad_escapes: - # Should complain about bad escape jobs - try: - toml2py._unescape_str(source) - assert False, "Should have thrown an exception for: " + source - except BadEscapeCharacter: - pass diff --git a/pipenv/patched/prettytoml/tokens/toml2py.py b/pipenv/patched/prettytoml/tokens/toml2py.py deleted file mode 100644 index 56804437fd..0000000000 --- a/pipenv/patched/prettytoml/tokens/toml2py.py +++ /dev/null @@ -1,130 +0,0 @@ -from __future__ import unicode_literals -import re -import string -import iso8601 -from prettytoml import tokens -from prettytoml.tokens import TYPE_BOOLEAN, TYPE_INTEGER, TYPE_FLOAT, TYPE_DATE, \ - TYPE_MULTILINE_STRING, TYPE_BARE_STRING, TYPE_MULTILINE_LITERAL_STRING, TYPE_LITERAL_STRING, \ - TYPE_STRING -import codecs -import six -from prettytoml.tokens.errors import MalformedDateError -from .errors import BadEscapeCharacter -import functools -import operator - - -def deserialize(token): - """ - Deserializes the value of a single tokens.Token instance based on its type. - - Raises DeserializationError when appropriate. - """ - - if token.type == TYPE_BOOLEAN: - return _to_boolean(token) - elif token.type == TYPE_INTEGER: - return _to_int(token) - elif token.type == TYPE_FLOAT: - return _to_float(token) - elif token.type == TYPE_DATE: - return _to_date(token) - elif token.type in (TYPE_STRING, TYPE_MULTILINE_STRING, TYPE_BARE_STRING, - TYPE_LITERAL_STRING, TYPE_MULTILINE_LITERAL_STRING): - return _to_string(token) - else: - raise Exception('This should never happen!') - - -def _unescape_str(text): - """ - Unescapes a string according the TOML spec. Raises BadEscapeCharacter when appropriate. - """ - text = text.decode('utf-8') if isinstance(text, six.binary_type) else text - tokens = [] - i = 0 - basicstr_re = re.compile(r'[^"\\\000-\037]*') - unicode_re = re.compile(r'[uU]((?<=u)[a-fA-F0-9]{4}|(?<=U)[a-fA-F0-9]{8})') - escapes = { - 'b': '\b', - 't': '\t', - 'n': '\n', - 'f': '\f', - 'r': '\r', - '\\': '\\', - '"': '"', - '/': '/', - "'": "'" - } - while True: - m = basicstr_re.match(text, i) - i = m.end() - tokens.append(m.group()) - if i == len(text) or text[i] != '\\': - break - else: - i += 1 - if unicode_re.match(text, i): - m = unicode_re.match(text, i) - i = m.end() - tokens.append(six.unichr(int(m.group(1), 16))) - else: - if text[i] not in escapes: - raise BadEscapeCharacter - tokens.append(escapes[text[i]]) - i += 1 - return ''.join(tokens) - - -def _to_string(token): - if token.type == tokens.TYPE_BARE_STRING: - return token.source_substring - - elif token.type == tokens.TYPE_STRING: - escaped = token.source_substring[1:-1] - return _unescape_str(escaped) - - elif token.type == tokens.TYPE_MULTILINE_STRING: - escaped = token.source_substring[3:-3] - - # Drop the first newline if existed - if escaped and escaped[0] == '\n': - escaped = escaped[1:] - - # Remove all occurrences of a slash-newline-zero-or-more-whitespace patterns - escaped = re.sub(r'\\\n\s*', repl='', string=escaped, flags=re.DOTALL) - return _unescape_str(escaped) - - elif token.type == tokens.TYPE_LITERAL_STRING: - return token.source_substring[1:-1] - - elif token.type == tokens.TYPE_MULTILINE_LITERAL_STRING: - text = token.source_substring[3:-3] - if text[0] == '\n': - text = text[1:] - return text - - raise RuntimeError('Control should never reach here.') - - -def _to_int(token): - return int(token.source_substring.replace('_', '')) - - -def _to_float(token): - assert token.type == tokens.TYPE_FLOAT - string = token.source_substring.replace('_', '') - return float(string) - - -def _to_boolean(token): - return token.source_substring == 'true' - - -_correct_date_format = re.compile(r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})') - - -def _to_date(token): - if not _correct_date_format.match(token.source_substring): - raise MalformedDateError - return iso8601.parse_date(token.source_substring) diff --git a/pipenv/patched/prettytoml/util.py b/pipenv/patched/prettytoml/util.py deleted file mode 100644 index 155f00e207..0000000000 --- a/pipenv/patched/prettytoml/util.py +++ /dev/null @@ -1,141 +0,0 @@ -import math -import itertools - - -def is_sequence_like(x): - """ - Returns True if x exposes a sequence-like interface. - """ - required_attrs = ( - '__len__', - '__getitem__' - ) - return all(hasattr(x, attr) for attr in required_attrs) - - -def is_dict_like(x): - """ - Returns True if x exposes a dict-like interface. - """ - required_attrs = ( - '__len__', - '__getitem__', - 'keys', - 'values', - ) - return all(hasattr(x, attr) for attr in required_attrs) - - -def join_with(iterable, separator): - """ - Joins elements from iterable with separator and returns the produced sequence as a list. - - separator must be addable to a list. - """ - inputs = list(iterable) - b = [] - for i, element in enumerate(inputs): - if isinstance(element, (list, tuple, set)): - b += tuple(element) - else: - b += [element] - if i < len(inputs)-1: - b += separator - return b - - -def chunkate_string(text, length): - """ - Iterates over the given seq in chunks of at maximally the given length. Will never break a whole word. - """ - iterator_index = 0 - - def next_newline(): - try: - return next(i for (i, c) in enumerate(text) if i > iterator_index and c == '\n') - except StopIteration: - return len(text) - - def next_breaker(): - try: - return next(i for (i, c) in reversed(tuple(enumerate(text))) - if i >= iterator_index and - (i < iterator_index+length) and - c in (' ', '\t')) - except StopIteration: - return len(text) - - while iterator_index < len(text): - next_chunk = text[iterator_index:min(next_newline(), next_breaker()+1)] - iterator_index += len(next_chunk) - yield next_chunk - - -def flatten_nested(nested_dicts): - """ - Flattens dicts and sequences into one dict with tuples of keys representing the nested keys. - - Example - >>> dd = { \ - 'dict1': {'name': 'Jon', 'id': 42}, \ - 'dict2': {'name': 'Sam', 'id': 41}, \ - 'seq1': [{'one': 1, 'two': 2}] \ - } - - >>> flatten_nested(dd) == { \ - ('dict1', 'name'): 'Jon', ('dict1', 'id'): 42, \ - ('dict2', 'name'): 'Sam', ('dict2', 'id'): 41, \ - ('seq1', 0, 'one'): 1, ('seq1', 0, 'two'): 2, \ - } - True - """ - assert isinstance(nested_dicts, (dict, list, tuple)), 'Only works with a collection parameter' - - def items(c): - if isinstance(c, dict): - return c.items() - elif isinstance(c, (list, tuple)): - return enumerate(c) - else: - raise RuntimeError('c must be a collection') - - def flatten(dd): - output = {} - for k, v in items(dd): - if isinstance(v, (dict, list, tuple)): - for child_key, child_value in flatten(v).items(): - output[(k,) + child_key] = child_value - else: - output[(k,)] = v - return output - - return flatten(nested_dicts) - - -class PeekableIterator: - - # Returned by peek() when the iterator is exhausted. Truthiness is False. - Nothing = tuple() - - def __init__(self, iter): - self._iter = iter - - def __next__(self): - return next(self._iter) - - def next(self): - return self.__next__() - - def __iter__(self): - return self - - def peek(self): - """ - Returns PeekableIterator.Nothing when the iterator is exhausted. - """ - try: - v = next(self._iter) - self._iter = itertools.chain((v,), self._iter) - return v - except StopIteration: - return PeekableIterator.Nothing diff --git a/pipenv/project.py b/pipenv/project.py index 4b90f4934d..13c6619f64 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -75,7 +75,7 @@ class _LockFileEncoder(json.JSONEncoder): This adds a few characteristics to the encoder: * The JSON is always prettified with indents and spaces. - * PrettyTOML's container elements are seamlessly encodable. + * TOMLKit's container elements are seamlessly encodable. * The output is always UTF-8-encoded text, never binary, even on Python 2. """ @@ -85,11 +85,7 @@ def __init__(self): ) def default(self, obj): - from prettytoml.elements.common import ContainerElement, TokenElement - - if isinstance(obj, (ContainerElement, TokenElement)): - return obj.primitive_value - elif isinstance(obj, vistir.compat.Path): + if isinstance(obj, vistir.compat.Path): obj = obj.as_posix() return super(_LockFileEncoder, self).default(obj) diff --git a/tasks/vendoring/patches/patched/contoml.patch b/tasks/vendoring/patches/patched/contoml.patch deleted file mode 100644 index b9b2e9d7f4..0000000000 --- a/tasks/vendoring/patches/patched/contoml.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/pipenv/patched/contoml/file/file.py b/pipenv/patched/contoml/file/file.py -index 5033a7b..99ce148 100644 ---- a/pipenv/patched/contoml/file/file.py -+++ b/pipenv/patched/contoml/file/file.py -@@ -30,6 +30,14 @@ class TOMLFile: - except KeyError: - return FreshTable(parent=self, name=item, is_array=False) - -+ def get(self, item, default=None): -+ """This was not here for who knows why.""" -+ -+ if item not in self: -+ return default -+ else: -+ return self.__getitem__(item) -+ - def __contains__(self, item): - return item in self.keys() - -@@ -223,7 +231,7 @@ class TOMLFile: - if has_anonymous_entry(): - return items - else: -- return items + [('', self[''])] -+ return list(items) + [('', self[''])] - - @property - def primitive(self): diff --git a/tasks/vendoring/patches/patched/prettytoml-newlinefix.patch b/tasks/vendoring/patches/patched/prettytoml-newlinefix.patch deleted file mode 100644 index 2b1066a10f..0000000000 --- a/tasks/vendoring/patches/patched/prettytoml-newlinefix.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/pipenv/patched/prettytoml/elements/traversal/__init__.py b/pipenv/patched/prettytoml/elements/traversal/__init__.py -index 5b98045..c93506e 100644 ---- a/pipenv/patched/prettytoml/elements/traversal/__init__.py -+++ b/pipenv/patched/prettytoml/elements/traversal/__init__.py -@@ -78,7 +78,7 @@ class TraversalMixin: - - if following_comment == float('-inf'): - return following_newline -- if following_newline == float('inf'): -+ if following_newline == float('-inf'): - return following_comment - - if following_newline < following_comment: diff --git a/tasks/vendoring/patches/patched/prettytoml-python37.patch b/tasks/vendoring/patches/patched/prettytoml-python37.patch deleted file mode 100644 index 5039a1c7eb..0000000000 --- a/tasks/vendoring/patches/patched/prettytoml-python37.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c44f2126fb5c75a5f5afd9d320c9f6cfc4ce3384 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Tue, 26 Jun 2018 21:02:45 +0200 -Subject: [PATCH] Catch StopIteration in AbstractTable._enumerate_items - -This makes PEP 479 enabled Pythons (such as 3.7) work again. - -Otherwise you get: - - RuntimeError: generator raised StopIteration - -Fixes https://github.com/pypa/pipenv/issues/2426 ---- - pipenv/patched/prettytoml/elements/abstracttable.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/pipenv/patched/prettytoml/elements/abstracttable.py b/pipenv/patched/prettytoml/elements/abstracttable.py -index 59fd574..627da0e 100644 ---- a/pipenv/patched/prettytoml/elements/abstracttable.py -+++ b/pipenv/patched/prettytoml/elements/abstracttable.py -@@ -19,7 +19,10 @@ def _enumerate_items(self): - """ - non_metadata = self._enumerate_non_metadata_sub_elements() - while True: -- yield next(non_metadata), next(non_metadata) -+ try: -+ yield next(non_metadata), next(non_metadata) -+ except StopIteration: -+ return - - def items(self): - for (key_i, key), (value_i, value) in self._enumerate_items(): diff --git a/tasks/vendoring/patches/patched/prettytoml-table-iter.patch b/tasks/vendoring/patches/patched/prettytoml-table-iter.patch deleted file mode 100644 index 9ec52633c4..0000000000 --- a/tasks/vendoring/patches/patched/prettytoml-table-iter.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/pipenv/patched/prettytoml/elements/abstracttable.py b/pipenv/patched/prettytoml/elements/abstracttable.py -index 59fd5748..48663aed 100644 ---- a/pipenv/patched/prettytoml/elements/abstracttable.py -+++ b/pipenv/patched/prettytoml/elements/abstracttable.py -@@ -1,8 +1,13 @@ -+try: -+ from collections.abc import Mapping -+except ImportError: -+ from collections import Mapping -+ - from prettytoml.elements.common import ContainerElement - from prettytoml.elements import traversal - - --class AbstractTable(ContainerElement, traversal.TraversalMixin): -+class AbstractTable(ContainerElement, traversal.TraversalMixin, Mapping): - """ - Common code for handling tables as key-value pairs with metadata elements sprinkled all over. - -@@ -37,6 +42,9 @@ class AbstractTable(ContainerElement, traversal.TraversalMixin): - def __len__(self): - return len(tuple(self._enumerate_items())) - -+ def __iter__(self): -+ return (key for key, _ in self.items()) -+ - def __contains__(self, item): - return item in self.keys() - diff --git a/tasks/vendoring/patches/patched/prettytoml-unicode.patch b/tasks/vendoring/patches/patched/prettytoml-unicode.patch deleted file mode 100644 index 54f4c6218b..0000000000 --- a/tasks/vendoring/patches/patched/prettytoml-unicode.patch +++ /dev/null @@ -1,132 +0,0 @@ -diff --git a/pipenv/patched/prettytoml/tokens/py2toml.py b/pipenv/patched/prettytoml/tokens/py2toml.py -index 8299195..2decd02 100644 ---- a/pipenv/patched/prettytoml/tokens/py2toml.py -+++ b/pipenv/patched/prettytoml/tokens/py2toml.py -@@ -2,6 +2,7 @@ - """ - A converter of python values to TOML Token instances. - """ -+from __future__ import unicode_literals - import codecs - import datetime - import six -@@ -81,10 +82,30 @@ def create_string_token(text, bare_string_allowed=False, multiline_strings_allow - - - def _escape_single_line_quoted_string(text): -- if six.PY2: -- return text.encode('unicode-escape').encode('string-escape').replace('"', '\\"').replace("\\'", "'") -- else: -- return codecs.encode(text, 'unicode-escape').decode().replace('"', '\\"') -+ text = text.decode('utf-8') if isinstance(text, six.binary_type) else text -+ start = 0 -+ i = 0 -+ res = [] -+ _escapes = {'\n': '\\n', '\r': '\\r', '\\': '\\\\', '\t': '\\t', -+ '\b': '\\b', '\f': '\\f', '"': '\\"'} -+ -+ def flush(): -+ if start < i: -+ res.append(text[start:i]) -+ return i + 1 -+ -+ while i < len(text): -+ c = text[i] -+ if c in _escapes: -+ start = flush() -+ res.append(_escapes[c]) -+ elif ord(c) < 0x20: -+ start = flush() -+ res.append('\\u%04x' % ord(c)) -+ i += 1 -+ -+ flush() -+ return ''.join(res) - - - def _create_multiline_string_token(text): -diff --git a/pipenv/patched/prettytoml/tokens/toml2py.py b/pipenv/patched/prettytoml/tokens/toml2py.py -index 2bf9c1c..5680443 100644 ---- a/pipenv/patched/prettytoml/tokens/toml2py.py -+++ b/pipenv/patched/prettytoml/tokens/toml2py.py -@@ -1,3 +1,4 @@ -+from __future__ import unicode_literals - import re - import string - import iso8601 -@@ -39,42 +40,40 @@ def _unescape_str(text): - """ - Unescapes a string according the TOML spec. Raises BadEscapeCharacter when appropriate. - """ -- -- # Detect bad escape jobs -- bad_escape_regexp = re.compile(r'([^\\]|^)\\[^btnfr"\\uU]') -- if bad_escape_regexp.findall(text): -- raise BadEscapeCharacter -- -- # Do the unescaping -- if six.PY2: -- return _unicode_escaped_string(text).decode('string-escape').decode('unicode-escape') -- else: -- return codecs.decode(_unicode_escaped_string(text), 'unicode-escape') -- -- --def _unicode_escaped_string(text): -- """ -- Escapes all unicode characters in the given string -- """ -- -- if six.PY2: -- text = unicode(text) -- -- def is_unicode(c): -- return c.lower() not in string.ascii_letters + string.whitespace + string.punctuation + string.digits -- -- def escape_unicode_char(x): -- if six.PY2: -- return x.encode('unicode-escape') -+ text = text.decode('utf-8') if isinstance(text, six.binary_type) else text -+ tokens = [] -+ i = 0 -+ basicstr_re = re.compile(r'[^"\\\000-\037]*') -+ unicode_re = re.compile(r'[uU]((?<=u)[a-fA-F0-9]{4}|(?<=U)[a-fA-F0-9]{8})') -+ escapes = { -+ 'b': '\b', -+ 't': '\t', -+ 'n': '\n', -+ 'f': '\f', -+ 'r': '\r', -+ '\\': '\\', -+ '"': '"', -+ '/': '/', -+ "'": "'" -+ } -+ while True: -+ m = basicstr_re.match(text, i) -+ i = m.end() -+ tokens.append(m.group()) -+ if i == len(text) or text[i] != '\\': -+ break - else: -- return codecs.encode(x, 'unicode-escape') -- -- if any(is_unicode(c) for c in text): -- homogeneous_chars = tuple(escape_unicode_char(c) if is_unicode(c) else c.encode() for c in text) -- homogeneous_bytes = functools.reduce(operator.add, homogeneous_chars) -- return homogeneous_bytes.decode() -- else: -- return text -+ i += 1 -+ if unicode_re.match(text, i): -+ m = unicode_re.match(text, i) -+ i = m.end() -+ tokens.append(six.unichr(int(m.group(1), 16))) -+ else: -+ if text[i] not in escapes: -+ raise BadEscapeCharacter -+ tokens.append(escapes[text[i]]) -+ i += 1 -+ return ''.join(tokens) - - - def _to_string(token): diff --git a/tasks/vendoring/patches/patched/prettytoml.patch b/tasks/vendoring/patches/patched/prettytoml.patch deleted file mode 100644 index 85dfb791f4..0000000000 --- a/tasks/vendoring/patches/patched/prettytoml.patch +++ /dev/null @@ -1,78 +0,0 @@ -diff --git a/pipenv/patched/prettytoml/_version.py b/pipenv/patched/prettytoml/_version.py -index 4f146e6..e0f1547 100644 ---- a/pipenv/patched/prettytoml/_version.py -+++ b/pipenv/patched/prettytoml/_version.py -@@ -1 +1 @@ --VERSION = '0.03' -+VERSION = 'master' -diff --git a/pipenv/patched/prettytoml/elements/table.py b/pipenv/patched/prettytoml/elements/table.py -index f78a6d1..cdc3ed4 100644 ---- a/pipenv/patched/prettytoml/elements/table.py -+++ b/pipenv/patched/prettytoml/elements/table.py -@@ -94,9 +94,9 @@ class TableElement(abstracttable.AbstractTable): - value_element, - factory.create_newline_element(), - ] -- -+ - insertion_index = self._find_insertion_index() -- -+ - self._sub_elements = \ - self.sub_elements[:insertion_index] + inserted_elements + self.sub_elements[insertion_index:] - -@@ -105,11 +105,16 @@ class TableElement(abstracttable.AbstractTable): - preceding_newline = self._find_preceding_newline(begin) - if preceding_newline >= 0: - begin = preceding_newline -- end = self._find_following_newline(begin) -+ end = self._find_following_line_terminator(begin) - if end < 0: - end = len(tuple(self._sub_elements)) - self._sub_elements = self.sub_elements[:begin] + self.sub_elements[end:] - -+ def pop(self, key): -+ v = self[key] -+ del self[key] -+ return v -+ - def value(self): - return self - -diff --git a/pipenv/patched/prettytoml/tokens/py2toml.py b/pipenv/patched/prettytoml/tokens/py2toml.py -index 3db97b4..8299195 100644 ---- a/pipenv/patched/prettytoml/tokens/py2toml.py -+++ b/pipenv/patched/prettytoml/tokens/py2toml.py -@@ -5,11 +5,8 @@ A converter of python values to TOML Token instances. - import codecs - import datetime - import six --import strict_rfc3339 --import timestamp - from prettytoml import tokens - import re --from prettytoml.elements.metadata import NewlineElement - from prettytoml.errors import TOMLError - from prettytoml.tokens import Token - from prettytoml.util import chunkate_string -@@ -49,15 +46,17 @@ def create_primitive_token(value, multiline_strings_allowed=True): - elif isinstance(value, float): - return tokens.Token(tokens.TYPE_FLOAT, u'{}'.format(value)) - elif isinstance(value, (datetime.datetime, datetime.date, datetime.time)): -- ts = timestamp(value) // 1000 -- return tokens.Token(tokens.TYPE_DATE, strict_rfc3339.timestamp_to_rfc3339_utcoffset(ts)) -+ s = value.isoformat() -+ if s.endswith('+00:00'): -+ s = s[:-6] + 'Z' -+ return tokens.Token(tokens.TYPE_DATE, s) - elif isinstance(value, six.string_types): - return create_string_token(value, multiline_strings_allowed=multiline_strings_allowed) - - raise NotPrimitiveError("{} of type {}".format(value, type(value))) - - --_bare_string_regex = re.compile('^[a-zA-Z0-9_-]*$') -+_bare_string_regex = re.compile('^[a-zA-Z_-]*$') - - - def create_string_token(text, bare_string_allowed=False, multiline_strings_allowed=True): diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index 1e00bbb70b..5e1bafb919 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -160,4 +160,4 @@ def test_rewrite_outline_table(PipenvInstance, pypi): with open(p.pipfile_path) as f: contents = f.read() assert "[packages.requests]" not in contents - assert 'requests = { version = "*" }' in contents + assert 'requests = {version = "*"}' in contents diff --git a/tests/unit/test_vendor.py b/tests/unit/test_vendor.py index 704b37fb7f..6514b16290 100644 --- a/tests/unit/test_vendor.py +++ b/tests/unit/test_vendor.py @@ -1,43 +1,10 @@ # -*- coding: utf-8 -*- # We need to import the patched packages directly from sys.path, so the # identity checks can pass. -import pipenv # noqa - -import datetime import os -import pytest -import pytz - -import contoml +import pipenv # noqa from pipfile.api import PipfileParser -from prettytoml import lexer, tokens -from prettytoml.elements.atomic import AtomicElement -from prettytoml.elements.metadata import ( - WhitespaceElement, PunctuationElement, CommentElement -) -from prettytoml.elements.table import TableElement -from prettytoml.tokens.py2toml import create_primitive_token - - -def test_table(): - initial_toml = """id=42 # My id\nage=14""" - tokens = tuple(lexer.tokenize(initial_toml)) - table = TableElement( - [ - AtomicElement(tokens[0:1]), - PunctuationElement(tokens[1:2]), - AtomicElement(tokens[2:3]), - WhitespaceElement(tokens[3:4]), - CommentElement(tokens[4:6]), - AtomicElement(tokens[6:7]), - PunctuationElement(tokens[7:8]), - AtomicElement(tokens[8:9]), - ] - ) - assert set(table.items()) == {('id', 42), ('age', 14)} - del table['id'] - assert set(table.items()) == {('age', 14)} class TestPipfileParser: @@ -71,38 +38,3 @@ def test_inject_environment_variables(self): assert parsed_dict["list"][1] == {} assert parsed_dict["bool"] is True assert parsed_dict["none"] is None - - -@pytest.mark.parametrize('dt, content', [ - ( # Date. - datetime.date(1992, 8, 19), - '1992-08-19', - ), - ( # Naive time. - datetime.time(15, 10), - '15:10:00', - ), - ( # Aware time in UTC. - datetime.time(15, 10, tzinfo=pytz.UTC), - '15:10:00Z', - ), - ( # Aware local time. - datetime.time(15, 10, tzinfo=pytz.FixedOffset(8 * 60)), - '15:10:00+08:00', - ), - ( # Naive datetime. - datetime.datetime(1992, 8, 19, 15, 10), - '1992-08-19T15:10:00', - ), - ( # Aware datetime in UTC. - datetime.datetime(1992, 8, 19, 15, 10, tzinfo=pytz.UTC), - '1992-08-19T15:10:00Z', - ), - ( # Aware local datetime. - datetime.datetime(1992, 8, 19, 15, 10, tzinfo=pytz.FixedOffset(8 * 60)), - '1992-08-19T15:10:00+08:00', - ), -]) -def test_token_date(dt, content): - token = create_primitive_token(dt) - assert token == tokens.Token(tokens.TYPE_DATE, content) From b27d6a771081f7f88dd3d0005e0d60bbbf0ee53d Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 11:04:42 +0800 Subject: [PATCH 03/14] clear references in patched.txt --- pipenv/patched/patched.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/pipenv/patched/patched.txt b/pipenv/patched/patched.txt index 4f3ee409d7..e7dadd8ec9 100644 --- a/pipenv/patched/patched.txt +++ b/pipenv/patched/patched.txt @@ -1,5 +1,4 @@ safety -git+https://github.com/jumpscale7/python-consistent-toml.git#egg=contoml crayons==0.1.2 pipfile==0.0.2 pip-tools==3.1.0 From 1555200463cd91babc1197e81bec15357d7f11f4 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 14:59:59 +0800 Subject: [PATCH 04/14] Add back some tests --- tests/unit/test_vendor.py | 49 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_vendor.py b/tests/unit/test_vendor.py index 6514b16290..35458c5342 100644 --- a/tests/unit/test_vendor.py +++ b/tests/unit/test_vendor.py @@ -1,9 +1,15 @@ # -*- coding: utf-8 -*- # We need to import the patched packages directly from sys.path, so the # identity checks can pass. +import pipenv # noqa + +import datetime import os -import pipenv # noqa +import pytest +import pytz +import tomlkit + from pipfile.api import PipfileParser @@ -38,3 +44,44 @@ def test_inject_environment_variables(self): assert parsed_dict["list"][1] == {} assert parsed_dict["bool"] is True assert parsed_dict["none"] is None + + +@pytest.mark.parametrize('dt, content', [ + ( # Date. + datetime.date(1992, 8, 19), + '1992-08-19', + ), + ( # Naive time. + datetime.time(15, 10), + '15:10:00', + ), + ( # Aware time in UTC. + datetime.time(15, 10, tzinfo=pytz.UTC), + '15:10:00+00:00', + ), + ( # Aware local time. + datetime.time(15, 10, tzinfo=pytz.FixedOffset(8 * 60)), + '15:10:00+08:00', + ), + ( # Naive datetime. + datetime.datetime(1992, 8, 19, 15, 10), + '1992-08-19T15:10:00', + ), + ( # Aware datetime in UTC. + datetime.datetime(1992, 8, 19, 15, 10, tzinfo=pytz.UTC), + '1992-08-19T15:10:00Z', + ), + ( # Aware local datetime. + datetime.datetime(1992, 8, 19, 15, 10, tzinfo=pytz.FixedOffset(8 * 60)), + '1992-08-19T15:10:00+08:00', + ), +]) +def test_token_date(dt, content): + item = tomlkit.item(dt) + assert item.as_string() == content + + +def test_dump_nonascii_string(): + content = 'name = "Stažené"\n' + toml_content = tomlkit.dumps(tomlkit.loads(content)) + assert toml_content == content From 53b073c7ffcce7d18dd3b459932d49f783546434 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 15:20:47 +0800 Subject: [PATCH 05/14] python 2.7 unicode --- pipenv/project.py | 2 +- tests/unit/test_vendor.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index 13c6619f64..74fe65271f 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -856,7 +856,7 @@ def write_toml(self, data, path=None): formatted_data = tomlkit.dumps(data).rstrip() else: encoder = toml.encoder.TomlPreserveInlineDictEncoder() - formatted_data = toml.dumps(data, encoder=encoder) + formatted_data = toml.dumps(data, encoder=encoder).rstrip() except Exception: document = tomlkit.document() for section in ("packages", "dev-packages"): diff --git a/tests/unit/test_vendor.py b/tests/unit/test_vendor.py index 35458c5342..aea9311214 100644 --- a/tests/unit/test_vendor.py +++ b/tests/unit/test_vendor.py @@ -82,6 +82,6 @@ def test_token_date(dt, content): def test_dump_nonascii_string(): - content = 'name = "Stažené"\n' + content = u'name = "Stažené"\n' toml_content = tomlkit.dumps(tomlkit.loads(content)) assert toml_content == content From b3aa66b1542200994dcdd5770228568a7f6dbac7 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 17:26:39 +0800 Subject: [PATCH 06/14] make tomlkit dump toml's inline table --- pipenv/project.py | 13 +++++----- pipenv/vendor/tomlkit/items.py | 6 ++++- .../vendor/tomlkit-dump-inline-table.patch | 24 +++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch diff --git a/pipenv/project.py b/pipenv/project.py index 74fe65271f..6d59b4cbf3 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -572,10 +572,15 @@ def clear_pipfile_cache(self): """Clear pipfile cache (e.g., so we can mutate parsed pipfile)""" _pipfile_cache.clear() + @staticmethod + def _is_tomlkit_parsed_result(parsed): + """Check by duck typing of tomlkit.api.Container""" + return hasattr(parsed, "_body") + @staticmethod def convert_outline_table(parsed): """Converts all outline to inline tables""" - if hasattr(parsed, "_body"): # Duck-type that implies tomlkit.api.Container. + if Project._istomlkit_parsed_result(parsed): empty_inline_table = tomlkit.inline_table else: empty_inline_table = toml.TomlDecoder().get_empty_inline_table @@ -852,11 +857,7 @@ def write_toml(self, data, path=None): if path is None: path = self.pipfile_location try: - if hasattr(data, "_body"): - formatted_data = tomlkit.dumps(data).rstrip() - else: - encoder = toml.encoder.TomlPreserveInlineDictEncoder() - formatted_data = toml.dumps(data, encoder=encoder).rstrip() + formatted_data = tomlkit.dumps(data).rstrip() except Exception: document = tomlkit.document() for section in ("packages", "dev-packages"): diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py index 781e2e9843..80e029d988 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py @@ -21,6 +21,7 @@ from pipenv.vendor.backports.functools_lru_cache import lru_cache else: from functools import lru_cache +from toml.decoder import InlineTableDict def item(value, _parent=None): @@ -36,7 +37,10 @@ def item(value, _parent=None): elif isinstance(value, float): return Float(value, Trivia(), str(value)) elif isinstance(value, dict): - val = Table(Container(), Trivia(), False) + if isinstance(value, InlineTableDict): + val = InlineTable(Container(), Trivia()) + else: + val = Table(Container(), Trivia(), False) for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): val[k] = item(v, _parent=val) diff --git a/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch b/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch new file mode 100644 index 0000000000..755bd31a5e --- /dev/null +++ b/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch @@ -0,0 +1,24 @@ +diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py +index 781e2e98..80e029d9 100644 +--- a/pipenv/vendor/tomlkit/items.py ++++ b/pipenv/vendor/tomlkit/items.py +@@ -21,6 +21,7 @@ if PY2: + from pipenv.vendor.backports.functools_lru_cache import lru_cache + else: + from functools import lru_cache ++from toml.decoder import InlineTableDict + + + def item(value, _parent=None): +@@ -36,7 +37,10 @@ def item(value, _parent=None): + elif isinstance(value, float): + return Float(value, Trivia(), str(value)) + elif isinstance(value, dict): +- val = Table(Container(), Trivia(), False) ++ if isinstance(value, InlineTableDict): ++ val = InlineTable(Container(), Trivia()) ++ else: ++ val = Table(Container(), Trivia(), False) + for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): + val[k] = item(v, _parent=val) + From 65d70905ee8d8e79bbe8ba8c5d5b72573f37e201 Mon Sep 17 00:00:00 2001 From: frostming Date: Thu, 8 Nov 2018 17:52:05 +0800 Subject: [PATCH 07/14] Force inline table --- pipenv/project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipenv/project.py b/pipenv/project.py index 6d59b4cbf3..4f947e4b18 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -580,7 +580,7 @@ def _is_tomlkit_parsed_result(parsed): @staticmethod def convert_outline_table(parsed): """Converts all outline to inline tables""" - if Project._istomlkit_parsed_result(parsed): + if Project._is_tomlkit_parsed_result(parsed): empty_inline_table = tomlkit.inline_table else: empty_inline_table = toml.TomlDecoder().get_empty_inline_table @@ -856,6 +856,7 @@ def write_toml(self, data, path=None): """Writes the given data structure out as TOML.""" if path is None: path = self.pipfile_location + data = self.convert_outline_table(data) try: formatted_data = tomlkit.dumps(data).rstrip() except Exception: From 3490fc85efc652f9f20dedd2c3dc6f5d1a2087e1 Mon Sep 17 00:00:00 2001 From: frostming Date: Fri, 9 Nov 2018 11:23:02 +0800 Subject: [PATCH 08/14] fix patch --- pipenv/vendor/tomlkit/container.py | 3 +-- .../patches/vendor/tomlkit-update-items.patch | 11 +++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py index 5ddd72e7b8..987a079036 100644 --- a/pipenv/vendor/tomlkit/container.py +++ b/pipenv/vendor/tomlkit/container.py @@ -196,8 +196,7 @@ def remove(self, key): # type: (Union[Key, str]) -> Container self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) else: self._body[idx] = (None, Null()) - super(Container, self).__delitem__(key.key) - + super(Container, self).__delitem__(key.key) return self diff --git a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch b/tasks/vendoring/patches/vendor/tomlkit-update-items.patch index 51f6006a94..c996cb9609 100644 --- a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch +++ b/tasks/vendoring/patches/vendor/tomlkit-update-items.patch @@ -9,11 +9,11 @@ index 37014921..5ddd72e7 100644 +from .items import Trivia from .items import Whitespace from .items import item as _item - + @@ -189,9 +190,14 @@ class Container(dict): if idx is None: raise NonExistentKey(key) - + - self._body[idx] = (None, Null()) + old_data = self._body[idx][1] + trivia = getattr(old_data, "trivia", None) @@ -21,9 +21,8 @@ index 37014921..5ddd72e7 100644 + self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) + else: + self._body[idx] = (None, Null()) -+ super(Container, self).__delitem__(key.key) - ++ super(Container, self).__delitem__(key.key) + - super(Container, self).__delitem__(key.key) - + return self - From de78c1efce2da437ed39f014509f576305bb0f2f Mon Sep 17 00:00:00 2001 From: frostming Date: Fri, 9 Nov 2018 12:59:51 +0800 Subject: [PATCH 09/14] Only convert outline tables when write toml --- pipenv/project.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index f58b9c585e..bed430af91 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -585,25 +585,28 @@ def convert_outline_table(parsed): else: empty_inline_table = toml.TomlDecoder().get_empty_inline_table for section in ("packages", "dev-packages"): + has_outline_table = False table_data = parsed.get(section, {}).copy() for package, value in table_data.items(): - if hasattr(value, "keys"): + if hasattr(value, "keys") and not isinstance( + value, (tomlkit.items.InlineTable, toml.decoder.InlineTableDict) + ): + has_outline_table = True table = empty_inline_table() table.update(value) table_data[package] = table - parsed[section] = table_data + if has_outline_table: + # We'll lose comments here, only update when necessary + parsed[section] = table_data return parsed def _parse_pipfile(self, contents): try: - data = tomlkit.parse(contents) + return tomlkit.parse(contents) except Exception: # We lose comments here, but it's for the best.) # Fallback to toml parser, for large files. - data = toml.loads(contents) - if "[packages." in contents or "[dev-packages." in contents: - data = self.convert_outline_table(data) - return data + return toml.loads(contents) def _read_pyproject(self): pyproject = self.path_to("pyproject.toml") From accd0ea4abdb1cbe35c094e01cc93b36147c44a3 Mon Sep 17 00:00:00 2001 From: frostming Date: Fri, 9 Nov 2018 14:18:04 +0800 Subject: [PATCH 10/14] Move to utils function --- pipenv/project.py | 31 ++----------------- pipenv/utils.py | 25 +++++++++++++++ .../patches/vendor/tomlkit-update-items.patch | 15 +++++---- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index bed430af91..04b519ed42 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -25,6 +25,7 @@ find_requirements, is_editable, cleanup_toml, + convert_toml_outline_tables, is_installable_file, is_valid_url, normalize_drive, @@ -572,34 +573,6 @@ def clear_pipfile_cache(self): """Clear pipfile cache (e.g., so we can mutate parsed pipfile)""" _pipfile_cache.clear() - @staticmethod - def _is_tomlkit_parsed_result(parsed): - """Check by duck typing of tomlkit.api.Container""" - return hasattr(parsed, "_body") - - @staticmethod - def convert_outline_table(parsed): - """Converts all outline to inline tables""" - if Project._is_tomlkit_parsed_result(parsed): - empty_inline_table = tomlkit.inline_table - else: - empty_inline_table = toml.TomlDecoder().get_empty_inline_table - for section in ("packages", "dev-packages"): - has_outline_table = False - table_data = parsed.get(section, {}).copy() - for package, value in table_data.items(): - if hasattr(value, "keys") and not isinstance( - value, (tomlkit.items.InlineTable, toml.decoder.InlineTableDict) - ): - has_outline_table = True - table = empty_inline_table() - table.update(value) - table_data[package] = table - if has_outline_table: - # We'll lose comments here, only update when necessary - parsed[section] = table_data - return parsed - def _parse_pipfile(self, contents): try: return tomlkit.parse(contents) @@ -860,7 +833,7 @@ def write_toml(self, data, path=None): """Writes the given data structure out as TOML.""" if path is None: path = self.pipfile_location - data = self.convert_outline_table(data) + data = convert_toml_outline_tables(data) try: formatted_data = tomlkit.dumps(data).rstrip() except Exception: diff --git a/pipenv/utils.py b/pipenv/utils.py index 8674aee207..9d495fa367 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -7,6 +7,8 @@ import shutil import stat import sys +import toml +import tomlkit import warnings import crayons @@ -93,6 +95,29 @@ def cleanup_toml(tml): return toml +def convert_toml_outline_tables(parsed): + """Converts all outline tables to inline tables.""" + if isinstance(parsed, tomlkit.container.Container): + empty_inline_table = tomlkit.inline_table + else: + empty_inline_table = toml.TomlDecoder().get_empty_inline_table + for section in ("packages", "dev-packages"): + has_outline_table = False + table_data = parsed.get(section, {}).copy() + for package, value in table_data.items(): + if hasattr(value, "keys") and not isinstance( + value, (tomlkit.items.InlineTable, toml.decoder.InlineTableDict) + ): + has_outline_table = True + table = empty_inline_table() + table.update(value) + table_data[package] = table + if has_outline_table: + # We'll lose comments here, only update when necessary + parsed[section] = table_data + return parsed + + def parse_python_version(output): """Parse a Python version output returned by `python --version`. diff --git a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch b/tasks/vendoring/patches/vendor/tomlkit-update-items.patch index c996cb9609..ed2fb95eb9 100644 --- a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch +++ b/tasks/vendoring/patches/vendor/tomlkit-update-items.patch @@ -1,5 +1,5 @@ diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py -index 37014921..5ddd72e7 100644 +index 37014921..987a0790 100644 --- a/pipenv/vendor/tomlkit/container.py +++ b/pipenv/vendor/tomlkit/container.py @@ -9,6 +9,7 @@ from .items import Item @@ -9,20 +9,19 @@ index 37014921..5ddd72e7 100644 +from .items import Trivia from .items import Whitespace from .items import item as _item - -@@ -189,9 +190,14 @@ class Container(dict): + +@@ -189,8 +190,12 @@ class Container(dict): if idx is None: raise NonExistentKey(key) - + - self._body[idx] = (None, Null()) +- + old_data = self._body[idx][1] + trivia = getattr(old_data, "trivia", None) + if trivia and getattr(trivia, "comment", None): + self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) + else: + self._body[idx] = (None, Null()) -+ super(Container, self).__delitem__(key.key) - -- super(Container, self).__delitem__(key.key) - + super(Container, self).__delitem__(key.key) + return self From 6df7d8861da841e552049dcde9ff9a0f23edc01e Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Sat, 10 Nov 2018 12:34:54 +0800 Subject: [PATCH 11/14] update tomlkit --- Pipfile.lock | 6 +- pipenv/vendor/tomlkit/__init__.py | 2 +- pipenv/vendor/tomlkit/_compat.py | 2 + pipenv/vendor/tomlkit/_utils.py | 17 +- pipenv/vendor/tomlkit/api.py | 2 + pipenv/vendor/tomlkit/container.py | 129 ++++-- pipenv/vendor/tomlkit/exceptions.py | 70 +++- pipenv/vendor/tomlkit/items.py | 53 ++- pipenv/vendor/tomlkit/parser.py | 586 +++++++++++++++------------- pipenv/vendor/tomlkit/source.py | 195 +++++++++ pipenv/vendor/tomlkit/toml_char.py | 19 +- pipenv/vendor/tomlkit/toml_file.py | 3 + pipenv/vendor/vendor.txt | 1 + 13 files changed, 742 insertions(+), 343 deletions(-) create mode 100644 pipenv/vendor/tomlkit/source.py diff --git a/Pipfile.lock b/Pipfile.lock index 3990a45167..30a618ac03 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -626,10 +626,10 @@ }, "tomlkit": { "hashes": [ - "sha256:8ab16e93162fc44d3ad83d2aa29a7140b8f7d996ae1790a73b9a7aed6fb504ac", - "sha256:ca181cee7aee805d455628f7c94eb8ae814763769a93e69157f250fe4ebe1926" + "sha256:82a8fbb8d8c6af72e96ba00b9db3e20ef61be6c79082552c9363f4559702258b", + "sha256:a43e0195edc9b3c198cd4b5f0f3d427a395d47c4a76ceba7cc875ed030756c39" ], - "version": "==0.4.4" + "version": "==0.5.2" }, "towncrier": { "editable": true, diff --git a/pipenv/vendor/tomlkit/__init__.py b/pipenv/vendor/tomlkit/__init__.py index 89e4cf595e..92bfa27cbc 100644 --- a/pipenv/vendor/tomlkit/__init__.py +++ b/pipenv/vendor/tomlkit/__init__.py @@ -22,4 +22,4 @@ from .api import ws -__version__ = "0.4.6" +__version__ = "0.5.2" diff --git a/pipenv/vendor/tomlkit/_compat.py b/pipenv/vendor/tomlkit/_compat.py index f94bb10e26..b7407af696 100644 --- a/pipenv/vendor/tomlkit/_compat.py +++ b/pipenv/vendor/tomlkit/_compat.py @@ -141,9 +141,11 @@ def _name_from_offset(delta): if PY2: unicode = unicode chr = unichr + long = long else: unicode = str chr = chr + long = int def decode(string, encodings=None): diff --git a/pipenv/vendor/tomlkit/_utils.py b/pipenv/vendor/tomlkit/_utils.py index f62a354afd..0a68be9f16 100644 --- a/pipenv/vendor/tomlkit/_utils.py +++ b/pipenv/vendor/tomlkit/_utils.py @@ -9,19 +9,30 @@ from ._compat import decode from ._compat import timezone +RFC_3339_LOOSE = re.compile( + "^" + r"(([0-9]+)-(\d{2})-(\d{2}))?" # Date + "(" + "([T ])?" # Separator + r"(\d{2}):(\d{2}):(\d{2})(\.([0-9]+))?" # Time + r"((Z)|([\+|\-]([01][0-9]|2[0-3]):([0-5][0-9])))?" # Timezone + ")?" + "$" +) + RFC_3339_DATETIME = re.compile( "^" "([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])" # Date "[T ]" # Separator - "([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.([0-9]+))?" # Time - "((Z)|([\+|\-]([01][0-9]|2[0-3]):([0-5][0-9])))?" # Timezone + r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.([0-9]+))?" # Time + r"((Z)|([\+|\-]([01][0-9]|2[0-3]):([0-5][0-9])))?" # Timezone "$" ) RFC_3339_DATE = re.compile("^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$") RFC_3339_TIME = re.compile( - "^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.([0-9]+))?$" + r"^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.([0-9]+))?$" ) _utc = timezone(timedelta(), "UTC") diff --git a/pipenv/vendor/tomlkit/api.py b/pipenv/vendor/tomlkit/api.py index 0ac2675262..e541c20c17 100644 --- a/pipenv/vendor/tomlkit/api.py +++ b/pipenv/vendor/tomlkit/api.py @@ -1,5 +1,7 @@ import datetime as _datetime +from typing import Tuple + from ._utils import parse_rfc3339 from .container import Container from .items import AoT diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py index 987a079036..cb8af1d522 100644 --- a/pipenv/vendor/tomlkit/container.py +++ b/pipenv/vendor/tomlkit/container.py @@ -1,5 +1,13 @@ from __future__ import unicode_literals +from typing import Any +from typing import Dict +from typing import Generator +from typing import List +from typing import Optional +from typing import Tuple +from typing import Union + from ._compat import decode from .exceptions import KeyAlreadyPresent from .exceptions import NonExistentKey @@ -9,7 +17,6 @@ from .items import Key from .items import Null from .items import Table -from .items import Trivia from .items import Whitespace from .items import item as _item @@ -74,7 +81,7 @@ def add( return self.append(key, item) - def append(self, key, item): # type: (Union[Key, str], Item) -> Container + def append(self, key, item): # type: (Union[Key, str, None], Item) -> Container if not isinstance(key, Key) and key is not None: key = Key(key) @@ -99,7 +106,11 @@ def append(self, key, item): # type: (Union[Key, str], Item) -> Container self.append(None, Whitespace("\n")) if key is not None and key in self: - current = self._body[self._map[key]][1] + current_idx = self._map[key] + if isinstance(current_idx, tuple): + current_idx = current_idx[0] + + current = self._body[current_idx][1] if isinstance(item, Table): if not isinstance(current, (Table, AoT)): raise KeyAlreadyPresent(key) @@ -121,7 +132,7 @@ def append(self, key, item): # type: (Union[Key, str], Item) -> Container current.append(k, v) return self - else: + elif not item.is_super_table(): raise KeyAlreadyPresent(key) elif isinstance(item, AoT): if not isinstance(current, AoT): @@ -173,7 +184,23 @@ def append(self, key, item): # type: (Union[Key, str], Item) -> Container else: return self._insert_at(0, key, item) - self._map[key] = len(self._body) + if key in self._map: + current_idx = self._map[key] + if isinstance(current_idx, tuple): + current_idx = current_idx[0] + + current = self._body[current_idx][1] + if key is not None and not isinstance(current, Table): + raise KeyAlreadyPresent(key) + + # Adding sub tables to a currently existing table + idx = self._map[key] + if not isinstance(idx, tuple): + idx = (idx,) + + self._map[key] = idx + (len(self._body),) + else: + self._map[key] = len(self._body) self._body.append((key, item)) @@ -190,12 +217,12 @@ def remove(self, key): # type: (Union[Key, str]) -> Container if idx is None: raise NonExistentKey(key) - old_data = self._body[idx][1] - trivia = getattr(old_data, "trivia", None) - if trivia and getattr(trivia, "comment", None): - self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) + if isinstance(idx, tuple): + for i in idx: + self._body[i] = (None, Null()) else: self._body[idx] = (None, Null()) + super(Container, self).__delitem__(key.key) return self @@ -224,7 +251,16 @@ def _insert_after( # Increment indices after the current index for k, v in self._map.items(): - if v > idx: + if isinstance(v, tuple): + new_indices = [] + for v_ in v: + if v_ > idx: + v_ = v_ + 1 + + new_indices.append(v_) + + self._map[k] = tuple(new_indices) + elif v > idx: self._map[k] = v + 1 self._map[other_key] = idx + 1 @@ -257,7 +293,16 @@ def _insert_at( # Increment indices after the current index for k, v in self._map.items(): - if v >= idx: + if isinstance(v, tuple): + new_indices = [] + for v_ in v: + if v_ >= idx: + v_ = v_ + 1 + + new_indices.append(v_) + + self._map[k] = tuple(new_indices) + elif v >= idx: self._map[k] = v + 1 self._map[key] = idx @@ -286,29 +331,7 @@ def as_string(self, prefix=None): # type: () -> str s = "" for k, v in self._body: if k is not None: - if False: - key = k.as_string() - - for _k, _v in v.value.body: - if _k is None: - s += v.as_string() - elif isinstance(_v, Table): - s += v.as_string(prefix=key) - else: - _key = key - if prefix is not None: - _key = prefix + "." + _key - - s += "{}{}{}{}{}{}{}".format( - _v.trivia.indent, - _key + "." + decode(_k.as_string()), - _k.sep, - decode(_v.as_string()), - _v.trivia.comment_ws, - decode(_v.trivia.comment), - _v.trivia.trail, - ) - elif isinstance(v, Table): + if isinstance(v, Table): s += self._render_table(k, v) elif isinstance(v, AoT): s += self._render_aot(k, v) @@ -332,7 +355,12 @@ def _render_table( if prefix is not None: _key = prefix + "." + _key - if not table.is_super_table(): + if not table.is_super_table() or ( + any( + not isinstance(v, (Table, AoT, Whitespace)) for _, v in table.value.body + ) + and not key.is_dotted() + ): open_, close = "[", "]" if table.is_aot_element(): open_, close = "[[", "]]" @@ -465,7 +493,7 @@ def __contains__(self, key): # type: (Union[Key, str]) -> bool return key in self._map - def __getitem__(self, key): # type: (Union[Key, str]) -> Item + def __getitem__(self, key): # type: (Union[Key, str]) -> Union[Item, Container] if not isinstance(key, Key): key = Key(key) @@ -473,6 +501,20 @@ def __getitem__(self, key): # type: (Union[Key, str]) -> Item if idx is None: raise NonExistentKey(key) + if isinstance(idx, tuple): + container = Container(True) + + for i in idx: + item = self._body[i][1] + + if isinstance(item, Table): + for k, v in item.value.body: + container.append(k, v) + else: + container.append(key, item) + + return container + item = self._body[idx][1] return item.value @@ -503,11 +545,20 @@ def _replace( def _replace_at( self, idx, new_key, value - ): # type: (int, Union[Key, str], Item) -> None + ): # type: (Union[int, Tuple[int]], Union[Key, str], Item) -> None + if isinstance(idx, tuple): + for i in idx[1:]: + self._body[i] = (None, Null()) + + idx = idx[0] + k, v = self._body[idx] self._map[new_key] = self._map.pop(k) + if isinstance(self._map[new_key], tuple): + self._map[new_key] = self._map[new_key][0] + value = _item(value) # Copying trivia @@ -517,6 +568,10 @@ def _replace_at( value.trivia.comment = v.trivia.comment value.trivia.trail = v.trivia.trail + if isinstance(value, Table): + # Insert a cosmetic new line for tables + value.append(None, Whitespace("\n")) + self._body[idx] = (new_key, value) super(Container, self).__setitem__(new_key.key, value.value) diff --git a/pipenv/vendor/tomlkit/exceptions.py b/pipenv/vendor/tomlkit/exceptions.py index 46ee938b45..4fbc667bdc 100644 --- a/pipenv/vendor/tomlkit/exceptions.py +++ b/pipenv/vendor/tomlkit/exceptions.py @@ -1,3 +1,6 @@ +from typing import Optional + + class TOMLKitError(Exception): pass @@ -23,6 +26,14 @@ def __init__( "{} at line {} col {}".format(message, self._line, self._col) ) + @property + def line(self): + return self._line + + @property + def col(self): + return self._col + class MixedArrayTypesError(ParseError): """ @@ -35,6 +46,50 @@ def __init__(self, line, col): # type: (int, int) -> None super(MixedArrayTypesError, self).__init__(line, col, message=message) +class InvalidNumberError(ParseError): + """ + A numeric field was improperly specified. + """ + + def __init__(self, line, col): # type: (int, int) -> None + message = "Invalid number" + + super(InvalidNumberError, self).__init__(line, col, message=message) + + +class InvalidDateTimeError(ParseError): + """ + A datetime field was improperly specified. + """ + + def __init__(self, line, col): # type: (int, int) -> None + message = "Invalid datetime" + + super(InvalidDateTimeError, self).__init__(line, col, message=message) + + +class InvalidDateError(ParseError): + """ + A date field was improperly specified. + """ + + def __init__(self, line, col): # type: (int, int) -> None + message = "Invalid date" + + super(InvalidDateError, self).__init__(line, col, message=message) + + +class InvalidTimeError(ParseError): + """ + A date field was improperly specified. + """ + + def __init__(self, line, col): # type: (int, int) -> None + message = "Invalid time" + + super(InvalidTimeError, self).__init__(line, col, message=message) + + class InvalidNumberOrDateError(ParseError): """ A numeric or date field was improperly specified. @@ -46,6 +101,17 @@ def __init__(self, line, col): # type: (int, int) -> None super(InvalidNumberOrDateError, self).__init__(line, col, message=message) +class InvalidUnicodeValueError(ParseError): + """ + A unicode code was improperly specified. + """ + + def __init__(self, line, col): # type: (int, int) -> None + message = "Invalid unicode value" + + super(InvalidUnicodeValueError, self).__init__(line, col, message=message) + + class UnexpectedCharError(ParseError): """ An unexpected character was found during parsing. @@ -106,7 +172,9 @@ class InternalParserError(ParseError): An error that indicates a bug in the parser. """ - def __init__(self, line, col, message=None): # type: (int, int) -> None + def __init__( + self, line, col, message=None + ): # type: (int, int, Optional[str]) -> None msg = "Internal parser error" if message: msg += " ({})".format(message) diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py index c3c2d59ff5..375b5f0251 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py @@ -6,14 +6,18 @@ from datetime import date from datetime import datetime from datetime import time -import sys -if sys.version_info >= (3, 4): - from enum import Enum -else: - from pipenv.vendor.backports.enum import Enum +from enum import Enum +from typing import Any +from typing import Dict +from typing import Generator +from typing import List +from typing import Optional +from typing import Union + from ._compat import PY2 from ._compat import decode +from ._compat import long from ._compat import unicode from ._utils import escape_string @@ -21,7 +25,6 @@ from pipenv.vendor.backports.functools_lru_cache import lru_cache else: from functools import lru_cache -from toml.decoder import InlineTableDict def item(value, _parent=None): @@ -37,10 +40,7 @@ def item(value, _parent=None): elif isinstance(value, float): return Float(value, Trivia(), str(value)) elif isinstance(value, dict): - if isinstance(value, InlineTableDict): - val = InlineTable(Container(), Trivia()) - else: - val = Table(Container(), Trivia(), False) + val = Table(Container(), Trivia(), False) for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): val[k] = item(v, _parent=val) @@ -124,6 +124,24 @@ def toggle(self): # type: () -> StringType }[self] +class BoolType(Enum): + TRUE = "true" + FALSE = "false" + + @lru_cache(maxsize=None) + def __bool__(self): + return {BoolType.TRUE: True, BoolType.FALSE: False}[self] + + if PY2: + __nonzero__ = __bool__ # for PY2 + + def __iter__(self): + return iter(self.value) + + def __len__(self): + return len(self.value) + + class Trivia: """ Trivia information (aka metadata). @@ -310,7 +328,7 @@ def __str__(self): # type: () -> str return "{}{}".format(self._trivia.indent, decode(self._trivia.comment)) -class Integer(int, Item): +class Integer(long, Item): """ An integer literal. """ @@ -449,10 +467,10 @@ class Bool(Item): A boolean literal. """ - def __init__(self, value, trivia): # type: (float, Trivia) -> None + def __init__(self, t, trivia): # type: (float, Trivia) -> None super(Bool, self).__init__(trivia) - self._value = value + self._value = bool(t) @property def discriminant(self): # type: () -> int @@ -747,10 +765,6 @@ def value(self): # type: () -> tomlkit.container.Container def discriminant(self): # type: () -> int return 9 - @property - def value(self): # type: () -> tomlkit.container.Container - return self._value - def add(self, key, item=None): # type: (Union[Key, Item, str], Any) -> Item if item is None: if not isinstance(key, (Comment, Whitespace)): @@ -924,6 +938,8 @@ def append(self, key, _item): # type: (Union[Key, str], Any) -> InlineTable if not isinstance(_item, (Whitespace, Comment)): if not _item.trivia.indent and len(self._value) > 0: _item.trivia.indent = " " + if _item.trivia.comment: + _item.trivia.comment = "" self._value.append(key, _item) @@ -1003,8 +1019,7 @@ def __setitem__(self, key, value): # type: (Union[Key, str], Any) -> None if key is not None: super(InlineTable, self).__setitem__(key, value) - - if hasattr(value, "trivia") and value.trivia.comment: + if value.trivia.comment: value.trivia.comment = "" m = re.match("(?s)^[^ ]*([ ]+).*$", self._trivia.indent) diff --git a/pipenv/vendor/tomlkit/parser.py b/pipenv/vendor/tomlkit/parser.py index 7971d9a27c..7b9483313f 100644 --- a/pipenv/vendor/tomlkit/parser.py +++ b/pipenv/vendor/tomlkit/parser.py @@ -1,24 +1,31 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -import datetime -import itertools import re import string -from copy import copy +from typing import Any +from typing import Generator +from typing import List +from typing import Optional +from typing import Tuple +from typing import Union -from ._compat import PY2 from ._compat import chr from ._compat import decode from ._utils import _escaped +from ._utils import RFC_3339_LOOSE from ._utils import parse_rfc3339 from .container import Container from .exceptions import EmptyKeyError from .exceptions import EmptyTableNameError from .exceptions import InternalParserError from .exceptions import InvalidCharInStringError -from .exceptions import InvalidNumberOrDateError +from .exceptions import InvalidDateTimeError +from .exceptions import InvalidDateError +from .exceptions import InvalidTimeError +from .exceptions import InvalidNumberError +from .exceptions import InvalidUnicodeValueError from .exceptions import MixedArrayTypesError from .exceptions import ParseError from .exceptions import UnexpectedCharError @@ -26,12 +33,14 @@ from .items import AoT from .items import Array from .items import Bool +from .items import BoolType from .items import Comment from .items import Date from .items import DateTime from .items import Float from .items import InlineTable from .items import Integer +from .items import Item from .items import Key from .items import KeyType from .items import Null @@ -41,6 +50,7 @@ from .items import Time from .items import Trivia from .items import Whitespace +from .source import Source from .toml_char import TOMLChar from .toml_document import TOMLDocument @@ -52,68 +62,69 @@ class Parser: def __init__(self, string): # type: (str) -> None # Input to parse - self._src = decode(string) # type: str - # Iterator used for getting characters from src. - self._chars = iter([(i, TOMLChar(c)) for i, c in enumerate(self._src)]) - # Current byte offset into src. - self._idx = 0 - # Current character - self._current = TOMLChar("") # type: TOMLChar - # Index into src between which and idx slices will be extracted - self._marker = 0 + self._src = Source(decode(string)) self._aot_stack = [] - self.inc() + @property + def _state(self): + return self._src.state + + @property + def _idx(self): + return self._src.idx + + @property + def _current(self): + return self._src.current + + @property + def _marker(self): + return self._src.marker def extract(self): # type: () -> str """ Extracts the value between marker and index """ - if self.end(): - return self._src[self._marker :] - else: - return self._src[self._marker : self._idx] + return self._src.extract() - def inc(self, exception=None): # type: () -> bool + def inc(self, exception=None): # type: (Optional[ParseError.__class__]) -> bool """ Increments the parser if the end of the input has not been reached. Returns whether or not it was able to advance. """ - try: - self._idx, self._current = next(self._chars) - - return True - except StopIteration: - self._idx = len(self._src) - self._current = TOMLChar("\0") - - if not exception: - return False - raise exception + return self._src.inc(exception=exception) - def inc_n(self, n, exception=None): # type: (int) -> bool + def inc_n(self, n, exception=None): # type: (int, Optional[ParseError]) -> bool """ Increments the parser by n characters if the end of the input has not been reached. """ - for _ in range(n): - if not self.inc(exception=exception): - return False + return self._src.inc_n(n=n, exception=exception) - return True + def consume(self, chars, min=0, max=-1): + """ + Consume chars until min/max is satisfied is valid. + """ + return self._src.consume(chars=chars, min=min, max=max) def end(self): # type: () -> bool """ Returns True if the parser has reached the end of the input. """ - return self._idx >= len(self._src) or self._current == "\0" + return self._src.end() def mark(self): # type: () -> None """ Sets the marker to the index's current position """ - self._marker = self._idx + self._src.mark() + + def parse_error(self, exception=ParseError, *args): + """ + Creates a generic "parse error" at the current position. + """ + return self._src.parse_error(exception, *args) def parse(self): # type: () -> TOMLDocument body = TOMLDocument(True) @@ -173,27 +184,6 @@ def _merge_ws(self, item, container): # type: (Item, Container) -> bool return True - def parse_error(self, kind=ParseError, args=None): # type: () -> None - """ - Creates a generic "parse error" at the current position. - """ - line, col = self._to_linecol(self._idx) - - if args: - return kind(line, col, *args) - else: - return kind(line, col) - - def _to_linecol(self, offset): # type: (int) -> Tuple[int, int] - cur = 0 - for i, line in enumerate(self._src.splitlines()): - if cur + len(line) + 1 > offset: - return (i + 1, offset - cur) - - cur += len(line) + 1 - - return len(self._src.splitlines()), 0 - def _is_child(self, parent, child): # type: (str, str) -> bool """ Returns whether a key is strictly a child of another key. @@ -256,55 +246,35 @@ def _parse_item(self): # type: () -> Optional[Tuple[Optional[Key], Item]] if the item is value-like. """ self.mark() - saved_idx = self._save_idx() - - while True: - c = self._current - if c == "\n": - # Found a newline; Return all whitespace found up to this point. - self.inc() - - return (None, Whitespace(self.extract())) - elif c in " \t\r": - # Skip whitespace. - if not self.inc(): - return (None, Whitespace(self.extract())) - elif c == "#": - # Found a comment, parse it - indent = self.extract() - cws, comment, trail = self._parse_comment_trail() - - return (None, Comment(Trivia(indent, cws, comment, trail))) - elif c == "[": - # Found a table, delegate to the calling function. - return - else: - # Begining of a KV pair. - # Return to beginning of whitespace so it gets included - # as indentation for the KV about to be parsed. - self._restore_idx(*saved_idx) - key, value = self._parse_key_value(True) - - return key, value - - def _save_idx(self): # type: () -> Tuple[Iterator, int, str] - if PY2: - # Python 2.7 does not allow to directly copy - # an iterator, so we have to make tees of the original - # chars iterator. - chars1, chars2 = itertools.tee(self._chars) - - # We can no longer use the original chars iterator. - self._chars = chars1 + with self._state as state: + while True: + c = self._current + if c == "\n": + # Found a newline; Return all whitespace found up to this point. + self.inc() - return chars2, self._idx, self._current + return None, Whitespace(self.extract()) + elif c in " \t\r": + # Skip whitespace. + if not self.inc(): + return None, Whitespace(self.extract()) + elif c == "#": + # Found a comment, parse it + indent = self.extract() + cws, comment, trail = self._parse_comment_trail() - return copy(self._chars), self._idx, self._current + return None, Comment(Trivia(indent, cws, comment, trail)) + elif c == "[": + # Found a table, delegate to the calling function. + return + else: + # Begining of a KV pair. + # Return to beginning of whitespace so it gets included + # as indentation for the KV about to be parsed. + state.restore = True + break - def _restore_idx(self, chars, idx, current): # type: (Iterator, int, str) -> None - self._chars = chars - self._idx = idx - self._current = current + return self._parse_key_value(True) def _parse_comment_trail(self): # type: () -> Tuple[str, str, str] """ @@ -341,7 +311,7 @@ def _parse_comment_trail(self): # type: () -> Tuple[str, str, str] elif c in " \t\r": self.inc() else: - raise self.parse_error(UnexpectedCharError, (c)) + raise self.parse_error(UnexpectedCharError, c) if self.end(): break @@ -361,9 +331,7 @@ def _parse_comment_trail(self): # type: () -> Tuple[str, str, str] return comment_ws, comment, trail - def _parse_key_value( - self, parse_comment=False, inline=True - ): # type: (bool, bool) -> (Key, Item) + def _parse_key_value(self, parse_comment=False): # type: (bool) -> (Key, Item) # Leading indent self.mark() @@ -383,7 +351,7 @@ def _parse_key_value( while self._current.is_kv_sep() and self.inc(): if self._current == "=": if found_equals: - raise self.parse_error(UnexpectedCharError, ("=",)) + raise self.parse_error(UnexpectedCharError, "=") else: found_equals = True pass @@ -473,7 +441,7 @@ def _parse_bare_key(self): # type: () -> Key def _handle_dotted_key( self, container, key, value - ): # type: (Container, Key) -> None + ): # type: (Container, Key, Any) -> None names = tuple(self._split_table_name(key.key)) name = names[0] name._dotted = True @@ -510,119 +478,199 @@ def _parse_value(self): # type: () -> Item Attempts to parse a value at the current position. """ self.mark() + c = self._current trivia = Trivia() - c = self._current - if c == '"': + if c == StringType.SLB.value: return self._parse_basic_string() - elif c == "'": + elif c == StringType.SLL.value: return self._parse_literal_string() - elif c == "t" and self._src[self._idx :].startswith("true"): - # Boolean: true - self.inc_n(4) + elif c == BoolType.TRUE.value[0]: + return self._parse_true() + elif c == BoolType.FALSE.value[0]: + return self._parse_false() + elif c == "[": + return self._parse_array() + elif c == "{": + return self._parse_inline_table() + elif c in "+-" or self._peek(4) in { + "+inf", + "-inf", + "inf", + "+nan", + "-nan", + "nan", + }: + # Number + while self._current not in " \t\n\r#,]}" and self.inc(): + pass - return Bool(True, trivia) - elif c == "f" and self._src[self._idx :].startswith("false"): - # Boolean: true - self.inc_n(5) + raw = self.extract() - return Bool(False, trivia) - elif c == "[": - # Array - elems = [] # type: List[Item] - self.inc() + item = self._parse_number(raw, trivia) + if item is not None: + return item - while self._current != "]": - self.mark() - while self._current.is_ws() or self._current == ",": - self.inc() + raise self.parse_error(InvalidNumberError) + elif c in string.digits: + # Integer, Float, Date, Time or DateTime + while self._current not in " \t\n\r#,]}" and self.inc(): + pass - if self._idx != self._marker: - elems.append(Whitespace(self.extract())) + raw = self.extract() - if self._current == "]": - break + m = RFC_3339_LOOSE.match(raw) + if m: + if m.group(1) and m.group(5): + # datetime + try: + return DateTime(parse_rfc3339(raw), trivia, raw) + except ValueError: + raise self.parse_error(InvalidDateTimeError) + + if m.group(1): + try: + return Date(parse_rfc3339(raw), trivia, raw) + except ValueError: + raise self.parse_error(InvalidDateError) + + if m.group(5): + try: + return Time(parse_rfc3339(raw), trivia, raw) + except ValueError: + raise self.parse_error(InvalidTimeError) - if self._current == "#": - cws, comment, trail = self._parse_comment_trail() + item = self._parse_number(raw, trivia) + if item is not None: + return item - next_ = Comment(Trivia("", cws, comment, trail)) - else: - next_ = self._parse_value() + raise self.parse_error(InvalidNumberError) + else: + raise self.parse_error(UnexpectedCharError, c) - elems.append(next_) + def _parse_true(self): + return self._parse_bool(BoolType.TRUE) - self.inc() + def _parse_false(self): + return self._parse_bool(BoolType.FALSE) - try: - res = Array(elems, trivia) - except ValueError: - raise self.parse_error(MixedArrayTypesError) + def _parse_bool(self, style): # type: (BoolType) -> Bool + with self._state: + style = BoolType(style) - if res.is_homogeneous(): - return res + # only keep parsing for bool if the characters match the style + # try consuming rest of chars in style + for c in style: + self.consume(c, min=1, max=1) - raise self.parse_error(MixedArrayTypesError) - elif c == "{": - # Inline table - elems = Container(True) - self.inc() + return Bool(style, Trivia()) - while self._current != "}": - self.mark() - while self._current.is_spaces() or self._current == ",": - self.inc() + def _parse_array(self): # type: () -> Array + # Consume opening bracket, EOF here is an issue (middle of array) + self.inc(exception=UnexpectedEofError) - if self._idx != self._marker: - ws = self.extract().lstrip(",") - if ws: - elems.append(None, Whitespace(ws)) + elems = [] # type: List[Item] + prev_value = None + while True: + # consume whitespace + mark = self._idx + self.consume(TOMLChar.SPACES) + newline = self.consume(TOMLChar.NL) + indent = self._src[mark : self._idx] + if newline: + elems.append(Whitespace(indent)) + continue - if self._current == "}": - break + # consume comment + if self._current == "#": + cws, comment, trail = self._parse_comment_trail() + elems.append(Comment(Trivia(indent, cws, comment, trail))) + continue - key, val = self._parse_key_value(False, inline=True) - elems.append(key, val) + # consume indent + if indent: + elems.append(Whitespace(indent)) + continue - self.inc() + # consume value + if not prev_value: + try: + elems.append(self._parse_value()) + prev_value = True + continue + except UnexpectedCharError: + pass - return InlineTable(elems, trivia) - elif c in string.digits + "+-" or self._peek(4) in { - "+inf", - "-inf", - "inf", - "+nan", - "-nan", - "nan", - }: - # Integer, Float, Date, Time or DateTime - while self._current not in " \t\n\r#,]}" and self.inc(): - pass + # consume comma + if prev_value and self._current == ",": + self.inc(exception=UnexpectedEofError) + elems.append(Whitespace(",")) + prev_value = False + continue - raw = self.extract() + # consume closing bracket + if self._current == "]": + # consume closing bracket, EOF here doesn't matter + self.inc() + break - item = self._parse_number(raw, trivia) - if item is not None: - return item + raise self.parse_error(UnexpectedCharError, self._current) - try: - res = parse_rfc3339(raw) - except ValueError: - res = None + try: + res = Array(elems, Trivia()) + except ValueError: + pass + else: + if res.is_homogeneous(): + return res - if res is None: - raise self.parse_error(InvalidNumberOrDateError) + raise self.parse_error(MixedArrayTypesError) + + def _parse_inline_table(self): # type: () -> InlineTable + # consume opening bracket, EOF here is an issue (middle of array) + self.inc(exception=UnexpectedEofError) - if isinstance(res, datetime.datetime): - return DateTime(res, trivia, raw) - elif isinstance(res, datetime.time): - return Time(res, trivia, raw) - elif isinstance(res, datetime.date): - return Date(res, trivia, raw) + elems = Container(True) + trailing_comma = None + while True: + # consume leading whitespace + mark = self._idx + self.consume(TOMLChar.SPACES) + raw = self._src[mark : self._idx] + if raw: + elems.add(Whitespace(raw)) + + if not trailing_comma: + # None: empty inline table + # False: previous key-value pair was not followed by a comma + if self._current == "}": + # consume closing bracket, EOF here doesn't matter + self.inc() + break + if trailing_comma is False: + raise self.parse_error(UnexpectedCharError, self._current) else: - raise self.parse_error(InvalidNumberOrDateError) - else: - raise self.parse_error(UnexpectedCharError, (c)) + # True: previous key-value pair was followed by a comma + if self._current == "}": + raise self.parse_error(UnexpectedCharError, self._current) + + key, val = self._parse_key_value(False) + elems.add(key, val) + + # consume trailing whitespace + mark = self._idx + self.consume(TOMLChar.SPACES) + raw = self._src[mark : self._idx] + if raw: + elems.add(Whitespace(raw)) + + # consume trailing comma + trailing_comma = self._current == "," + if trailing_comma: + # consume closing bracket, EOF here is an issue (middle of inline table) + self.inc(exception=UnexpectedEofError) + + return InlineTable(elems, Trivia()) def _parse_number(self, raw, trivia): # type: (str, Trivia) -> Optional[Item] # Leading zeros are not allowed @@ -670,11 +718,13 @@ def _parse_number(self, raw, trivia): # type: (str, Trivia) -> Optional[Item] except ValueError: return - def _parse_literal_string(self): # type: () -> Item - return self._parse_string(StringType.SLL) + def _parse_literal_string(self): # type: () -> String + with self._state: + return self._parse_string(StringType.SLL) - def _parse_basic_string(self): # type: () -> Item - return self._parse_string(StringType.SLB) + def _parse_basic_string(self): # type: () -> String + with self._state: + return self._parse_string(StringType.SLB) def _parse_escaped_char(self, multiline): if multiline and self._current.is_ws(): @@ -696,7 +746,7 @@ def _parse_escaped_char(self, multiline): # the escape followed by whitespace must have a newline # before any other chars if "\n" not in tmp: - raise self.parse_error(InvalidCharInStringError, (self._current,)) + raise self.parse_error(InvalidCharInStringError, self._current) return "" @@ -717,15 +767,17 @@ def _parse_escaped_char(self, multiline): return u - raise self.parse_error(InvalidCharInStringError, (self._current,)) + raise self.parse_error(InvalidUnicodeValueError) - def _parse_string(self, delim): # type: (str) -> Item - delim = StringType(delim) - assert delim.is_singleline() + raise self.parse_error(InvalidCharInStringError, self._current) + def _parse_string(self, delim): # type: (StringType) -> String # only keep parsing for string if the current character matches the delim if self._current != delim.unit: - raise ValueError("Expecting a {!r} character".format(delim)) + raise self.parse_error( + InternalParserError, + "Invalid character for string type {}".format(delim), + ) # consume the opening/first delim, EOF here is an issue # (middle of string or middle of delim) @@ -755,7 +807,7 @@ def _parse_string(self, delim): # type: (str) -> Item while True: if delim.is_singleline() and self._current.is_nl(): # single line cannot have actual newline characters - raise self.parse_error(InvalidCharInStringError, (self._current,)) + raise self.parse_error(InvalidCharInStringError, self._current) elif not escaped and self._current == delim.unit: # try to process current as a closing delim original = self.extract() @@ -781,8 +833,6 @@ def _parse_string(self, delim): # type: (str) -> Item if not close: # if there is no close characters, keep parsing continue else: - close = delim.unit - # consume the closing delim, we do not care if EOF occurs as # that would simply imply the end of self._src self.inc() @@ -817,8 +867,7 @@ def _parse_table( """ if self._current != "[": raise self.parse_error( - InternalParserError, - ("_parse_table() called on non-bracket character.",), + InternalParserError, "_parse_table() called on non-bracket character." ) indent = self.extract() @@ -945,7 +994,7 @@ def _parse_table( else: raise self.parse_error( InternalParserError, - ("_parse_item() returned None on a non-bracket character.",), + "_parse_item() returned None on a non-bracket character.", ) if isinstance(result, Null): @@ -970,32 +1019,27 @@ def _peek_table(self): # type: () -> Tuple[bool, str] Returns the name of the table about to be parsed, as well as whether it is part of an AoT. """ - # Save initial state - idx = self._save_idx() - marker = self._marker - - if self._current != "[": - raise self.parse_error( - InternalParserError, ("_peek_table() entered on non-bracket character",) - ) + # we always want to restore after exiting this scope + with self._state(save_marker=True, restore=True): + if self._current != "[": + raise self.parse_error( + InternalParserError, + "_peek_table() entered on non-bracket character", + ) - # AoT - self.inc() - is_aot = False - if self._current == "[": + # AoT self.inc() - is_aot = True - - self.mark() + is_aot = False + if self._current == "[": + self.inc() + is_aot = True - while self._current != "]" and self.inc(): - table_name = self.extract() + self.mark() - # Restore initial state - self._restore_idx(*idx) - self._marker = marker + while self._current != "]" and self.inc(): + table_name = self.extract() - return is_aot, table_name + return is_aot, table_name def _parse_aot(self, first, name_first): # type: (Table, str) -> AoT """ @@ -1022,57 +1066,53 @@ def _peek(self, n): # type: (int) -> str n is the max number of characters that will be peeked. """ - idx = self._save_idx() - buf = "" - for _ in range(n): - if self._current not in " \t\n\r#,]}": - buf += self._current - self.inc() - continue - - break - - self._restore_idx(*idx) + # we always want to restore after exiting this scope + with self._state(restore=True): + buf = "" + for _ in range(n): + if self._current not in " \t\n\r#,]}": + buf += self._current + self.inc() + continue - return buf + break + return buf - def _peek_unicode(self, is_long): # type: () -> Tuple[bool, str] + def _peek_unicode( + self, is_long + ): # type: (bool) -> Tuple[Optional[str], Optional[str]] """ Peeks ahead non-intrusively by cloning then restoring the initial state of the parser. Returns the unicode value is it's a valid one else None. """ - # Save initial state - idx = self._save_idx() - marker = self._marker - - if self._current not in {"u", "U"}: - raise self.parse_error( - InternalParserError, ("_peek_unicode() entered on non-unicode value") - ) + # we always want to restore after exiting this scope + with self._state(save_marker=True, restore=True): + if self._current not in {"u", "U"}: + raise self.parse_error( + InternalParserError, "_peek_unicode() entered on non-unicode value" + ) - # AoT - self.inc() # Dropping prefix - self.mark() + self.inc() # Dropping prefix + self.mark() - if is_long: - chars = 8 - else: - chars = 4 + if is_long: + chars = 8 + else: + chars = 4 - if not self.inc_n(chars): - value, extracted = None, None - else: - extracted = self.extract() + if not self.inc_n(chars): + value, extracted = None, None + else: + extracted = self.extract() - try: - value = chr(int(extracted, 16)) - except ValueError: - value = None + if extracted[0].lower() == "d" and extracted[1].strip("01234567"): + return None, None - # Restore initial state - self._restore_idx(*idx) - self._marker = marker + try: + value = chr(int(extracted, 16)) + except ValueError: + value = None - return value, extracted + return value, extracted diff --git a/pipenv/vendor/tomlkit/source.py b/pipenv/vendor/tomlkit/source.py new file mode 100644 index 0000000000..1a96e05893 --- /dev/null +++ b/pipenv/vendor/tomlkit/source.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import itertools + +from copy import copy +from typing import Optional +from typing import Tuple + +from ._compat import PY2 +from ._compat import unicode +from .exceptions import UnexpectedEofError +from .exceptions import UnexpectedCharError +from .exceptions import ParseError +from .toml_char import TOMLChar + + +class _State: + def __init__( + self, source, save_marker=False, restore=False + ): # type: (_Source, Optional[bool], Optional[bool]) -> None + self._source = source + self._save_marker = save_marker + self.restore = restore + + def __enter__(self): # type: () -> None + # Entering this context manager - save the state + if PY2: + # Python 2.7 does not allow to directly copy + # an iterator, so we have to make tees of the original + # chars iterator. + self._source._chars, self._chars = itertools.tee(self._source._chars) + else: + self._chars = copy(self._source._chars) + self._idx = self._source._idx + self._current = self._source._current + self._marker = self._source._marker + + return self + + def __exit__(self, exception_type, exception_val, trace): + # Exiting this context manager - restore the prior state + if self.restore or exception_type: + self._source._chars = self._chars + self._source._idx = self._idx + self._source._current = self._current + if self._save_marker: + self._source._marker = self._marker + + # Restore exceptions are silently consumed, other exceptions need to + # propagate + return exception_type is None + + +class _StateHandler: + """ + State preserver for the Parser. + """ + + def __init__(self, source): # type: (Source) -> None + self._source = source + self._states = [] + + def __call__(self, *args, **kwargs): + return _State(self._source, *args, **kwargs) + + def __enter__(self): # type: () -> None + state = self() + self._states.append(state) + return state.__enter__() + + def __exit__(self, exception_type, exception_val, trace): + state = self._states.pop() + return state.__exit__(exception_type, exception_val, trace) + + +class Source(unicode): + EOF = TOMLChar("\0") + + def __init__(self, _): # type: (unicode) -> None + super(Source, self).__init__() + + # Collection of TOMLChars + self._chars = iter([(i, TOMLChar(c)) for i, c in enumerate(self)]) + + self._idx = 0 + self._marker = 0 + self._current = TOMLChar("") + + self._state = _StateHandler(self) + + self.inc() + + def reset(self): + # initialize both idx and current + self.inc() + + # reset marker + self.mark() + + @property + def state(self): # type: () -> _StateHandler + return self._state + + @property + def idx(self): # type: () -> int + return self._idx + + @property + def current(self): # type: () -> TOMLChar + return self._current + + @property + def marker(self): # type: () -> int + return self._marker + + def extract(self): # type: () -> unicode + """ + Extracts the value between marker and index + """ + return self[self._marker : self._idx] + + def inc(self, exception=None): # type: (Optional[ParseError.__class__]) -> bool + """ + Increments the parser if the end of the input has not been reached. + Returns whether or not it was able to advance. + """ + try: + self._idx, self._current = next(self._chars) + + return True + except StopIteration: + self._idx = len(self) + self._current = self.EOF + if exception: + raise self.parse_error(exception) + + return False + + def inc_n(self, n, exception=None): # type: (int, Exception) -> bool + """ + Increments the parser by n characters + if the end of the input has not been reached. + """ + for _ in range(n): + if not self.inc(exception=exception): + return False + + return True + + def consume(self, chars, min=0, max=-1): + """ + Consume chars until min/max is satisfied is valid. + """ + while self.current in chars and max != 0: + min -= 1 + max -= 1 + if not self.inc(): + break + + # failed to consume minimum number of characters + if min > 0: + self.parse_error(UnexpectedCharError) + + def end(self): # type: () -> bool + """ + Returns True if the parser has reached the end of the input. + """ + return self._current is self.EOF + + def mark(self): # type: () -> None + """ + Sets the marker to the index's current position + """ + self._marker = self._idx + + def parse_error( + self, exception=ParseError, *args + ): # type: (ParseError.__class__, ...) -> ParseError + """ + Creates a generic "parse error" at the current position. + """ + line, col = self._to_linecol() + + return exception(line, col, *args) + + def _to_linecol(self): # type: () -> Tuple[int, int] + cur = 0 + for i, line in enumerate(self.splitlines()): + if cur + len(line) + 1 > self.idx: + return (i + 1, self.idx - cur) + + cur += len(line) + 1 + + return len(self.splitlines()), 0 diff --git a/pipenv/vendor/tomlkit/toml_char.py b/pipenv/vendor/tomlkit/toml_char.py index 5164ea8b2a..02c5517289 100644 --- a/pipenv/vendor/tomlkit/toml_char.py +++ b/pipenv/vendor/tomlkit/toml_char.py @@ -16,44 +16,51 @@ def __init__(self, c): if len(self) > 1: raise ValueError("A TOML character must be of length 1") + BARE = string.ascii_letters + string.digits + "-_" + KV = "= \t" + NUMBER = string.digits + "+-_.e" + SPACES = " \t" + NL = "\n\r" + WS = SPACES + NL + @lru_cache(maxsize=None) def is_bare_key_char(self): # type: () -> bool """ Whether the character is a valid bare key name or not. """ - return self in string.ascii_letters + string.digits + "-" + "_" + return self in self.BARE @lru_cache(maxsize=None) def is_kv_sep(self): # type: () -> bool """ Whether the character is a valid key/value separator ot not. """ - return self in "= \t" + return self in self.KV @lru_cache(maxsize=None) def is_int_float_char(self): # type: () -> bool """ Whether the character if a valid integer or float value character or not. """ - return self in string.digits + "+" + "-" + "_" + "." + "e" + return self in self.NUMBER @lru_cache(maxsize=None) def is_ws(self): # type: () -> bool """ Whether the character is a whitespace character or not. """ - return self in " \t\r\n" + return self in self.WS @lru_cache(maxsize=None) def is_nl(self): # type: () -> bool """ Whether the character is a new line character or not. """ - return self in "\n\r" + return self in self.NL @lru_cache(maxsize=None) def is_spaces(self): # type: () -> bool """ Whether the character is a space or not """ - return self in " \t" + return self in self.SPACES diff --git a/pipenv/vendor/tomlkit/toml_file.py b/pipenv/vendor/tomlkit/toml_file.py index 631e995958..3b416664dd 100644 --- a/pipenv/vendor/tomlkit/toml_file.py +++ b/pipenv/vendor/tomlkit/toml_file.py @@ -1,5 +1,8 @@ import io +from typing import Any +from typing import Dict + from .api import loads from .toml_document import TOMLDocument diff --git a/pipenv/vendor/vendor.txt b/pipenv/vendor/vendor.txt index 45ff0384c0..3228068f84 100644 --- a/pipenv/vendor/vendor.txt +++ b/pipenv/vendor/vendor.txt @@ -51,3 +51,4 @@ git+https://github.com/sarugaku/passa.git@master#egg=passa cursor==1.2.0 resolvelib==0.2.2 backports.functools_lru_cache==1.5 +tomlkit \ No newline at end of file From 1f7c9ef949e7d68b6dd642158ee35772614cb2e0 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Sat, 10 Nov 2018 12:48:26 +0800 Subject: [PATCH 12/14] update patch --- pipenv/utils.py | 7 +- pipenv/vendor/tomlkit/api.py | 2 - pipenv/vendor/tomlkit/container.py | 16 +- pipenv/vendor/tomlkit/exceptions.py | 2 - pipenv/vendor/tomlkit/items.py | 13 +- pipenv/vendor/tomlkit/parser.py | 7 - pipenv/vendor/tomlkit/source.py | 2 - pipenv/vendor/tomlkit/toml_file.py | 3 - pipenv/vendor/vendor.txt | 3 +- .../vendor/tomlkit-dump-inline-table.patch | 34 ----- .../patches/vendor/tomlkit-fix.patch | 144 ++++++++++++++++++ .../vendor/tomlkit-typing-imports.patch | 93 ----------- .../patches/vendor/tomlkit-update-items.patch | 27 ---- 13 files changed, 158 insertions(+), 195 deletions(-) delete mode 100644 tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch create mode 100644 tasks/vendoring/patches/vendor/tomlkit-fix.patch delete mode 100644 tasks/vendoring/patches/vendor/tomlkit-typing-imports.patch delete mode 100644 tasks/vendoring/patches/vendor/tomlkit-update-items.patch diff --git a/pipenv/utils.py b/pipenv/utils.py index 9d495fa367..9a74b2b94d 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -102,19 +102,14 @@ def convert_toml_outline_tables(parsed): else: empty_inline_table = toml.TomlDecoder().get_empty_inline_table for section in ("packages", "dev-packages"): - has_outline_table = False - table_data = parsed.get(section, {}).copy() + table_data = parsed.get(section, {}) for package, value in table_data.items(): if hasattr(value, "keys") and not isinstance( value, (tomlkit.items.InlineTable, toml.decoder.InlineTableDict) ): - has_outline_table = True table = empty_inline_table() table.update(value) table_data[package] = table - if has_outline_table: - # We'll lose comments here, only update when necessary - parsed[section] = table_data return parsed diff --git a/pipenv/vendor/tomlkit/api.py b/pipenv/vendor/tomlkit/api.py index e541c20c17..0ac2675262 100644 --- a/pipenv/vendor/tomlkit/api.py +++ b/pipenv/vendor/tomlkit/api.py @@ -1,7 +1,5 @@ import datetime as _datetime -from typing import Tuple - from ._utils import parse_rfc3339 from .container import Container from .items import AoT diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py index cb8af1d522..9b5db5cb66 100644 --- a/pipenv/vendor/tomlkit/container.py +++ b/pipenv/vendor/tomlkit/container.py @@ -1,13 +1,5 @@ from __future__ import unicode_literals -from typing import Any -from typing import Dict -from typing import Generator -from typing import List -from typing import Optional -from typing import Tuple -from typing import Union - from ._compat import decode from .exceptions import KeyAlreadyPresent from .exceptions import NonExistentKey @@ -17,6 +9,7 @@ from .items import Key from .items import Null from .items import Table +from .items import Trivia from .items import Whitespace from .items import item as _item @@ -221,7 +214,12 @@ def remove(self, key): # type: (Union[Key, str]) -> Container for i in idx: self._body[i] = (None, Null()) else: - self._body[idx] = (None, Null()) + old_data = self._body[idx][1] + trivia = getattr(old_data, "trivia", None) + if trivia and trivia.comment: + self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) + else: + self._body[idx] = (None, Null()) super(Container, self).__delitem__(key.key) diff --git a/pipenv/vendor/tomlkit/exceptions.py b/pipenv/vendor/tomlkit/exceptions.py index 4fbc667bdc..c1a4e620e0 100644 --- a/pipenv/vendor/tomlkit/exceptions.py +++ b/pipenv/vendor/tomlkit/exceptions.py @@ -1,5 +1,3 @@ -from typing import Optional - class TOMLKitError(Exception): diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py index 375b5f0251..7035b69ecc 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py @@ -7,13 +7,6 @@ from datetime import datetime from datetime import time from enum import Enum -from typing import Any -from typing import Dict -from typing import Generator -from typing import List -from typing import Optional -from typing import Union - from ._compat import PY2 from ._compat import decode @@ -25,6 +18,7 @@ from pipenv.vendor.backports.functools_lru_cache import lru_cache else: from functools import lru_cache +from toml.decoder import InlineTableDict def item(value, _parent=None): @@ -40,7 +34,10 @@ def item(value, _parent=None): elif isinstance(value, float): return Float(value, Trivia(), str(value)) elif isinstance(value, dict): - val = Table(Container(), Trivia(), False) + if isinstance(value, InlineTableDict): + val = InlineTable(Container(), Trivia()) + else: + val = Table(Container(), Trivia(), False) for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): val[k] = item(v, _parent=val) diff --git a/pipenv/vendor/tomlkit/parser.py b/pipenv/vendor/tomlkit/parser.py index 7b9483313f..3f507bb4ca 100644 --- a/pipenv/vendor/tomlkit/parser.py +++ b/pipenv/vendor/tomlkit/parser.py @@ -4,13 +4,6 @@ import re import string -from typing import Any -from typing import Generator -from typing import List -from typing import Optional -from typing import Tuple -from typing import Union - from ._compat import chr from ._compat import decode from ._utils import _escaped diff --git a/pipenv/vendor/tomlkit/source.py b/pipenv/vendor/tomlkit/source.py index 1a96e05893..dcfdafd0a5 100644 --- a/pipenv/vendor/tomlkit/source.py +++ b/pipenv/vendor/tomlkit/source.py @@ -4,8 +4,6 @@ import itertools from copy import copy -from typing import Optional -from typing import Tuple from ._compat import PY2 from ._compat import unicode diff --git a/pipenv/vendor/tomlkit/toml_file.py b/pipenv/vendor/tomlkit/toml_file.py index 3b416664dd..631e995958 100644 --- a/pipenv/vendor/tomlkit/toml_file.py +++ b/pipenv/vendor/tomlkit/toml_file.py @@ -1,8 +1,5 @@ import io -from typing import Any -from typing import Dict - from .api import loads from .toml_document import TOMLDocument diff --git a/pipenv/vendor/vendor.txt b/pipenv/vendor/vendor.txt index 3228068f84..9924810eed 100644 --- a/pipenv/vendor/vendor.txt +++ b/pipenv/vendor/vendor.txt @@ -34,7 +34,7 @@ requirementslib==1.2.5 pyparsing==2.2.2 pytoml==0.1.19 plette==0.2.2 - tomlkit==0.4.6 + tomlkit==0.5.2 shellingham==1.2.7 six==1.11.0 semver==2.8.1 @@ -51,4 +51,3 @@ git+https://github.com/sarugaku/passa.git@master#egg=passa cursor==1.2.0 resolvelib==0.2.2 backports.functools_lru_cache==1.5 -tomlkit \ No newline at end of file diff --git a/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch b/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch deleted file mode 100644 index 8cd6d5cafb..0000000000 --- a/tasks/vendoring/patches/vendor/tomlkit-dump-inline-table.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py -index 781e2e98..c3c2d59f 100644 ---- a/pipenv/vendor/tomlkit/items.py -+++ b/pipenv/vendor/tomlkit/items.py -@@ -21,6 +21,7 @@ if PY2: - from pipenv.vendor.backports.functools_lru_cache import lru_cache - else: - from functools import lru_cache -+from toml.decoder import InlineTableDict - - - def item(value, _parent=None): -@@ -36,7 +37,10 @@ def item(value, _parent=None): - elif isinstance(value, float): - return Float(value, Trivia(), str(value)) - elif isinstance(value, dict): -- val = Table(Container(), Trivia(), False) -+ if isinstance(value, InlineTableDict): -+ val = InlineTable(Container(), Trivia()) -+ else: -+ val = Table(Container(), Trivia(), False) - for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): - val[k] = item(v, _parent=val) - -@@ -1000,6 +1004,9 @@ class InlineTable(Item, dict): - if key is not None: - super(InlineTable, self).__setitem__(key, value) - -+ if hasattr(value, "trivia") and value.trivia.comment: -+ value.trivia.comment = "" -+ - m = re.match("(?s)^[^ ]*([ ]+).*$", self._trivia.indent) - if not m: - return diff --git a/tasks/vendoring/patches/vendor/tomlkit-fix.patch b/tasks/vendoring/patches/vendor/tomlkit-fix.patch new file mode 100644 index 0000000000..5dd9d3fe1e --- /dev/null +++ b/tasks/vendoring/patches/vendor/tomlkit-fix.patch @@ -0,0 +1,144 @@ +diff --git a/pipenv/vendor/tomlkit/api.py b/pipenv/vendor/tomlkit/api.py +index e541c20c..0ac26752 100644 +--- a/pipenv/vendor/tomlkit/api.py ++++ b/pipenv/vendor/tomlkit/api.py +@@ -1,7 +1,5 @@ + import datetime as _datetime + +-from typing import Tuple +- + from ._utils import parse_rfc3339 + from .container import Container + from .items import AoT +diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py +index cb8af1d5..56ee2d62 100644 +--- a/pipenv/vendor/tomlkit/container.py ++++ b/pipenv/vendor/tomlkit/container.py +@@ -1,13 +1,5 @@ + from __future__ import unicode_literals + +-from typing import Any +-from typing import Dict +-from typing import Generator +-from typing import List +-from typing import Optional +-from typing import Tuple +-from typing import Union +- + from ._compat import decode + from .exceptions import KeyAlreadyPresent + from .exceptions import NonExistentKey +@@ -17,6 +9,7 @@ from .items import Item + from .items import Key + from .items import Null + from .items import Table ++from .items import Trivia + from .items import Whitespace + from .items import item as _item + +@@ -221,7 +214,12 @@ class Container(dict): + for i in idx: + self._body[i] = (None, Null()) + else: +- self._body[idx] = (None, Null()) ++ old_data = self._body[idx][1] ++ trivia = getattr(old_data, "trivia", None) ++ if trivia and trivia.comment: ++ self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) ++ else: ++ self._body[idx] = (None, Null()) + + super(Container, self).__delitem__(key.key) + +diff --git a/pipenv/vendor/tomlkit/exceptions.py b/pipenv/vendor/tomlkit/exceptions.py +index 4fbc667b..c1a4e620 100644 +--- a/pipenv/vendor/tomlkit/exceptions.py ++++ b/pipenv/vendor/tomlkit/exceptions.py +@@ -1,5 +1,3 @@ +-from typing import Optional +- + + class TOMLKitError(Exception): + +diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py +index 375b5f02..7035b69e 100644 +--- a/pipenv/vendor/tomlkit/items.py ++++ b/pipenv/vendor/tomlkit/items.py +@@ -7,13 +7,6 @@ from datetime import date + from datetime import datetime + from datetime import time + from enum import Enum +-from typing import Any +-from typing import Dict +-from typing import Generator +-from typing import List +-from typing import Optional +-from typing import Union +- + + from ._compat import PY2 + from ._compat import decode +@@ -25,6 +18,7 @@ if PY2: + from pipenv.vendor.backports.functools_lru_cache import lru_cache + else: + from functools import lru_cache ++from toml.decoder import InlineTableDict + + + def item(value, _parent=None): +@@ -40,7 +34,10 @@ def item(value, _parent=None): + elif isinstance(value, float): + return Float(value, Trivia(), str(value)) + elif isinstance(value, dict): +- val = Table(Container(), Trivia(), False) ++ if isinstance(value, InlineTableDict): ++ val = InlineTable(Container(), Trivia()) ++ else: ++ val = Table(Container(), Trivia(), False) + for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): + val[k] = item(v, _parent=val) + +diff --git a/pipenv/vendor/tomlkit/parser.py b/pipenv/vendor/tomlkit/parser.py +index 7b948331..3f507bb4 100644 +--- a/pipenv/vendor/tomlkit/parser.py ++++ b/pipenv/vendor/tomlkit/parser.py +@@ -4,13 +4,6 @@ from __future__ import unicode_literals + import re + import string + +-from typing import Any +-from typing import Generator +-from typing import List +-from typing import Optional +-from typing import Tuple +-from typing import Union +- + from ._compat import chr + from ._compat import decode + from ._utils import _escaped +diff --git a/pipenv/vendor/tomlkit/source.py b/pipenv/vendor/tomlkit/source.py +index 1a96e058..dcfdafd0 100644 +--- a/pipenv/vendor/tomlkit/source.py ++++ b/pipenv/vendor/tomlkit/source.py +@@ -4,8 +4,6 @@ from __future__ import unicode_literals + import itertools + + from copy import copy +-from typing import Optional +-from typing import Tuple + + from ._compat import PY2 + from ._compat import unicode +diff --git a/pipenv/vendor/tomlkit/toml_file.py b/pipenv/vendor/tomlkit/toml_file.py +index 3b416664..631e9959 100644 +--- a/pipenv/vendor/tomlkit/toml_file.py ++++ b/pipenv/vendor/tomlkit/toml_file.py +@@ -1,8 +1,5 @@ + import io + +-from typing import Any +-from typing import Dict +- + from .api import loads + from .toml_document import TOMLDocument + diff --git a/tasks/vendoring/patches/vendor/tomlkit-typing-imports.patch b/tasks/vendoring/patches/vendor/tomlkit-typing-imports.patch deleted file mode 100644 index 2288b51333..0000000000 --- a/tasks/vendoring/patches/vendor/tomlkit-typing-imports.patch +++ /dev/null @@ -1,93 +0,0 @@ -diff --git a/pipenv/vendor/tomlkit/api.py b/pipenv/vendor/tomlkit/api.py -index e541c20c..0ac26752 100644 ---- a/pipenv/vendor/tomlkit/api.py -+++ b/pipenv/vendor/tomlkit/api.py -@@ -1,7 +1,5 @@ - import datetime as _datetime - --from typing import Tuple -- - from ._utils import parse_rfc3339 - from .container import Container - from .items import AoT -diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py -index c1d2d7c6..a7876ff1 100644 ---- a/pipenv/vendor/tomlkit/container.py -+++ b/pipenv/vendor/tomlkit/container.py -@@ -1,13 +1,5 @@ - from __future__ import unicode_literals - --from typing import Any --from typing import Dict --from typing import Generator --from typing import List --from typing import Optional --from typing import Tuple --from typing import Union -- - from ._compat import decode - from .exceptions import KeyAlreadyPresent - from .exceptions import NonExistentKey -diff --git a/pipenv/vendor/tomlkit/exceptions.py b/pipenv/vendor/tomlkit/exceptions.py -index 8d48bf19..d889a924 100644 ---- a/pipenv/vendor/tomlkit/exceptions.py -+++ b/pipenv/vendor/tomlkit/exceptions.py -@@ -1,6 +1,3 @@ --from typing import Optional -- -- - class TOMLKitError(Exception): - - pass -diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py -index 747dbd50..8807f4b3 100644 ---- a/pipenv/vendor/tomlkit/items.py -+++ b/pipenv/vendor/tomlkit/items.py -@@ -6,14 +6,11 @@ import string - from datetime import date - from datetime import datetime - from datetime import time --from enum import Enum --from typing import Any --from typing import Dict --from typing import Generator --from typing import List --from typing import Optional --from typing import Union -- -+import sys -+if sys.version_info >= (3, 4): -+ from enum import Enum -+else: -+ from pipenv.vendor.backports.enum import Enum - - from ._compat import PY2 - from ._compat import decode -diff --git a/pipenv/vendor/tomlkit/parser.py b/pipenv/vendor/tomlkit/parser.py -index b55a3fe4..3d4984d1 100644 ---- a/pipenv/vendor/tomlkit/parser.py -+++ b/pipenv/vendor/tomlkit/parser.py -@@ -7,10 +7,6 @@ import re - import string - - from copy import copy --from typing import Iterator --from typing import Optional --from typing import Tuple --from typing import Union - - from ._compat import PY2 - from ._compat import chr -diff --git a/pipenv/vendor/tomlkit/toml_file.py b/pipenv/vendor/tomlkit/toml_file.py -index 3b416664..631e9959 100644 ---- a/pipenv/vendor/tomlkit/toml_file.py -+++ b/pipenv/vendor/tomlkit/toml_file.py -@@ -1,8 +1,5 @@ - import io - --from typing import Any --from typing import Dict -- - from .api import loads - from .toml_document import TOMLDocument - diff --git a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch b/tasks/vendoring/patches/vendor/tomlkit-update-items.patch deleted file mode 100644 index ed2fb95eb9..0000000000 --- a/tasks/vendoring/patches/vendor/tomlkit-update-items.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py -index 37014921..987a0790 100644 ---- a/pipenv/vendor/tomlkit/container.py -+++ b/pipenv/vendor/tomlkit/container.py -@@ -9,6 +9,7 @@ from .items import Item - from .items import Key - from .items import Null - from .items import Table -+from .items import Trivia - from .items import Whitespace - from .items import item as _item - -@@ -189,8 +190,12 @@ class Container(dict): - if idx is None: - raise NonExistentKey(key) - -- self._body[idx] = (None, Null()) -- -+ old_data = self._body[idx][1] -+ trivia = getattr(old_data, "trivia", None) -+ if trivia and getattr(trivia, "comment", None): -+ self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) -+ else: -+ self._body[idx] = (None, Null()) - super(Container, self).__delitem__(key.key) - - return self From de98b874ec22acdedc1155fa9e6db3ac40b2a016 Mon Sep 17 00:00:00 2001 From: frostming Date: Sat, 10 Nov 2018 14:51:19 +0800 Subject: [PATCH 13/14] backports import --- pipenv/vendor/tomlkit/items.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py index 7035b69ecc..39128d30ff 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py @@ -6,7 +6,10 @@ from datetime import date from datetime import datetime from datetime import time -from enum import Enum +try: + from enum import Enum +except ImportError: + from pipenv.vendor.backports.enum import Enum from ._compat import PY2 from ._compat import decode From f5c7c58be01e4a0fa17c64d5790e16c8cfc56bec Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Sat, 10 Nov 2018 15:41:09 +0800 Subject: [PATCH 14/14] Change fallback style --- pipenv/vendor/tomlkit/items.py | 6 +-- .../patches/vendor/tomlkit-fix.patch | 50 +++++++++++-------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py index 39128d30ff..cccfd4a18e 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py @@ -6,10 +6,6 @@ from datetime import date from datetime import datetime from datetime import time -try: - from enum import Enum -except ImportError: - from pipenv.vendor.backports.enum import Enum from ._compat import PY2 from ._compat import decode @@ -18,8 +14,10 @@ from ._utils import escape_string if PY2: + from pipenv.vendor.backports.enum import Enum from pipenv.vendor.backports.functools_lru_cache import lru_cache else: + from enum import Enum from functools import lru_cache from toml.decoder import InlineTableDict diff --git a/tasks/vendoring/patches/vendor/tomlkit-fix.patch b/tasks/vendoring/patches/vendor/tomlkit-fix.patch index 5dd9d3fe1e..36e2f8083d 100644 --- a/tasks/vendoring/patches/vendor/tomlkit-fix.patch +++ b/tasks/vendoring/patches/vendor/tomlkit-fix.patch @@ -4,19 +4,19 @@ index e541c20c..0ac26752 100644 +++ b/pipenv/vendor/tomlkit/api.py @@ -1,7 +1,5 @@ import datetime as _datetime - + -from typing import Tuple - from ._utils import parse_rfc3339 from .container import Container from .items import AoT diff --git a/pipenv/vendor/tomlkit/container.py b/pipenv/vendor/tomlkit/container.py -index cb8af1d5..56ee2d62 100644 +index cb8af1d5..9b5db5cb 100644 --- a/pipenv/vendor/tomlkit/container.py +++ b/pipenv/vendor/tomlkit/container.py @@ -1,13 +1,5 @@ from __future__ import unicode_literals - + -from typing import Any -from typing import Dict -from typing import Generator @@ -35,7 +35,7 @@ index cb8af1d5..56ee2d62 100644 +from .items import Trivia from .items import Whitespace from .items import item as _item - + @@ -221,7 +214,12 @@ class Container(dict): for i in idx: self._body[i] = (None, Null()) @@ -47,9 +47,9 @@ index cb8af1d5..56ee2d62 100644 + self._body[idx] = (None, Comment(Trivia(comment_ws="", comment=trivia.comment))) + else: + self._body[idx] = (None, Null()) - + super(Container, self).__delitem__(key.key) - + diff --git a/pipenv/vendor/tomlkit/exceptions.py b/pipenv/vendor/tomlkit/exceptions.py index 4fbc667b..c1a4e620 100644 --- a/pipenv/vendor/tomlkit/exceptions.py @@ -57,17 +57,18 @@ index 4fbc667b..c1a4e620 100644 @@ -1,5 +1,3 @@ -from typing import Optional - - + class TOMLKitError(Exception): - + diff --git a/pipenv/vendor/tomlkit/items.py b/pipenv/vendor/tomlkit/items.py -index 375b5f02..7035b69e 100644 +index 375b5f02..cccfd4a1 100644 --- a/pipenv/vendor/tomlkit/items.py +++ b/pipenv/vendor/tomlkit/items.py -@@ -7,13 +7,6 @@ from datetime import date +@@ -6,14 +6,6 @@ import string + from datetime import date from datetime import datetime from datetime import time - from enum import Enum +-from enum import Enum -from typing import Any -from typing import Dict -from typing import Generator @@ -75,18 +76,23 @@ index 375b5f02..7035b69e 100644 -from typing import Optional -from typing import Union - - + from ._compat import PY2 from ._compat import decode -@@ -25,6 +18,7 @@ if PY2: +@@ -22,9 +14,12 @@ from ._compat import unicode + from ._utils import escape_string + + if PY2: ++ from pipenv.vendor.backports.enum import Enum from pipenv.vendor.backports.functools_lru_cache import lru_cache else: ++ from enum import Enum from functools import lru_cache +from toml.decoder import InlineTableDict - - + + def item(value, _parent=None): -@@ -40,7 +34,10 @@ def item(value, _parent=None): +@@ -40,7 +35,10 @@ def item(value, _parent=None): elif isinstance(value, float): return Float(value, Trivia(), str(value)) elif isinstance(value, dict): @@ -97,7 +103,7 @@ index 375b5f02..7035b69e 100644 + val = Table(Container(), Trivia(), False) for k, v in sorted(value.items(), key=lambda i: (isinstance(i[1], dict), i[0])): val[k] = item(v, _parent=val) - + diff --git a/pipenv/vendor/tomlkit/parser.py b/pipenv/vendor/tomlkit/parser.py index 7b948331..3f507bb4 100644 --- a/pipenv/vendor/tomlkit/parser.py @@ -105,7 +111,7 @@ index 7b948331..3f507bb4 100644 @@ -4,13 +4,6 @@ from __future__ import unicode_literals import re import string - + -from typing import Any -from typing import Generator -from typing import List @@ -122,11 +128,11 @@ index 1a96e058..dcfdafd0 100644 +++ b/pipenv/vendor/tomlkit/source.py @@ -4,8 +4,6 @@ from __future__ import unicode_literals import itertools - + from copy import copy -from typing import Optional -from typing import Tuple - + from ._compat import PY2 from ._compat import unicode diff --git a/pipenv/vendor/tomlkit/toml_file.py b/pipenv/vendor/tomlkit/toml_file.py @@ -135,10 +141,10 @@ index 3b416664..631e9959 100644 +++ b/pipenv/vendor/tomlkit/toml_file.py @@ -1,8 +1,5 @@ import io - + -from typing import Any -from typing import Dict - from .api import loads from .toml_document import TOMLDocument - +