Skip to content

Conversation

@rgommers
Copy link
Member

@rgommers rgommers commented Aug 9, 2025

Ready for review; opened as Draft because I need to check if anything changes in wheel builds related to this.

@rgommers rgommers added this to the 2.4.0 release milestone Aug 9, 2025
@rgommers rgommers added 01 - Enhancement 14 - Release 36 - Build Build related PR Meson Items related to the introduction of Meson as the new build system for NumPy labels Aug 9, 2025
Copy link
Member

@mattip mattip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Two small nits.

@charris
Copy link
Member

charris commented Aug 10, 2025

LGTM AFAICT, I'm not familiar with the details of PEP 639, and it looks quite involved.

@rgommers rgommers marked this pull request as ready for review August 10, 2025 10:25
@rgommers
Copy link
Member Author

This is good to go now. Tested wheel builds as well on my fork, logs here.

@mattip
Copy link
Member

mattip commented Aug 11, 2025

I downloaded and inspected a wheel built on the fork. It has (as expected) an additional licenses directory in the numpy-2.4.0.dev0.dist-info directory, that includes the licenses as specified in the pyproject.toml. Is there anything additional I should look at that is changed by this PR?

@rgommers
Copy link
Member Author

No nothing else to look at that I can think of.

@mattip mattip merged commit 6454df5 into numpy:main Aug 11, 2025
77 checks passed
@mattip
Copy link
Member

mattip commented Aug 11, 2025

Thanks @rgommers

@oscarbenjamin
Copy link

I just changed python-flint to use PEP 639 (flintlib/python-flint#321) and thought I would come and see what numpy was doing with it (python-flint's previous approach was copied from numpy).

If I understand correctly this PR was about things that are vendored directly but does not update the license expression for things that are bundled into numpy's wheels by auditwheel. Their license files are included but are still all concatenated into one file. For python-flint I made a script that handles these two steps so it can be used like:

[tool.cibuildwheel.linux]
before-all = "bin/cibw_before_all_linux_$(uname -m).sh"
before-build = "pip install wheel auditwheel"
repair-wheel-command = [
"""bin/cibw_repair_wheel_licenses.py {wheel} \
    --license LGPL-3.0-or-later \
    --license-file '.local/src/gmp-*/COPYING:python-flint.libs/gmp-*/COPYING' \
    --license-file '.local/src/gmp-*/COPYING.LESSERv3:python-flint.libs/gmp-*/COPYING.LESSERv3' \
    --license-file '.local/src/mpfr-*/COPYING:python-flint.libs/mpfr-*/COPYING' \
    --license-file '.local/src/mpfr-*/COPYING.LESSER:python-flint.libs/mpfr-*/COPYING.LESSER' \
    --license-file '.local/src/flint-*/COPYING:python-flint.libs/flint-*/COPYING' \
    --license-file '.local/src/flint-*/COPYING.LESSER:python-flint.libs/flint-*/COPYING.LESSER' \
""",
"auditwheel repair -w {dest_dir} {wheel}",
]

The script copies each license file separately into the wheel and combines the license expressions into a single SPDX expression.

Inside the wheels it is:

$ tree python_flint.libs/
python_flint.libs/
├── libflint-db910cfb.so.21.0.0
├── libgmp-b288de48.so.10.5.0
└── libmpfr-a43da5fb.so.6.2.2

$ tree python_flint-0.8.0.dist-info/
python_flint-0.8.0.dist-info/
├── licenses
│   ├── LICENSE
│   └── python-flint.libs
│       ├── flint-3.3.1
│       │   ├── COPYING
│       │   └── COPYING.LESSER
│       ├── gmp-6.3.0
│       │   ├── COPYING
│       │   └── COPYING.LESSERv3
│       └── mpfr-4.2.2
│           ├── COPYING
│           └── COPYING.LESSER
├── METADATA
├── RECORD
└── WHEEL

$ grep License- python_flint-0.8.0.dist-info/METADATA 
License-Expression: MIT AND LGPL-3.0-or-later
License-File: LICENSE
License-File: python-flint.libs/gmp-6.3.0/COPYING
License-File: python-flint.libs/gmp-6.3.0/COPYING.LESSERv3
License-File: python-flint.libs/mpfr-4.2.2/COPYING
License-File: python-flint.libs/mpfr-4.2.2/COPYING.LESSER
License-File: python-flint.libs/flint-3.3.1/COPYING
License-File: python-flint.libs/flint-3.3.1/COPYING.LESSER

Ideally there would be some common tooling to do this and it would be integrated with tools like auditwheel because you probably need this every time you use auditwheel. Also auditwheel is the only tool that knows what files were actually bundled and really you want that to be checked to see that the licenses (among other things) are accounted for.

In the mean time feel free to adapt that script if it is helpful. It only does wheels (not the sdist).

The extra bits in numpy's concatenated licenses are these parts preceding each license text:

Name: GCC runtime library
Files: numpy.libs/libgfortran*.so
Description: dynamically linked to files compiled with gcc
Availability: https://gcc.gnu.org/git/?p=gcc.git;a=tree;f=libgfortran

I haven't included that because I wanted to preserve the upstream license files byte for byte if possible and I was not sure where to put this extra information. Is it important to have that stuff?

@rgommers
Copy link
Member Author

@oscarbenjamin thanks for sharing, that is very useful! I like your approach. I opened numpy/numpy-release#11 to track changing to this method.

I haven't included that because I wanted to preserve the upstream license files byte for byte if possible and I was not sure where to put this extra information. Is it important to have that stuff?

It's not critical I'd say. If we wanted to preserve it, a good place to add it could be in a LICENSES/README.md file. I agree that preserving upstream licenses unchanged is a good goal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

01 - Enhancement 14 - Release 36 - Build Build related PR Meson Items related to the introduction of Meson as the new build system for NumPy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants