diff --git a/newsfragments/4012.bugfix.rst b/newsfragments/4012.bugfix.rst new file mode 100644 index 0000000000..dec528060a --- /dev/null +++ b/newsfragments/4012.bugfix.rst @@ -0,0 +1,2 @@ +Detects (and complain about) ``scripts`` and ``gui-scripts`` set via ``setup.py`` +when ``pyproject.toml`` does not include them in ``dynamic``. diff --git a/setuptools/config/_apply_pyprojecttoml.py b/setuptools/config/_apply_pyprojecttoml.py index 5fe1108dc8..2d64860b04 100644 --- a/setuptools/config/_apply_pyprojecttoml.py +++ b/setuptools/config/_apply_pyprojecttoml.py @@ -296,6 +296,16 @@ def _get_previous_entrypoints(dist: "Distribution") -> Dict[str, list]: return {k: v for k, v in value.items() if k not in ignore} +def _get_previous_scripts(dist: "Distribution") -> Optional[list]: + value = getattr(dist, "entry_points", None) or {} + return value.get("console_scripts") + + +def _get_previous_gui_scripts(dist: "Distribution") -> Optional[list]: + value = getattr(dist, "entry_points", None) or {} + return value.get("gui_scripts") + + def _attrgetter(attr): """ Similar to ``operator.attrgetter`` but returns None if ``attr`` is not found @@ -371,6 +381,8 @@ def _acessor(obj): "classifiers": _attrgetter("metadata.classifiers"), "urls": _attrgetter("metadata.project_urls"), "entry-points": _get_previous_entrypoints, + "scripts": _get_previous_scripts, + "gui-scripts": _get_previous_gui_scripts, "dependencies": _some_attrgetter("_orig_install_requires", "install_requires"), "optional-dependencies": _some_attrgetter("_orig_extras_require", "extras_require"), } diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py index fd240f8674..a6a827094d 100644 --- a/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -330,6 +330,8 @@ def pyproject(self, tmp_path, dynamic, extra_content=""): [ ("install_requires", "dependencies", ["six"]), ("classifiers", "classifiers", ["Private :: Classifier"]), + ("entry_points", "scripts", {"console_scripts": ["foobar=foobar:main"]}), + ("entry_points", "gui-scripts", {"gui_scripts": ["bazquux=bazquux:main"]}), ], ) def test_not_listed_in_dynamic(self, tmp_path, attr, field, value):