-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Hi setuptools devs, I'd like to use this issue to summarize issues in the interaction between setuptools
and numpy.distutils
, and then see if we can find a way to resolve those structurally.
The setuptools 50.0
release gave NumPy and SciPy (a heavy numpy.distutils
users) a number of concrete problems:
- gh-2368,
CCompiler_spawn() got an unexpected keyword argument 'env'
, also reported to NumPy at distutils MSVC: CCompiler_spawn() got an unexpected keyword argument 'env' numpy/numpy#17216 - setuptools >= 48.0.0 broken in AIX for Python 3.7 #2367, AIX build of SciPy broken, also reported to SciPy at Scipy build failure in AIX with Python 3.7 scipy/scipy#12797
- WIP: CI: try building with setuptools 50.0 numpy/numpy#17209, CI break in NumPy,
from distutils import sysconfig
broken on TravisCI - WIP: BLD: try to fix build with setuptools 50.0 on Windows scipy/scipy#12798, SciPy CI breakage due to a valid LDFLAGS fix showing up in
setuptools._distutils
, which gave the SciPy build a new-ffat-lto-objects
that it couldn't handle. - There's likely more that's not yet reported; wheel builds of multiple packages using older NumPy versions that haven't pinned
setuptools
are definitely broken. Same for CI/deployment pipelines on ARM64 and other platforms that don't have wheels.
All of the above are resolvable. The bigger issue here is the interaction between distutils
, numpy.distutils
and setuptools
. Due to setuptools
release cadence, such breaks will keep on happening due to incompatibilities between numpy.distutils
and setuptools
. Let me summarize the issue, and then some options for dealing with it.
Old situation, for setuptools <50.0:
numpy.distutils
extends and monkeypatchesdistutils
.- the import order in NumPy and SciPy
setup.py
is:
import setuptools # unused, just to let setuptools do its monkeypatching dance first
from numpy.distutils.core import setup
This situation worked reasonably well, because:
distutils
moved slowly- larger
distutils
changes typically showed up in pre-releases of new Python versions, or in bugfix releases (say 3.7.7) that vendors like Anaconda qualify before they ship it, so we could adjustnumpy.distutils
to those changes setuptools
didn't do all that much that was relevant build-wise
New situation, for setuptools 50.0:
(default situation, no env var set)
setuptools
replacesdistutils
with its vendoredsetuptools._distutils
, even if plaindistuils
is imported firstnumpy.distutils
is unchanged, so it still extends and monkeypatchesdistutils
- which is nowsetuptools._distutils
So numpy.distutils
finds itself monkeypatching setuptools
code all of sudden, and that
setuptools
code includes patches from Python 3.9-dev that are therefore now released into the wild with new setuptools
releases without any alpha/beta/QA trajectory like we had before.
The releasing new patches quickly without testing will still be an issue for numpy.distutils
probably, even if the SETUPTOOLS_USE_DISTUTILS="local"
behaviour gets reverted for the time being (which seems likely, since there's a ton of other issues right now, like the Debian breakage).
What now?
Longer-term I don't think it's feasible for numpy.distutils
to work as it does today and extend setuptools
; the release cycle mismatch will be too much of a problem. I'm not quite sure what the best solution for that is though. Options could include:
- for every NumPy release, add a hard
setuptools <= current_setuptools_version
constraint (NumPy releases get supported for 2.5 years by most of the scientific ecosystem though (i.e. ~50% of Python's user base), so that'll mean pretty oldsetuptools
versions for building, e.g., wheels of packages that rely on NumPy - example: scikit-learn needs to build with NumPy 1.13.3 right now, so it would get setuptools 36.5) - make
numpy.distutils
a standalone package on top ofsetuptools
(then at least release cycle can be matched, but situation remains unstable) - integrate
numpy.distutils
intosetuptools
(more testing will then be done before setuptools releases and no extending/monkeypatching is needed, but is it a good idea knowledge and work load sharing wise?)
Let me emphasize that I do see the upsides in merging disutils
into setuptools
, both design and maintenance wise. And we (NumPy & scientific packages) have been burned in the past by distutils
patches going unmerged for ages, so setuptools
being better maintained is great.
Also, for context, it may be useful to list what numpy.distutils
adds besides carrying around needed distutils
patches:
- Fortran build support
- SIMD intrinsics support
- BLAS/LAPACK library support (OpenBLAS, MKL, ATLAS, Netlib LAPACK/BLAS, BLIS, 64-bit ILP interface, etc.)
- Support for a few other scientific libraries, like FFTW and UMFPACK (less often used)
- Better MinGW support
- Per-compiler build flag customization (e.g.
-O3
andSSE2
flags are default) - EDIT: a simple user build config system, see site.cfg.example
Looking forward to hearing your thoughts on this topic.