Skip to content

Commit d363210

Browse files
committed
fix: parse name earlier
Signed-off-by: Frost Ming <me@frostming.com>
1 parent 4821fe5 commit d363210

File tree

4 files changed

+7
-10
lines changed

4 files changed

+7
-10
lines changed

src/pdm/models/candidates.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,6 @@ def __init__(
146146
:param link: the file link of the candidate.
147147
"""
148148
self.req = req
149-
if isinstance(req, FileRequirement):
150-
req.check_installable()
151149
self.name = name or self.req.project_name
152150
self.version = version
153151
if link is None and not req.is_named:
@@ -292,6 +290,8 @@ def format(self) -> str:
292290
def prepare(self, environment: BaseEnvironment, reporter: CandidateReporter | None = None) -> PreparedCandidate:
293291
"""Prepare the candidate for installation."""
294292
if self._prepared is None:
293+
if isinstance(self.req, FileRequirement):
294+
self.req.check_installable()
295295
self._prepared = PreparedCandidate(self, environment, reporter=reporter or CandidateReporter())
296296
else:
297297
self._prepared.environment = environment

src/pdm/models/requirements.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ def _parse_url(self) -> None:
312312
self.path = path
313313
# For relative path, we don't resolve URL now, so the path may still contain fragments,
314314
# it will be handled in `relocate()` method.
315+
result = Setup.from_directory(self.absolute_path) # type: ignore[arg-type]
316+
if result.name:
317+
self.name = result.name
315318
else:
316319
url = url_without_fragments(self.url)
317320
relpath = get_relative_path(url)
@@ -401,13 +404,8 @@ def check_installable(self) -> None:
401404
if path.is_dir():
402405
if not path.joinpath("setup.py").exists() and not path.joinpath("pyproject.toml").exists():
403406
raise RequirementError(f"The local path '{self.path}' is not installable.")
404-
result = Setup.from_directory(path)
405-
if result.name:
406-
self.name = result.name
407407
elif self.editable:
408408
raise RequirementError("Local file requirement must not be editable.")
409-
elif self.editable and not self.is_vcs:
410-
raise RequirementError("Non-VCS remote file requirement must not be editable.")
411409

412410

413411
@dataclasses.dataclass(eq=False)

tests/models/test_candidates.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,5 +314,6 @@ def test_parse_metadata_with_dynamic_fields(project, local_finder):
314314

315315
def test_get_metadata_for_non_existing_path(project):
316316
req = parse_requirement("file:///${PROJECT_ROOT}/non-existing-path")
317+
candidate = Candidate(req)
317318
with pytest.raises(RequirementError, match="The local path '.+' does not exist"):
318-
Candidate(req)
319+
candidate.prepare(project.environment).metadata

tests/models/test_requirements.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ def filter_requirements_to_lines(
8383
@pytest.mark.parametrize("req, result", REQUIREMENTS)
8484
def test_convert_req_dict_to_req_line(req, result):
8585
r = parse_requirement(req)
86-
if hasattr(r, "check_installable"):
87-
r.check_installable()
8886
result = result or req
8987
assert r.as_line() == result
9088

0 commit comments

Comments
 (0)