From b357d0c9238aa3950abb3a4e5e56ba5f58ea6d5f Mon Sep 17 00:00:00 2001 From: Micael Malta Date: Wed, 7 Dec 2022 23:08:57 -0500 Subject: [PATCH] fix: egg segment for local dependency (#1552) * fix: egg segment for local dependency * add news * fix: egg segment for local dependency with hash on folder name --- news/1552.bugfix.md | 1 + src/pdm/models/requirements.py | 7 ++++--- src/pdm/utils.py | 10 ++++++++++ tests/fixtures/projects/demo-#-with-hash/demo.py | 5 +++++ tests/fixtures/projects/demo-#-with-hash/setup.py | 15 +++++++++++++++ tests/models/test_candidates.py | 2 ++ 6 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 news/1552.bugfix.md create mode 100644 tests/fixtures/projects/demo-#-with-hash/demo.py create mode 100644 tests/fixtures/projects/demo-#-with-hash/setup.py diff --git a/news/1552.bugfix.md b/news/1552.bugfix.md new file mode 100644 index 0000000000..20182f57d2 --- /dev/null +++ b/news/1552.bugfix.md @@ -0,0 +1 @@ +Fix a bug with egg segment for local dependency diff --git a/src/pdm/models/requirements.py b/src/pdm/models/requirements.py index 7c88f5ef7c..161c615ae8 100644 --- a/src/pdm/models/requirements.py +++ b/src/pdm/models/requirements.py @@ -30,6 +30,7 @@ add_ssh_scheme_to_git_uri, normalize_name, path_to_url, + path_without_fragments, url_to_path, url_without_fragments, ) @@ -292,11 +293,11 @@ def _parse_url(self) -> None: path = get_relative_path(self.url) if path is None: try: - self.path = Path(url_to_path(self.url)) + self.path = path_without_fragments(url_to_path(self.url)) except AssertionError: pass else: - self.path = Path(path) + self.path = path_without_fragments(path) if self.url: self._parse_name_from_url() @@ -305,7 +306,7 @@ def relocate(self, backend: BuildBackend) -> None: if self.path is None or self.path.is_absolute(): return # self.path is relative - self.path = Path(os.path.relpath(self.path, backend.root)) + self.path = path_without_fragments(os.path.relpath(self.path, backend.root)) self.url = backend.relative_path_to_url(self.path.as_posix()) @property diff --git a/src/pdm/utils.py b/src/pdm/utils.py index 265d705252..9e8049a79a 100644 --- a/src/pdm/utils.py +++ b/src/pdm/utils.py @@ -25,6 +25,8 @@ from pdm._types import Source from pdm.compat import Distribution +_egg_fragment_re = re.compile(r"(.*)[#&]egg=[^&]*") + def create_tracked_tempdir( suffix: str | None = None, prefix: str | None = None, dir: str | None = None @@ -410,3 +412,11 @@ def is_pip_compatible_with_python(python_version: Version | str) -> bool: pip = importlib_metadata.distribution("pip") requires_python = get_specifier(pip.metadata["Requires-Python"]) return requires_python.contains(python_version, True) + + +def path_without_fragments(path: str) -> Path: + """Remove egg fragment from path""" + match = _egg_fragment_re.search(path) + if not match: + return Path(path) + return Path(match.group(1)) diff --git a/tests/fixtures/projects/demo-#-with-hash/demo.py b/tests/fixtures/projects/demo-#-with-hash/demo.py new file mode 100644 index 0000000000..cb86642baf --- /dev/null +++ b/tests/fixtures/projects/demo-#-with-hash/demo.py @@ -0,0 +1,5 @@ +import os + +import chardet + +print(os.name) diff --git a/tests/fixtures/projects/demo-#-with-hash/setup.py b/tests/fixtures/projects/demo-#-with-hash/setup.py new file mode 100644 index 0000000000..3266916c79 --- /dev/null +++ b/tests/fixtures/projects/demo-#-with-hash/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + + +setup( + name="demo", + version="0.0.1", + description="test demo", + py_modules=["demo"], + python_requires=">=3.3", + install_requires=["idna", "chardet; os_name=='nt'"], + extras_require={ + "tests": ["pytest"], + "security": ['requests; python_version>="3.6"'], + }, +) diff --git a/tests/models/test_candidates.py b/tests/models/test_candidates.py index 99e7785f73..b071a1fdbd 100644 --- a/tests/models/test_candidates.py +++ b/tests/models/test_candidates.py @@ -125,6 +125,8 @@ def test_parse_abnormal_specifiers(project): "demo @ file:///${PROJECT_ROOT}/tests/fixtures/artifacts/demo-0.0.1.tar.gz", "demo @ file:///${PROJECT_ROOT}/tests/fixtures/projects/demo", "-e ./tests/fixtures/projects/demo", + "-e file:///${PROJECT_ROOT}/tests/fixtures/projects/demo#egg=demo", + "-e file:///${PROJECT_ROOT}/tests/fixtures/projects/demo-#-with-hash#egg=demo", ], ) def test_expand_project_root_in_url(req_str, core):