pypa / setuptools

Official project repository for the Setuptools build system
https://pypi.org/project/setuptools/
MIT License
2.46k stars 1.18k forks source link

Setuptools uses `["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]` when `license-files` is not explicitly configured. #3874

Open fizyk opened 1 year ago

fizyk commented 1 year ago

setuptools version

67.6.0 (=>61.0.0)

Python version

3.11.0

OS

ubuntu

Additional environment information

This happens when I build package with build/setuptools

Description

I recently moved packages configuration to the pyproject.toml from setup.cfg, and pointed to the bad LICENSE file (instead of COPYING.lesser).

Building package gave me this warning:

/tmp/build-env-nktdwp4w/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/home/runner/work/pytest-redis/pytest-redis/LICENSE' cannot be found
  warnings.warn(f"File {path!r} cannot be found")

But the wheel's METADATA file had this entry instead:

License-File: AUTHORS.rst

Link to the build:

https://github.com/ClearcodeHQ/pytest-redis/actions/runs/4513863420

Expected behavior

Build will either fail, or will not include any information about the license file.

How to Reproduce

  1. Clone this repository at specified tag: https://github.com/ClearcodeHQ/pytest-redis/tree/v3.0.0
  2. Build virtual-env with pipenv install --dev
  3. Build package pipenv run python -m build .
  4. Check license's metadata with cat pytest_redis.egg-info/PKG-INFO | grep License-File

Output

> pipenv run python -m build .                                                                                                                                                                                                     
* Creating venv isolated environment...
* Installing packages in isolated environment... (setuptools >= 61.0.0, wheel)
* Getting build dependencies for sdist...
/tmp/build-env-hyjh_zg5/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
  warnings.warn(msg, _BetaConfiguration)
/tmp/build-env-hyjh_zg5/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/home/fizyk/workspace/pytest-redis/LICENSE' cannot be found
  warnings.warn(f"File {path!r} cannot be found")
running egg_info
writing pytest_redis.egg-info/PKG-INFO
writing dependency_links to pytest_redis.egg-info/dependency_links.txt
writing entry points to pytest_redis.egg-info/entry_points.txt
writing requirements to pytest_redis.egg-info/requires.txt
writing top-level names to pytest_redis.egg-info/top_level.txt
reading manifest file 'pytest_redis.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.py'
warning: no files found matching '*.py' under directory 'src/pytest_redis'
no previously-included directories found matching 'docs/build'
adding license file 'AUTHORS.rst'
writing manifest file 'pytest_redis.egg-info/SOURCES.txt'
* Building sdist...
/tmp/build-env-hyjh_zg5/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
  warnings.warn(msg, _BetaConfiguration)
/tmp/build-env-hyjh_zg5/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/home/fizyk/workspace/pytest-redis/LICENSE' cannot be found
  warnings.warn(f"File {path!r} cannot be found")
running sdist
running egg_info
writing pytest_redis.egg-info/PKG-INFO
writing dependency_links to pytest_redis.egg-info/dependency_links.txt
writing entry points to pytest_redis.egg-info/entry_points.txt
writing requirements to pytest_redis.egg-info/requires.txt
writing top-level names to pytest_redis.egg-info/top_level.txt
reading manifest file 'pytest_redis.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.py'
warning: no files found matching '*.py' under directory 'src/pytest_redis'
no previously-included directories found matching 'docs/build'
adding license file 'AUTHORS.rst'
writing manifest file 'pytest_redis.egg-info/SOURCES.txt'
running check
creating pytest-redis-3.0.0
creating pytest-redis-3.0.0/pytest_redis
creating pytest-redis-3.0.0/pytest_redis.egg-info
creating pytest-redis-3.0.0/pytest_redis/executor
creating pytest-redis-3.0.0/pytest_redis/factories
creating pytest-redis-3.0.0/tests
copying files to pytest-redis-3.0.0...
copying AUTHORS.rst -> pytest-redis-3.0.0
copying CHANGES.rst -> pytest-redis-3.0.0
copying CONTRIBUTING.rst -> pytest-redis-3.0.0
copying MANIFEST.in -> pytest-redis-3.0.0
copying README.rst -> pytest-redis-3.0.0
copying pyproject.toml -> pytest-redis-3.0.0
copying setup.cfg -> pytest-redis-3.0.0
copying pytest_redis/__init__.py -> pytest-redis-3.0.0/pytest_redis
copying pytest_redis/config.py -> pytest-redis-3.0.0/pytest_redis
copying pytest_redis/exception.py -> pytest-redis-3.0.0/pytest_redis
copying pytest_redis/plugin.py -> pytest-redis-3.0.0/pytest_redis
copying pytest_redis.egg-info/PKG-INFO -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/SOURCES.txt -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/dependency_links.txt -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/entry_points.txt -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/requires.txt -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/top_level.txt -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis.egg-info/zip-safe -> pytest-redis-3.0.0/pytest_redis.egg-info
copying pytest_redis/executor/__init__.py -> pytest-redis-3.0.0/pytest_redis/executor
copying pytest_redis/executor/noop.py -> pytest-redis-3.0.0/pytest_redis/executor
copying pytest_redis/executor/process.py -> pytest-redis-3.0.0/pytest_redis/executor
copying pytest_redis/factories/__init__.py -> pytest-redis-3.0.0/pytest_redis/factories
copying pytest_redis/factories/client.py -> pytest-redis-3.0.0/pytest_redis/factories
copying pytest_redis/factories/noproc.py -> pytest-redis-3.0.0/pytest_redis/factories
copying pytest_redis/factories/proc.py -> pytest-redis-3.0.0/pytest_redis/factories
copying tests/test_executor.py -> pytest-redis-3.0.0/tests
copying tests/test_redis.py -> pytest-redis-3.0.0/tests
Writing pytest-redis-3.0.0/setup.cfg
Creating tar archive
removing 'pytest-redis-3.0.0' (and everything under it)
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (setuptools >= 61.0.0, wheel)
* Getting build dependencies for wheel...
/tmp/build-env-3oeehqfs/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
  warnings.warn(msg, _BetaConfiguration)
