From e083646b310c6153227558482d699eed8da84e55 Mon Sep 17 00:00:00 2001 From: Nicolas Simonds <0xDEC0DE@users.noreply.github.com> Date: Thu, 29 Apr 2021 01:27:00 -0700 Subject: [PATCH 1/2] Simplify/improve Package.clone() (#159) Downstream clients (e.g., poetry) appear to assume that the result of a Package.clone() will be a full-fidelity copy of the original. Use `copy.deepcopy` to clone the object, and ensure that this is the case. Resolves Issue #2422 Co-authored-by: Nicolas Simonds --- poetry/core/packages/package.py | 31 +++---------------------------- tests/packages/test_package.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/poetry/core/packages/package.py b/poetry/core/packages/package.py index 211261c56..be18ae7cb 100644 --- a/poetry/core/packages/package.py +++ b/poetry/core/packages/package.py @@ -404,34 +404,9 @@ def with_features(self, features): # type: (List[str]) -> "Package" def without_features(self): # type: () -> "Package" return self.with_features([]) - def clone(self): # type: () -> "Package" - if self.is_root(): - clone = self.__class__(self.pretty_name, self.version) - else: - clone = self.__class__( - self.pretty_name, - self.version, - source_type=self._source_type, - source_url=self._source_url, - source_reference=self._source_reference, - features=list(self.features), - ) - - clone.description = self.description - clone.category = self.category - clone.optional = self.optional - clone.python_versions = self.python_versions - clone.marker = self.marker - clone.extras = self.extras - clone.root_dir = self.root_dir - clone.develop = self.develop - - for dep in self.requires: - clone.requires.append(dep) - - for dep in self.dev_requires: - clone.dev_requires.append(dep) - + def clone(self) -> "Package": + clone = self.__class__(self.pretty_name, self.version) + clone.__dict__ = copy.deepcopy(self.__dict__) return clone def __hash__(self): # type: () -> int diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index 40b980795..da9d52975 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -280,3 +280,30 @@ def test_to_dependency_for_url(): assert "https://example.com/path.tar.gz" == dep.url assert "url" == dep.source_type assert "https://example.com/path.tar.gz" == dep.source_url + + +def test_package_clone(f): + # TODO(nic): this test is not future-proof, in that any attributes added + # to the Package object and not filled out in this test setup might + # cause comparisons to match that otherwise should not. A factory method + # to create a Package object with all fields fully randomized would be the + # most rigorous test for this, but that's likely overkill. + p = Package( + "lol_wut", + "3.141.5926535", + pretty_version="③.⑭.⑮", + source_type="git", + source_url="http://some.url", + source_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", + source_resolved_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", + features=["abc", "def"], + develop=random.choice((True, False)), + ) + p.files = (["file1", "file2", "file3"],) + p.homepage = "https://some.other.url" + p.repository_url = "http://bug.farm" + p.documentation_url = "http://lorem.ipsum/dolor/sit.amet" + p2 = p.clone() + + assert p == p2 + assert p.__dict__ == p2.__dict__ From e6127536f0ecec19f6fa4413eaeb65689d6f5176 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 21 Aug 2021 22:36:27 +0200 Subject: [PATCH 2/2] fix: adapt for 1.0 version --- poetry/core/packages/package.py | 2 +- tests/packages/test_package.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/poetry/core/packages/package.py b/poetry/core/packages/package.py index be18ae7cb..9f7bc7163 100644 --- a/poetry/core/packages/package.py +++ b/poetry/core/packages/package.py @@ -404,7 +404,7 @@ def with_features(self, features): # type: (List[str]) -> "Package" def without_features(self): # type: () -> "Package" return self.with_features([]) - def clone(self) -> "Package": + def clone(self): # type: () -> "Package" clone = self.__class__(self.pretty_name, self.version) clone.__dict__ = copy.deepcopy(self.__dict__) return clone diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index da9d52975..d717aa96a 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -297,7 +297,6 @@ def test_package_clone(f): source_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", source_resolved_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", features=["abc", "def"], - develop=random.choice((True, False)), ) p.files = (["file1", "file2", "file3"],) p.homepage = "https://some.other.url"