Skip to content

Commit 884b845

Browse files
authored
Fix "residual" invalid dynamic behaviour of optional-dependencies (#4696)
2 parents cffbd73 + 2c99d1e commit 884b845

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

newsfragments/4696.bugfix.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix clashes for ``optional-dependencies`` in ``pyproject.toml`` and
2+
``extra_requires`` in ``setup.cfg/setup.py``.
3+
As per PEP 621, ``optional-dependencies`` has to be honoured and dynamic
4+
behaviour is not allowed.

setuptools/config/_apply_pyprojecttoml.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,10 @@ def _dependencies(dist: Distribution, val: list, _root_dir):
217217

218218

219219
def _optional_dependencies(dist: Distribution, val: dict, _root_dir):
220-
existing = getattr(dist, "extras_require", None) or {}
221-
dist.extras_require = {**existing, **val}
220+
if getattr(dist, "extras_require", None):
221+
msg = "`extras_require` overwritten in `pyproject.toml` (optional-dependencies)"
222+
SetuptoolsWarning.emit(msg)
223+
dist.extras_require = val
222224

223225

224226
def _ext_modules(dist: Distribution, val: list[dict]) -> list[Extension]:

setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from setuptools.config.pyprojecttoml import apply_configuration
77
from setuptools.dist import Distribution
8+
from setuptools.warnings import SetuptoolsWarning
89

910

1011
def test_dynamic_dependencies(tmp_path):
@@ -77,23 +78,32 @@ def test_mixed_dynamic_optional_dependencies(tmp_path):
7778
7879
[tool.setuptools.dynamic.optional-dependencies.images]
7980
file = ["requirements-images.txt"]
80-
81-
[build-system]
82-
requires = ["setuptools", "wheel"]
83-
build-backend = "setuptools.build_meta"
8481
"""
8582
),
8683
}
8784

8885
path.build(files, prefix=tmp_path)
89-
90-
# Test that the mix-and-match doesn't currently validate.
9186
pyproject = tmp_path / "pyproject.toml"
9287
with pytest.raises(ValueError, match="project.optional-dependencies"):
9388
apply_configuration(Distribution(), pyproject)
9489

95-
# Explicitly disable the validation and try again, to see that the mix-and-match
96-
# result would be correct.
97-
dist = Distribution()
98-
dist = apply_configuration(dist, pyproject, ignore_option_errors=True)
99-
assert dist.extras_require == {"docs": ["sphinx"], "images": ["pillow~=42.0"]}
90+
91+
def test_mixed_extras_require_optional_dependencies(tmp_path):
92+
files = {
93+
"pyproject.toml": cleandoc(
94+
"""
95+
[project]
96+
name = "myproj"
97+
version = "1.0"
98+
optional-dependencies.docs = ["sphinx"]
99+
"""
100+
),
101+
}
102+
103+
path.build(files, prefix=tmp_path)
104+
pyproject = tmp_path / "pyproject.toml"
105+
106+
with pytest.warns(SetuptoolsWarning, match=".extras_require. overwritten"):
107+
dist = Distribution({"extras_require": {"hello": ["world"]}})
108+
dist = apply_configuration(dist, pyproject)
109+
assert dist.extras_require == {"docs": ["sphinx"]}

0 commit comments

Comments
 (0)