From 9e4a1af958c8ebbbe0cda2d2cbe5be065ee0bdef Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 19 Aug 2022 18:16:06 +0100 Subject: [PATCH 1/6] Replicate problems with `setup.py --version` and auto-discovery --- setuptools/tests/test_config_discovery.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/setuptools/tests/test_config_discovery.py b/setuptools/tests/test_config_discovery.py index fac365f410..f6c114af6e 100644 --- a/setuptools/tests/test_config_discovery.py +++ b/setuptools/tests/test_config_discovery.py @@ -508,6 +508,15 @@ def test_compatible_with_numpy_configuration(tmp_path): assert dist.packages is None +def test_name_discovery_doesnt_break_cli(tmpdir_cwd): + jaraco.path.build({"pkg.py": ""}) + dist = Distribution({}) + dist.script_args = ["--name"] + dist.set_defaults() + dist.parse_command_line() # <-- no exception should be raised here. + assert dist.get_name() == "pkg" + + def _populate_project_dir(root, files, options): # NOTE: Currently pypa/build will refuse to build the project if no # `pyproject.toml` or `setup.py` is found. So it is impossible to do From fd6e0773589691eb0d4455b26af7c2d417d6ff60 Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Fri, 19 Aug 2022 12:22:12 +1000 Subject: [PATCH 2/6] Remove inadvertent splatting of the name attribute The `name` attribute of a `Distribution` object is used by the command-line processing system and is not intended to hold the name of the distribution itself. Setting it to the name will cause the command-line processing system to have a bad time. --- setuptools/discovery.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setuptools/discovery.py b/setuptools/discovery.py index 6a3d2c9d2e..98fc2a7f48 100644 --- a/setuptools/discovery.py +++ b/setuptools/discovery.py @@ -481,7 +481,6 @@ def analyse_name(self): ) if name: self.dist.metadata.name = name - self.dist.name = name def _find_name_single_package_or_module(self) -> Optional[str]: """Exactly one module or package""" From e1fd1b447895dc8e8d4183d23e492d862608d258 Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Fri, 19 Aug 2022 12:43:21 +1000 Subject: [PATCH 3/6] Add changelog entry. --- changelog.d/3547.change.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/3547.change.rst diff --git a/changelog.d/3547.change.rst b/changelog.d/3547.change.rst new file mode 100644 index 0000000000..0ccf00a6d9 --- /dev/null +++ b/changelog.d/3547.change.rst @@ -0,0 +1 @@ +Stop `ConfigDiscovery.analyse_name` from splatting the `Distribution.name` attribute -- by :user:`jeamland` \ No newline at end of file From ce572dfe4aa5cad3c6889863a46dbac6e015b397 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 19 Aug 2022 17:36:38 +0100 Subject: [PATCH 4/6] Replicate problems with name discovery and dynamic versions According to issue 3545 it seems that "name-discovery" happens, even when the project already explicitly sets it. This is related to parsing of dynamic versions (via `attr` directive), which triggers the auto-discovery to obtain the value of `package_dir`. The value of `package_dir` is used to find the path to the module in `version = {"attr" = "module_name.attr_name"}`. --- setuptools/tests/test_config_discovery.py | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/setuptools/tests/test_config_discovery.py b/setuptools/tests/test_config_discovery.py index f6c114af6e..85b64b31dd 100644 --- a/setuptools/tests/test_config_discovery.py +++ b/setuptools/tests/test_config_discovery.py @@ -517,6 +517,40 @@ def test_name_discovery_doesnt_break_cli(tmpdir_cwd): assert dist.get_name() == "pkg" +def test_preserve_explicit_name_with_dynamic_version(tmpdir_cwd, monkeypatch): + """According to #3545 it seems that ``name`` discovery is running, + even when the project already explicitly sets it. + This seems to be related to parsing of dynamic versions (via ``attr`` directive), + which requires the auto-discovery of ``package_dir``. + """ + files = { + "src": { + "pkg": {"__init__.py": "__version__ = 42\n"}, + }, + "pyproject.toml": DALS(""" + [project] + name = "myproj" # purposefully different from package name + dynamic = ["version"] + [tool.setuptools.dynamic] + version = {"attr" = "pkg.__version__"} + """) + } + jaraco.path.build(files) + dist = Distribution({}) + orig_analyse_name = dist.set_defaults.analyse_name + + def spy_analyse_name(): + # We can check if name discovery was triggered by ensuring the original + # name remains instead of the package name. + orig_analyse_name() + assert dist.get_name() == "myproj" + + monkeypatch.setattr(dist.set_defaults, "analyse_name", spy_analyse_name) + dist.parse_config_files() + assert dist.get_version() == "42" + assert set(dist.packages) == {"pkg"} + + def _populate_project_dir(root, files, options): # NOTE: Currently pypa/build will refuse to build the project if no # `pyproject.toml` or `setup.py` is found. So it is impossible to do From ffd88b0dc44477035ef340e7126c2559fa77929b Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 19 Aug 2022 17:46:47 +0100 Subject: [PATCH 5/6] Fix problems with name discovery and dynamic versions --- setuptools/config/pyprojecttoml.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/setuptools/config/pyprojecttoml.py b/setuptools/config/pyprojecttoml.py index 9ff0c87fa8..d995f0bcc7 100644 --- a/setuptools/config/pyprojecttoml.py +++ b/setuptools/config/pyprojecttoml.py @@ -234,8 +234,8 @@ def expand(self): # A distribution object is required for discovering the correct package_dir dist = self._ensure_dist() - - with _EnsurePackagesDiscovered(dist, self.setuptools_cfg) as ensure_discovered: + ctx = _EnsurePackagesDiscovered(dist, self.project_cfg, self.setuptools_cfg) + with ctx as ensure_discovered: package_dir = ensure_discovered.package_dir self._expand_data_files() self._expand_cmdclass(package_dir) @@ -428,8 +428,11 @@ def _ignore_errors(ignore_option_errors: bool): class _EnsurePackagesDiscovered(_expand.EnsurePackagesDiscovered): - def __init__(self, distribution: "Distribution", setuptools_cfg: dict): + def __init__( + self, distribution: "Distribution", project_cfg: dict, setuptools_cfg: dict + ): super().__init__(distribution) + self._project_cfg = project_cfg self._setuptools_cfg = setuptools_cfg def __enter__(self): @@ -443,8 +446,10 @@ def __enter__(self): dist.set_defaults._ignore_ext_modules() # pyproject.toml-specific behaviour - # Set `py_modules` and `packages` in dist to short-circuit auto-discovery, - # but avoid overwriting empty lists purposefully set by users. + # Set `name`, `py_modules` and `packages` in dist to short-circuit + # auto-discovery, but avoid overwriting empty lists purposefully set by users. + if dist.metadata.name is None: + dist.metadata.name = self._project_cfg.get("name") if dist.py_modules is None: dist.py_modules = cfg.get("py-modules") if dist.packages is None: From 9a4b45f3163985fce18fd52fad3269982c052508 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 19 Aug 2022 18:23:59 +0100 Subject: [PATCH 6/6] Fix rst syntax in news fragment --- changelog.d/3547.change.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/3547.change.rst b/changelog.d/3547.change.rst index 0ccf00a6d9..88583b1b63 100644 --- a/changelog.d/3547.change.rst +++ b/changelog.d/3547.change.rst @@ -1 +1 @@ -Stop `ConfigDiscovery.analyse_name` from splatting the `Distribution.name` attribute -- by :user:`jeamland` \ No newline at end of file +Stop ``ConfigDiscovery.analyse_name`` from splatting the ``Distribution.name`` attribute -- by :user:`jeamland`