From 7754e6633fd6047baf3790a9aec8be91680e094e Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Mon, 19 Sep 2022 18:03:16 -0400 Subject: [PATCH] Refactor requirementslib for categories and remove unused code. --- pipenv/vendor/plette/lockfiles.py | 18 +- .../vendor/requirementslib/models/lockfile.py | 43 +---- .../vendor/requirementslib/models/project.py | 156 ------------------ 3 files changed, 17 insertions(+), 200 deletions(-) diff --git a/pipenv/vendor/plette/lockfiles.py b/pipenv/vendor/plette/lockfiles.py index 001b360c..22ffe547 100644 --- a/pipenv/vendor/plette/lockfiles.py +++ b/pipenv/vendor/plette/lockfiles.py @@ -35,12 +35,6 @@ class _LockFileEncoder(json.JSONEncoder): yield "\n" -LOCKFILE_SECTIONS = { - "_meta": Meta, - "default": PackageCollection, - "develop": PackageCollection, -} - PIPFILE_SPEC_CURRENT = 6 @@ -70,8 +64,11 @@ class Lockfile(DataView): @classmethod def validate(cls, data): super(Lockfile, cls).validate(data) - for key, klass in LOCKFILE_SECTIONS.items(): - klass.validate(data[key]) + for key, value in data.items(): + if key == "_meta": + Meta.validate(value) + else: + PackageCollection.validate(value) @classmethod def load(cls, f, encoding=None): @@ -98,7 +95,10 @@ class Lockfile(DataView): def __getitem__(self, key): value = self._data[key] try: - return LOCKFILE_SECTIONS[key](value) + if key == "_meta": + return Meta(value) + else: + return PackageCollection(value) except KeyError: return value diff --git a/pipenv/vendor/requirementslib/models/lockfile.py b/pipenv/vendor/requirementslib/models/lockfile.py index be84ee75..57cf2320 100644 --- a/pipenv/vendor/requirementslib/models/lockfile.py +++ b/pipenv/vendor/requirementslib/models/lockfile.py @@ -53,7 +53,7 @@ class Lockfile(object): @property def section_keys(self): - return ["default", "develop"] + return set(self.lockfile.keys()) - {"_meta"} @property def extended_keys(self): @@ -75,8 +75,6 @@ class Lockfile(object): def __getitem__(self, k, *args, **kwargs): retval = None lockfile = self._lockfile - section = None - pkg_type = None try: retval = lockfile[k] except KeyError: @@ -94,7 +92,6 @@ class Lockfile(object): return retval def __getattr__(self, k, *args, **kwargs): - retval = None lockfile = super(Lockfile, self).__getattribute__("_lockfile") try: return super(Lockfile, self).__getattribute__(k) @@ -122,7 +119,6 @@ class Lockfile(object): :return: A project file with the model and location for interaction :rtype: :class:`~requirementslib.models.project.ProjectFile` """ - pf = ProjectFile.read(path, lockfiles.Lockfile, invalid_ok=True) return pf @@ -250,6 +246,9 @@ class Lockfile(object): def create(cls, path, create=True): return cls.load(path, create=create) + def get_section(self, name): + return self._lockfile.get(name) + @property def develop(self): return self._lockfile.develop @@ -280,38 +279,12 @@ class Lockfile(object): for k, v in deps.items(): yield Requirement.from_pipfile(k, v) - @property - def dev_requirements(self): - if not self._dev_requirements: - self._dev_requirements = list(self.get_requirements(dev=True, only=True)) - return self._dev_requirements - - @property - def requirements(self): - if not self._requirements: - self._requirements = list(self.get_requirements(dev=False, only=True)) - return self._requirements - - @property - def dev_requirements_list(self): - return [{name: entry._data} for name, entry in self._lockfile.develop.items()] - - @property - def requirements_list(self): - return [{name: entry._data} for name, entry in self._lockfile.default.items()] + def requirements_list(self, category): + if self._lockfile.get(category): + return [{name: entry._data} for name, entry in self._lockfile[category].items()] + return [] def write(self): self.projectfile.model = copy.deepcopy(self._lockfile) self.projectfile.write() - def as_requirements(self, include_hashes=False, dev=False): - """Returns a list of requirements in pip-style format.""" - lines = [] - section = self.dev_requirements if dev else self.requirements - for req in section: - kwargs = {"include_hashes": include_hashes} - if req.editable: - kwargs["include_markers"] = False - r = req.as_line(**kwargs) - lines.append(r.strip()) - return lines diff --git a/pipenv/vendor/requirementslib/models/project.py b/pipenv/vendor/requirementslib/models/project.py index 139451c4..0bf8bbfa 100644 --- a/pipenv/vendor/requirementslib/models/project.py +++ b/pipenv/vendor/requirementslib/models/project.py @@ -3,11 +3,7 @@ import io import os import pipenv.vendor.attr as attr -import pipenv.vendor.plette as plette -import pipenv.vendor.plette.models as models -import pipenv.vendor.tomlkit as tomlkit from pipenv.patched.pip._vendor.packaging.markers import Marker -from pipenv.patched.pip._vendor.packaging.utils import canonicalize_name SectionDifference = collections.namedtuple("SectionDifference", ["inthis", "inthat"]) FileDifference = collections.namedtuple("FileDifference", ["default", "develop"]) @@ -70,155 +66,3 @@ class ProjectFile(object): strio = io.StringIO() self.model.dump(strio) return strio.getvalue() - - -@attr.s -class Project(object): - - root = attr.ib() - _p = attr.ib(init=False) - _l = attr.ib(init=False) - - def __attrs_post_init__(self): - self.root = root = os.path.abspath(self.root) - self._p = ProjectFile.read(os.path.join(root, "Pipfile"), plette.Pipfile) - self._l = ProjectFile.read( - os.path.join(root, "Pipfile.lock"), plette.Lockfile, invalid_ok=True - ) - - @property - def pipfile(self): - return self._p.model - - @property - def pipfile_location(self): - return self._p.location - - @property - def lockfile(self): - return self._l.model - - @property - def lockfile_location(self): - return self._l.location - - @lockfile.setter - def lockfile(self, new): - self._l.model = new - - def is_synced(self): - return self.lockfile and self.lockfile.is_up_to_date(self.pipfile) - - def _get_pipfile_section(self, develop, insert=True): - name = "dev-packages" if develop else "packages" - try: - section = self.pipfile[name] - except KeyError: - section = models.PackageCollection(tomlkit.table()) - if insert: - self.pipfile[name] = section - return section - - def contains_key_in_pipfile(self, key): - sections = [ - self._get_pipfile_section(develop=False, insert=False), - self._get_pipfile_section(develop=True, insert=False), - ] - return any( - (canonicalize_name(name) == canonicalize_name(key)) - for section in sections - for name in section - ) - - def add_line_to_pipfile(self, line, develop): - from pipenv.vendor.requirementslib import Requirement - - requirement = Requirement.from_line(line) - section = self._get_pipfile_section(develop=develop) - key = requirement.normalized_name - entry = next(iter(requirement.as_pipfile().values())) - if isinstance(entry, dict): - # HACK: TOMLKit prefers to expand tables by default, but we - # always want inline tables here. Also tomlkit.inline_table - # does not have `update()`. - table = tomlkit.inline_table() - for k, v in entry.items(): - table[k] = v - entry = table - section[key] = entry - - def remove_keys_from_pipfile(self, keys, default, develop): - keys = {canonicalize_name(key) for key in keys} - sections = [] - if default: - sections.append(self._get_pipfile_section(develop=False, insert=False)) - if develop: - sections.append(self._get_pipfile_section(develop=True, insert=False)) - for section in sections: - removals = set() - for name in section: - if canonicalize_name(name) in keys: - removals.add(name) - for key in removals: - del section._data[key] - - def remove_keys_from_lockfile(self, keys): - keys = {canonicalize_name(key) for key in keys} - removed = False - for section_name in ("default", "develop"): - try: - section = self.lockfile[section_name] - except KeyError: - continue - removals = set() - for name in section: - if canonicalize_name(name) in keys: - removals.add(name) - removed = removed or bool(removals) - for key in removals: - del section._data[key] - - if removed: - # HACK: The lock file no longer represents the Pipfile at this - # point. Set the hash to an arbitrary invalid value. - self.lockfile.meta.hash = models.Hash({"__invalid__": ""}) - - def difference_lockfile(self, lockfile): - """Generate a difference between the current and given lockfiles. - - Returns a 2-tuple containing differences in default in develop - sections. - - Each element is a 2-tuple of dicts. The first, `inthis`, contains - entries only present in the current lockfile; the second, `inthat`, - contains entries only present in the given one. - - If a key exists in both this and that, but the values differ, the key - is present in both dicts, pointing to values from each file. - """ - diff_data = { - "default": SectionDifference({}, {}), - "develop": SectionDifference({}, {}), - } - for section_name, section_diff in diff_data.items(): - try: - this = self.lockfile[section_name]._data - except (KeyError, TypeError): - this = {} - try: - that = lockfile[section_name]._data - except (KeyError, TypeError): - that = {} - for key, this_value in this.items(): - try: - that_value = that[key] - except KeyError: - section_diff.inthis[key] = this_value - continue - if not _are_pipfile_entries_equal(this_value, that_value): - section_diff.inthis[key] = this_value - section_diff.inthat[key] = that_value - for key, that_value in that.items(): - if key not in this: - section_diff.inthat[key] = that_value - return FileDifference(**diff_data)