diff --git a/pdm/models/candidates.py b/pdm/models/candidates.py index 3bc579564b898c3b19103c01a281b825c698aedc..5f781769e960c0068fdd923c5d4af13c89e46944 100644 --- a/pdm/models/candidates.py +++ b/pdm/models/candidates.py @@ -412,14 +412,25 @@ class PreparedCandidate: except ValueError: termui.logger.warn("Failed to parse pyproject.toml") else: - setup = Setup( - name=metadata.name, - version=metadata.version, - install_requires=metadata.dependencies or [], - extras_require=metadata.optional_dependencies or {}, - python_requires=metadata.requires_python or None, - ) - return SetupDistribution(setup) + dynamic_fields = metadata.dynamic or [] + # Use the parse result only when all are static + if set(dynamic_fields).isdisjoint( + { + "name", + "version", + "dependencies", + "optional-dependencies", + "requires-python", + } + ): + setup = Setup( + name=metadata.name, + version=metadata.version, + install_requires=metadata.dependencies or [], + extras_require=metadata.optional_dependencies or {}, + python_requires=metadata.requires_python or None, + ) + return SetupDistribution(setup) # If all fail, try building the source to get the metadata builder = EditableBuilder if self.req.editable else WheelBuilder try: diff --git a/tests/fixtures/projects/test-hatch-static/README.md b/tests/fixtures/projects/test-hatch-static/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/fixtures/projects/test-hatch-static/pyproject.toml b/tests/fixtures/projects/test-hatch-static/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..f69690c62af442a8e5442faf9d82be5db6dd9cf9 --- /dev/null +++ b/tests/fixtures/projects/test-hatch-static/pyproject.toml @@ -0,0 +1,16 @@ +[build-system] +requires = ["hatchling>=0.15.0"] +build-backend = "hatchling.build" + +[project] +name = "test-hatch" +version = "0.1.0" +description = "Test hatch project" +readme = "README.md" +license = "MIT" +requires-python = ">=3.7" +authors = [{ name = "John", email = "john@example.org" }] +classifiers = [ + "License :: OSI Approved :: MIT License", +] +dependencies = ["requests", "click"] diff --git a/tests/models/test_candidates.py b/tests/models/test_candidates.py index c98dc89e224453f932a90740860864e23ccc579d..3e1f3ab011342b65a6240b83ea80bbedde48d203 100644 --- a/tests/models/test_candidates.py +++ b/tests/models/test_candidates.py @@ -334,3 +334,24 @@ def test_find_candidates_from_find_links(project): ] candidates = list(repo.find_candidates(parse_requirement("demo"))) assert len(candidates) == 2 + + +def test_parse_metadata_from_pep621(project, mocker): + builder = mocker.patch("pdm.builders.wheel.WheelBuilder.build") + req = parse_requirement( + f"test-hatch @ file://{FIXTURES.as_posix()}/projects/test-hatch-static" + ) + candidate = Candidate(req) + metadata = candidate.prepare(project.environment).metadata + assert sorted(metadata.requires) == ["click", "requests"] + builder.assert_not_called() + + +def test_parse_metadata_with_dynamic_fields(project, local_finder): + req = parse_requirement( + f"demo-package @ file://{FIXTURES.as_posix()}/projects/demo-src-package" + ) + candidate = Candidate(req) + metadata = candidate.prepare(project.environment).metadata + assert not metadata.requires + assert metadata.version == "0.1.0"