[BUG] Package names with `/` cause unexpected behaviour and unhelpful exceptions
setuptools version
56.0.0
Python version
Python 3.8.10
OS
Windows 11
Additional environment information
Encountered via tox, which invokes build and eventually runs a sdist install via setuptools
Description
If you provide a package name in a setup.cfg file like "foo/bar" and you optionally pass the --sdist argument the build will fail with rather unhelpful error output.
It looks as though distutils treats the package name as a string and creates the tar filename from that string, whereas setuptools expects to find a tar file with the name {package_name}.tar.gz.
With more cleverly devised paths users can control where the tar.gz file ends up being created, putting it anywhere that the user has permission to write to.
Expected behavior
Wheel handles this case by normalizing the package name, this would be the most user-friendly solution, otherwise I would also be happy with an exception since the package name is probably invalid (or maybe should be?).
How to Reproduce
- Clone https://github.com/da1910/build-troubles
cd build-troublespython -m build
Output
Traceback (most recent call last):
File "C:\Users\me\AppData\Local\Temp\build-env-qewrwpt_\lib\site-packages\setuptools\build_meta.py", line 106, in _file_with_extension
file, = matching
ValueError: not enough values to unpack (expected 1, got 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\git\build-troubles\venv\lib\site-packages\pep517\in_process\_in_process.py", line 363, in <module>
main()
File "C:\git\build-troubles\venv\lib\site-packages\pep517\in_process\_in_process.py", line 345, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "C:\git\build-troubles\venv\lib\site-packages\pep517\in_process\_in_process.py", line 314, in build_sdist
return backend.build_sdist(sdist_directory, config_settings)
File "C:\Users\me\AppData\Local\Temp\build-env-qewrwpt_\lib\site-packages\setuptools\build_meta.py", line 234, in build_sdist
return self._build_with_temp_dir(['sdist', '--formats', 'gztar'],
File "C:\Users\me\AppData\Local\Temp\build-env-qewrwpt_\lib\site-packages\setuptools\build_meta.py", line 217, in _build_with_temp_dir
result_basename = _file_with_extension(
File "C:\Users\me\AppData\Local\Temp\build-env-qewrwpt_\lib\site-packages\setuptools\build_meta.py", line 108, in _file_with_extension
raise ValueError(
ValueError: No distribution was found. Ensure that `setup.py` is not empty and that it calls `setup()`.
Code of Conduct
- [X] I agree to follow the PSF Code of Conduct
I'm pretty sure the spec says that package names can contain only ., -, and _ characters (in addition to alphanumeric). Probably Setuptools should fail early on violation of the expectation.
@da1910 Did you solve it?
I did not. To my knowledge this issue persists.
I'm pretty sure the spec says that package names can contain only
.,-, and_characters (in addition to alphanumeric). Probably Setuptools should fail early on violation of the expectation.
Seems like a nice and easy fix then, validate the package name up front against the spec
There's something in setuptools now called 'validate pyproject'. It's possible that it's already doing the appropriate validation. I was going to test before I ran up against https://github.com/pypa/packaging/issues/678. Having worked around that issue, I'm now able to test and confirm the issue still exists when using 'setup.cfg', but when using pyproject.toml, the name is properly validated:
draft [1] 🐚 cat pyproject.toml
[project]
name="foo/bar"
draft 🐚 pyproject-build .
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- setuptools >= 40.8.0
* Getting build dependencies for sdist...
configuration error: `project.name` must be pep508-identifier
DESCRIPTION:
The name (primary identifier) of the project. MUST be statically defined.
GIVEN VALUE:
"foo/bar"
OFFENDING RULE: 'format'
DEFINITION:
{
"type": "string",
"format": "pep508-identifier"
}
For more details about `format` see
https://validate-pyproject.readthedocs.io/en/latest/api/validate_pyproject.formats.html
Traceback (most recent call last):
File "/Users/jaraco/Library/Application Support/pipx/venvs/build/lib/python3.13t/site-packages/pyproject_hooks/_in_process/_in_process.py", line 373, in <module>
main()
~~~~^^
File "/Users/jaraco/Library/Application Support/pipx/venvs/build/lib/python3.13t/site-packages/pyproject_hooks/_in_process/_in_process.py", line 357, in main
json_out["return_val"] = hook(**hook_input["kwargs"])
~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jaraco/Library/Application Support/pipx/venvs/build/lib/python3.13t/site-packages/pyproject_hooks/_in_process/_in_process.py", line 308, in get_requires_for_build_sdist
return hook(config_settings)
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/build_meta.py", line 330, in get_requires_for_build_sdist
return self._get_build_requires(config_settings, requirements=[])
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/build_meta.py", line 297, in _get_build_requires
self.run_setup()
~~~~~~~~~~~~~~^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/build_meta.py", line 497, in run_setup
super().run_setup(setup_script=setup_script)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/build_meta.py", line 313, in run_setup
exec(code, locals())
~~~~^^^^^^^^^^^^^^^^
File "<string>", line 1, in <module>
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/__init__.py", line 108, in setup
return distutils.core.setup(**attrs)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/_distutils/core.py", line 158, in setup
dist.parse_config_files()
~~~~~~~~~~~~~~~~~~~~~~~^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/dist.py", line 603, in parse_config_files
pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/config/pyprojecttoml.py", line 70, in apply_configuration
config = read_configuration(filepath, True, ignore_option_errors, dist)
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/config/pyprojecttoml.py", line 135, in read_configuration
validate(subset, filepath)
~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/private/var/folders/f2/2plv6q2n7l932m2x004jlw340000gn/T/build-env-d0zgdok3/lib/python3.13t/site-packages/setuptools/config/pyprojecttoml.py", line 59, in validate
raise ValueError(f"{error}\n{summary}") from None
ValueError: invalid pyproject.toml config: `project.name`.
configuration error: `project.name` must be pep508-identifier
ERROR Backend subprocess exited when trying to invoke get_requires_for_build_sdist
Therefore, my recommendation is:
If using setup.py or setup.cfg, provide a valid identifier or switch to using pyproject.toml.
I'm flagging this as won't fix, but I'd also accept a PR to validate the name using setup.py or setup.cfg.