Skip to content

Conversation

@jameslamb
Copy link
Collaborator

@jameslamb jameslamb commented Jan 20, 2026

Fixes #6665
Replaces #6681

This project uses setuptools when building a Python wheel with a pre-compiled lib_lightgbm.{dll,dylib,so}, like this:

cmake -B build -S .
cmake --build build --target _lightgbm
sh build-python.sh install --precompile

That's helpful for users building with customizations (like the MPI version), and that pattern used in all the TASK=regular CI jobs here.

For a few months, that's been raising warnings about license metadata, warning that a new setuptools in February 2026 may turn those warnings into errors.

warning text (click me)

Warnings below from a recent regular job (build link)

/tmp/build-env-vhotg1gp/lib/python3.13/site-packages/setuptools/config/_apply_pyprojecttoml.py:82: SetuptoolsDeprecationWarning: `project.license` as a TOML table is deprecated
!!

        ********************************************************************************
        Please use a simple string containing a SPDX expression for `project.license`. You can also use `project.license-files`. (Both options available on setuptools>=77.0.0).

        By 2026-Feb-18, you need to update your project and remove deprecated calls
        or your builds will no longer be supported.

        See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
        ********************************************************************************

!!
  corresp(dist, value, root_dir)
/tmp/build-env-vhotg1gp/lib/python3.13/site-packages/setuptools/config/_apply_pyprojecttoml.py:61: SetuptoolsDeprecationWarning: License classifiers are deprecated.
!!

        ********************************************************************************
        Please consider removing the following classifiers in favor of a SPDX license expression:

        License :: OSI Approved :: MIT License

        See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
        ********************************************************************************

!!
  dist._finalize_license_expression()
/tmp/build-env-vhotg1gp/lib/python3.13/site-packages/setuptools/dist.py:759: SetuptoolsDeprecationWarning: License classifiers are deprecated.
!!

        ********************************************************************************
        Please consider removing the following classifiers in favor of a SPDX license expression:

        License :: OSI Approved :: MIT License

        See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license for details.
        ********************************************************************************

!!
  self._finalize_license_expression()

This resolves those warnings with following changes:

  • updating the way license metadata is spelled
  • moving the floor on scikit-build-core to the earliest version that supported PEP 639 (v0.11.0)
  • switching from setuptools to hatchling

I found those specific floors while doing something similar for RAPIDS projects: rapidsai/build-planning#152

Benefits of these changes

  • prevents builds from being broken with newer setuptools this year
  • permanently fixes [python-package] UNKNOWN python package #6665 and reduces the risk of it happening in the future (details below)
  • pulls in fixes, performance improvements, etc. in newer scikit-build-core
  • makes it easier for security and compliance scanners to extract license data from lightgbm installations

Notes for Reviewers

Why scikit-build-core>=0.11.0?

Tat's the first version that support PEP 639 license metadata.

