This is an automated email from the ASF dual-hosted git repository.
apitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new 866502e6d6 GH-45867: [Python] Fix `SetuptoolsDeprecationWarning`
(#47141)
866502e6d6 is described below
commit 866502e6d64e1e2422bbe7978c7bc3a5617431df
Author: Patrick J. Roddy <[email protected]>
AuthorDate: Thu Dec 18 12:11:45 2025 +0000
GH-45867: [Python] Fix `SetuptoolsDeprecationWarning` (#47141)
### Rationale for this change
When building locally, I get many errors along the lines of
```
Please ensure the files specified are contained by the root
of the Python package (normally marked by `pyproject.toml`).
By 2026-Mar-20, 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/specifications/glob-patterns/
for details.
```
<img width="958" height="755" alt="terminal demo"
src="https://github.com/user-attachments/assets/67f0e261-c4d2-403c-b004-688dfaaccda6"
/>
### What changes are included in this PR?
- Make the licence [SPDX compliant](https://spdx.org/licenses)
- Remove the licence classifier
- Move the licence files from `setup.cfg` to `pyproject.toml`
- Fix the [disallowed glob
patterns](https://packaging.python.org/en/latest/specifications/glob-patterns)
via symlinks
- Bumped the minimum version of `setuptools` due to macOS CI failures
(don't know why this happened, caching maybe?)
I appreciate the symlink change might prove controversial. See discussions
in https://github.com/apache/arrow/issues/45867, fixes
https://github.com/apache/arrow/issues/45867.
### Are these changes tested?
When I rebuild locally, I get no errors any more.
### Are there any user-facing changes?
Yes. The minimum required version of `setuptools` is now `77`. However,
this is available on `>=3.9` so won't affect anyone really.
* GitHub Issue: #45867
Authored-by: Patrick J. Roddy <[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
---
ci/conda_env_python.txt | 2 +-
python/.gitignore | 5 +++++
python/pyproject.toml | 9 ++++++---
python/requirements-build.txt | 2 +-
python/setup.cfg | 5 -----
python/setup.py | 34 +++++++++++++++++++++++++++++++++-
6 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/ci/conda_env_python.txt b/ci/conda_env_python.txt
index 4e3fd9f2de..eddba95a11 100644
--- a/ci/conda_env_python.txt
+++ b/ci/conda_env_python.txt
@@ -28,5 +28,5 @@ numpy>=1.16.6
pytest
pytest-faulthandler
s3fs>=2023.10.0
-setuptools>=64
+setuptools>=77
setuptools_scm>=8
diff --git a/python/.gitignore b/python/.gitignore
index fbc3b19243..dec4ffc1c9 100644
--- a/python/.gitignore
+++ b/python/.gitignore
@@ -45,3 +45,8 @@ pyarrow/_table_api.h
manylinux1/arrow
nm_arrow.log
visible_symbols.log
+
+# the purpose of the custom SDist class in setup.py is to include these files
+# in the sdist tarball, but we don't want to track duplicates
+LICENSE.txt
+NOTICE.txt
diff --git a/python/pyproject.toml b/python/pyproject.toml
index fe812227eb..0a730fd4f7 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -22,7 +22,7 @@ requires = [
# configuring setuptools_scm in pyproject.toml requires
# versions released after 2022
"setuptools_scm[toml]>=8",
- "setuptools>=64",
+ "setuptools>=77",
]
build-backend = "setuptools.build_meta"
@@ -32,9 +32,12 @@ dynamic = ["version"]
requires-python = ">=3.10"
description = "Python library for Apache Arrow"
readme = {file = "README.md", content-type = "text/markdown"}
-license = {text = "Apache Software License"}
+license = "Apache-2.0"
+license-files = [
+ "LICENSE.txt",
+ "NOTICE.txt",
+]
classifiers = [
- 'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
diff --git a/python/requirements-build.txt b/python/requirements-build.txt
index e3fb5bc000..9e03e04ade 100644
--- a/python/requirements-build.txt
+++ b/python/requirements-build.txt
@@ -1,4 +1,4 @@
cython>=3.1
numpy>=1.25
setuptools_scm>=8
-setuptools>=64
+setuptools>=77
diff --git a/python/setup.cfg b/python/setup.cfg
index 3df4ff27ef..b0c3edfa8b 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -15,11 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-[metadata]
-license_files =
- ../LICENSE.txt
- ../NOTICE.txt
-
[build_sphinx]
source-dir = doc/
build-dir = doc/_build
diff --git a/python/setup.py b/python/setup.py
index b6fea83eb0..a27bd3baef 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -23,6 +23,7 @@ import os.path
from os.path import join as pjoin
import re
import shlex
+import shutil
import sys
import warnings
@@ -33,6 +34,7 @@ else:
from distutils import sysconfig
from setuptools import setup, Extension, Distribution
+from setuptools.command.sdist import sdist
from Cython.Distutils import build_ext as _build_ext
import Cython
@@ -395,11 +397,41 @@ class BinaryDistribution(Distribution):
return True
+class CopyLicenseSdist(sdist):
+ """Custom sdist command that copies license files from parent directory."""
+
+ def make_release_tree(self, base_dir, files):
+ # Call parent to do the normal work
+ super().make_release_tree(base_dir, files)
+
+ # Define source (parent dir) and destination (sdist root) for license
files
+ license_files = [
+ ("LICENSE.txt", "../LICENSE.txt"),
+ ("NOTICE.txt", "../NOTICE.txt"),
+ ]
+
+ for dest_name, src_path in license_files:
+ src_full = os.path.join(os.path.dirname(__file__), src_path)
+ dest_full = os.path.join(base_dir, dest_name)
+
+ # Remove any existing file/symlink at destination
+ if os.path.exists(dest_full) or os.path.islink(dest_full):
+ os.unlink(dest_full)
+
+ if not os.path.exists(src_full):
+ msg = f"Required license file not found: {src_full}"
+ raise FileNotFoundError(msg)
+
+ shutil.copy2(src_full, dest_full)
+ print(f"Copied {src_path} to {dest_name} in sdist")
+
+
setup(
distclass=BinaryDistribution,
# Dummy extension to trigger build_ext
ext_modules=[Extension('__dummy__', sources=[])],
cmdclass={
- 'build_ext': build_ext
+ 'build_ext': build_ext,
+ 'sdist': CopyLicenseSdist,
},
)