/tmp/build-env-3oeehqfs/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/tmp/build-via-sdist-dzk2xt3i/pytest-redis-3.0.0/LICENSE' cannot be found
  warnings.warn(f"File {path!r} cannot be found")
running egg_info
writing pytest_redis.egg-info/PKG-INFO
writing dependency_links to pytest_redis.egg-info/dependency_links.txt
writing entry points to pytest_redis.egg-info/entry_points.txt
writing requirements to pytest_redis.egg-info/requires.txt
writing top-level names to pytest_redis.egg-info/top_level.txt
reading manifest file 'pytest_redis.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.py'
warning: no files found matching '*.py' under directory 'src/pytest_redis'
no previously-included directories found matching 'docs/build'
adding license file 'AUTHORS.rst'
writing manifest file 'pytest_redis.egg-info/SOURCES.txt'
* Installing packages in isolated environment... (wheel)
* Building wheel...
/tmp/build-env-3oeehqfs/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py:108: _BetaConfiguration: Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*.
  warnings.warn(msg, _BetaConfiguration)
/tmp/build-env-3oeehqfs/lib/python3.11/site-packages/setuptools/config/expand.py:144: UserWarning: File '/tmp/build-via-sdist-dzk2xt3i/pytest-redis-3.0.0/LICENSE' cannot be found
  warnings.warn(f"File {path!r} cannot be found")
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/pytest_redis
copying pytest_redis/exception.py -> build/lib/pytest_redis
copying pytest_redis/plugin.py -> build/lib/pytest_redis
copying pytest_redis/config.py -> build/lib/pytest_redis
copying pytest_redis/__init__.py -> build/lib/pytest_redis
creating build/lib/pytest_redis/executor
copying pytest_redis/executor/process.py -> build/lib/pytest_redis/executor
copying pytest_redis/executor/noop.py -> build/lib/pytest_redis/executor
copying pytest_redis/executor/__init__.py -> build/lib/pytest_redis/executor
creating build/lib/pytest_redis/factories
copying pytest_redis/factories/proc.py -> build/lib/pytest_redis/factories
copying pytest_redis/factories/__init__.py -> build/lib/pytest_redis/factories
copying pytest_redis/factories/client.py -> build/lib/pytest_redis/factories
copying pytest_redis/factories/noproc.py -> build/lib/pytest_redis/factories
running egg_info
writing pytest_redis.egg-info/PKG-INFO
writing dependency_links to pytest_redis.egg-info/dependency_links.txt
writing entry points to pytest_redis.egg-info/entry_points.txt
writing requirements to pytest_redis.egg-info/requires.txt
writing top-level names to pytest_redis.egg-info/top_level.txt
reading manifest file 'pytest_redis.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.py'
warning: no files found matching '*.py' under directory 'src/pytest_redis'
no previously-included directories found matching 'docs/build'
adding license file 'AUTHORS.rst'
writing manifest file 'pytest_redis.egg-info/SOURCES.txt'
warning: build_py: byte-compiling is disabled, skipping.

installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/pytest_redis
copying build/lib/pytest_redis/exception.py -> build/bdist.linux-x86_64/wheel/pytest_redis
creating build/bdist.linux-x86_64/wheel/pytest_redis/executor
copying build/lib/pytest_redis/executor/process.py -> build/bdist.linux-x86_64/wheel/pytest_redis/executor
copying build/lib/pytest_redis/executor/noop.py -> build/bdist.linux-x86_64/wheel/pytest_redis/executor
copying build/lib/pytest_redis/executor/__init__.py -> build/bdist.linux-x86_64/wheel/pytest_redis/executor
copying build/lib/pytest_redis/plugin.py -> build/bdist.linux-x86_64/wheel/pytest_redis
copying build/lib/pytest_redis/config.py -> build/bdist.linux-x86_64/wheel/pytest_redis
creating build/bdist.linux-x86_64/wheel/pytest_redis/factories
copying build/lib/pytest_redis/factories/proc.py -> build/bdist.linux-x86_64/wheel/pytest_redis/factories
copying build/lib/pytest_redis/factories/__init__.py -> build/bdist.linux-x86_64/wheel/pytest_redis/factories
copying build/lib/pytest_redis/factories/client.py -> build/bdist.linux-x86_64/wheel/pytest_redis/factories
copying build/lib/pytest_redis/factories/noproc.py -> build/bdist.linux-x86_64/wheel/pytest_redis/factories
copying build/lib/pytest_redis/__init__.py -> build/bdist.linux-x86_64/wheel/pytest_redis
warning: install_lib: byte-compiling is disabled, skipping.

running install_egg_info
Copying pytest_redis.egg-info to build/bdist.linux-x86_64/wheel/pytest_redis-3.0.0-py3.11.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/pytest_redis-3.0.0.dist-info/WHEEL
creating '/home/fizyk/workspace/pytest-redis/dist/.tmp-4_umboyl/pytest_redis-3.0.0-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'pytest_redis/__init__.py'
adding 'pytest_redis/config.py'
adding 'pytest_redis/exception.py'
adding 'pytest_redis/plugin.py'
adding 'pytest_redis/executor/__init__.py'
adding 'pytest_redis/executor/noop.py'
adding 'pytest_redis/executor/process.py'
adding 'pytest_redis/factories/__init__.py'
adding 'pytest_redis/factories/client.py'
adding 'pytest_redis/factories/noproc.py'
adding 'pytest_redis/factories/proc.py'
adding 'pytest_redis-3.0.0.dist-info/AUTHORS.rst'
adding 'pytest_redis-3.0.0.dist-info/METADATA'
adding 'pytest_redis-3.0.0.dist-info/WHEEL'
adding 'pytest_redis-3.0.0.dist-info/entry_points.txt'
adding 'pytest_redis-3.0.0.dist-info/top_level.txt'
adding 'pytest_redis-3.0.0.dist-info/zip-safe'
adding 'pytest_redis-3.0.0.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Successfully built pytest-redis-3.0.0.tar.gz and pytest_redis-3.0.0-py3-none-any.whl
> cat pytest_redis.egg-info/PKG-INFO | grep License-File                                                                                                                                                                           
License-File: AUTHORS.rst
abravalheri commented 1 year ago

Hi @fizyk, the field License-File is a non-standard field that is different from License.

If you set license in pyproject.toml, the existing standards mandate that the License field reflects that, but not to License-File.

The meaning of setting [project] license = {file = "..."} is that setuptools should read this file and embed its contents into the PKG-INFO/METADATA files. The meaning of License-File however is different: it tells setuptools to copy the file to the .dist-info folder.

By default setuptools will consider the following glob patterns to populate License-File when it is not given: ['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']. Note that this is inline with the draft version of PEP 629.

Sorry if that is a complicated topic, it took me a long time to wrap my head around this. You can have a look on the valuable comments by C.A.M Gerlach (the person that is currently heading the standardisation on License-File) on the Python discourse about this:

I am afraid that until PEP 639 comes out in it's final form and is approved, we are not going to touch License-File (to avoid reworking the implementation multiple times).

If you wish to omit License-File please set something like the following:

[tool.setuptools]
license-files = ["LICENSE"]

Configuration reference: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#setuptools-specific-configuration

(Although I haven't tested it myself... It might be the case that even if setuptools does not add the default files, pypa/wheel will).

fizyk commented 1 year ago

Okay.... but if I have the license = {file = "COPYING.lesser"} entry correctly configured - it points to correct, existing file,

The License-File field is not present in the package metadata ( see https://github.com/ClearcodeHQ/pytest-redis/tree/v3.0.1 )

abravalheri commented 1 year ago

Interesting. Thank you very much for pointing that out. It seems that there is a problem with the JSON schema used to generate the validation code:

https://github.com/abravalheri/validate-pyproject/blob/b7b4c96e1e0252900b399370ff1b0d7346a140ea/src/validate_pyproject/plugins/setuptools.schema.json#L182

That is why "COPYING" and "NOTICE" are not matching but "LI[CS]ENSE" and "AUTHORS" are matching... There are wrong whitespaces in the JSON schema.

I didn't thought it would add the default value (I thought it would use it only as documentation). I will try to fix the discrepancy tomorrow morning. But then, License-File should be present anyway.