I recently updated all of RAPIDS to that version (rapidsai/build-planning#152) and didn't encounter any problems, so I think it's safe.

why switch to hatchling? how does that affect portability?

hatchling makes --precompile builds of lightgbm more portable and more backwards-compatible than the current setup with setuptools 😁

hatchling is a pure Python package (just a py3-none-any wheel), so it doesn't bring any new constraints on GLIBC version, CPU architecture, or operating system.

It also avoids these setuptools-specific problems:

For these --precompile builds, we only need very very simple Python packaging: create a zip archive out of a directory and write the appropriate wheel metadata. No compiler flags, handling of symlinks, other configuration for sdists, etc.

This is a long-term fix for #6665, replacing #6681 😁 (see #6665 (comment))

why hatchling>=1.27.0 specifically?

hatchling==1.27.0 was the final version to support Python 3.9 (pypa/hatch#2097), the oldest Python lightgbm supports.

@jameslamb jameslamb changed the title WIP: [python-package] use PEP 639 license metadata, 'scikit-build-core>=0.11.0', 'setuptools>=77.0.0' WIP: [python-package] use PEP 639 license metadata, bump toscikit-build-core>=0.11.0, use hatchling instead of setuptools Jan 20, 2026
@microsoft microsoft deleted a comment Jan 20, 2026
BUILD_SDIST=true
BUILD_WHEEL=false
BUILD_SDIST=false
BUILD_WHEEL=true
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

With hatchling we have tighter control over package contents, so --precompile can build a wheel 😁

cd ..
if test "${BUILD_WHEEL}" = true; then
PACKAGE_NAME="$(echo lightgbm*.whl)"
PACKAGE_FILE="$(echo dist/lightgbm*.whl)"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If this echo is portable enough, then we can avoid using --find-links in pip.

Not strictly related to the rest of this change, but just something else I noticed that could help with building from source using build-python.sh.


sudo apt-get -y install python-pip
sudo -H pip install setuptools numpy scipy scikit-learn -U
sudo -H pip install numpy scipy scikit-learn -U
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

setuptools was only helpful here because it gets system installed by apt-get install python-pip on Ubuntu, and so needed to be upgraded.

Any other build-time requirements (like scikit-build-core) don't need to be separately installed by default, because they'll be set up in pip's isolated build environment.


# at this point, if 'install' was passed but the package type wasn't indicated, prefer wheel
if test "${BUILD_SDIST}" = false && test "${BUILD_WHEEL}" = false; then
echo "[INFO] 'install' passed but no package type ('bdist_wheel', 'sdist') chosen. Defaulting to 'bdist_wheel'."
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Test like this:

$ sh build-python.sh install
...
[INFO] 'install' passed but no package type ('bdist_wheel', 'sdist') chosen. Defaulting to 'bdist_wheel'.
[INFO] --- building wheel ---
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - scikit-build-core>=0.11.0
* Getting build dependencies for wheel...
* Building wheel...
...
Successfully built lightgbm-4.6.0.99-py3-none-macosx_14_0_arm64.whl
[INFO] --- installing lightgbm ---
Processing ./dist/lightgbm-4.6.0.99-py3-none-macosx_14_0_arm64.whl
Installing collected packages: lightgbm
  Attempting uninstall: lightgbm
    Found existing installation: lightgbm 4.6.0.99
    Uninstalling lightgbm-4.6.0.99:
      Successfully uninstalled lightgbm-4.6.0.99
Successfully installed lightgbm-4.6.0.99


sudo apt-get -y install python-pip
sudo -H pip install setuptools numpy scipy scikit-learn -U
sudo apt-get -y install python3-pip python3-venv
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

python3-venv is required because now these commands build a wheel (not an sdist), with build isolation.

Found that in testing on Ubuntu 22.04: #6665 (comment)

echo "" >> ./MANIFEST.in

# replace build backend configuration
cat >> ./pyproject.toml <<EOF
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using heredocs for readability. See this old review thread: #6681 (comment)

@jameslamb jameslamb changed the title WIP: [python-package] use PEP 639 license metadata, bump toscikit-build-core>=0.11.0, use hatchling instead of setuptools [python-package] use PEP 639 license metadata, bump toscikit-build-core>=0.11.0, use hatchling instead of setuptools Jan 20, 2026
@jameslamb jameslamb marked this pull request as ready for review January 20, 2026 13:05
Copy link
Collaborator

@borchero borchero left a comment

Choose a reason for hiding this comment

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

Nice! Big fan of hatchling ;)

@jameslamb
Copy link
Collaborator Author

Thanks @borchero . Yeah I've started trying it out recently and am really liking it!

Inspired by pyOpenSci's write-up here: https://www.pyopensci.org/python-package-guide/package-structure-code/python-package-build-tools.html#about-hatch

(cc @ucodery @lwasser thanks 😊)

@jameslamb jameslamb merged commit 6af94aa into master Jan 21, 2026
76 checks passed
@jameslamb jameslamb deleted the spdx-license-data branch January 21, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[python-package] UNKNOWN python package

3 participants