-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BLD: default to Meson in pyproject.toml #16187
Conversation
As the current version of the I thought about it some more, and this isn't just going to be painful for building PyPI artifacts, it's a problem in general:
The above is true not just for SciPy, but for any complex package. So why do So, tentative conclusion 1: The second part of this is: what should the SciPy sdist on PyPI look like? Should it mirror as closely as possible what's in the corresponding release tag in the repo (e..g,
It's not at all obvious that that's the right thing to do. Sdist's have multiple purposes, and the So, tentative conclusion 2: SciPy sdists on PyPI should no longer contain Thoughts? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get to the second set of detailed questions yet, but my comments/concerns are perhaps the most obvious ones:
- These adjustments to
pyproject.toml
hardly seem to fit with its original purpose, it would be great if the need for developer flexibility could simply be enforced with a build flag similar to--no-build-isolation
--this is definitely not possible? And we can't accomplish ameson
/mesonpy
override with a[tool]
type field inpyproject.toml
instead of purging out our pins? - The relationship to the ongoing work in MAINT, BLD: cibuildwheel Linux start #15925 with
cibuildwheel
isn't clear to me--there seem to be some areas that overlap, and the desired incantation for producing release artifacts is getting confusing for me now (which one is the "driver?" I would have thought we'd aim forcibuildwheel
as the driver, but not sure on thesdist
part...)
tools/build-pypi-artifacts.py
Outdated
an environment that has the correct dependencies already | ||
installed. If there's a mismatch in, for example, the version | ||
of numpy that is installed in the (CI) environment compared to | ||
what's specified in `pyproject.toml`, an error will be raised. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it may be good to clarify the relationship with cibuildwheel
here. I was kind of hoping I'd be able to swap the build backend and method of providing OpenBLAS/gfortran stuff and then be ready to swap, but perhaps that's a bit optimistic.
Having two potential/custom routes to PyPI wheel generation is confusing to me though, so we should sort it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be only one way. Look at this like this:
cibuildwheel
(or the currentscipy-wheels
repo based onmultibuild
) are meant to (a) set up the environments needed build wheels for PyPI, and (b) provide a means to trigger those builds.- Both
cibuildwheel
andmultibuild
need to run one single command, e.g.pip wheel
orpython -m build
, to actually build the wheel after all of the environment setup (and maybe applying some patches). Currently that ispython setup.py bdist_wheel
. We need a replacement for that - which has to come from this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, I would like to have more of the logic of what is now in scipy-wheels/cibuildwheel CI config files to live in scripts, so that it can be tested and debugged locally rather than only in CI itself. That's always a good thing.
pyproject.toml
Outdated
@@ -60,6 +45,7 @@ maintainers = [ | |||
# https://scipy.github.io/devdocs/dev/core-dev/index.html#version-ranges-for-numpy-and-other-dependencies | |||
requires-python = ">=3.8" | |||
dependencies = [ | |||
# TODO: update to "pin-compatible" once possible, see https://github.com/FFY00/meson-python/issues/29 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pin-compatible
is going to be a PyPI package or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it should be a string that meson-python
dynamically replaces to >=<version-at-build_time>
. So if you build against numpy 1.18.5, this will say >=1.18.5
(now our lowest-supported version), if you build against 1.22.1, then >=1.22.1
, etc. This will solve a long-standing issue where our install_requires
for numpy
is simply wrong when users build wheels, or even when we build wheels for PyPI where due to Python or platform version support the numpy version we build against is not the lowest-supported one.
The actual syntax of this still needs to be finalized, see mesonbuild/meson-python#29.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds a bit like what you'd get from using setup_requires with unversioned numpy, and then an install_requires that is dynamically calculated using homebrew functions in setup.py based on whichever version got installed... which setuptools may not have ever supported because you'd need to calculate that after the build requirements got installed and calculated. At least it would definitely work if you installed numpy before running ye olde python3 setup.py install
.
I can see why you'd want proper support for that in the build backend, lol.
Good question, let me write a (long) problem statement and distutils/meson comparison later today. That will make the problems we're running into clearer. Re "its original purpose," that is part of the problem - there isn't just a single purpose, there are multiple - and it's not even written down clearly which ones those are. It's mostly a handwavy "allow tools like
Let me repeat here what I just wrote in an inline comment:
|
This is the state with SciPy's current main branch at commit 7076a90 for the
For completeness, this is the diff of the one commit on top of diff --git a/pyproject.toml b/pyproject.toml
index 1b44bc54e..f5c49aab6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,9 @@
# "pybind11>=2.4.3,<2.5.0",
[build-system]
+build-backend = 'mesonpy'
requires = [
+ "meson-python>=0.4.0",
"wheel",
"setuptools<60.0", # do not increase, 60.0 enables vendored distutils
"Cython>=0.29.18", Note that I do Behavior of sdist/wheel build and install commandsGenerating an sdistWith $ python setup.py sdist
$ ls dist
scipy-1.9.0.dev0+2035.7076a90.tar.gz $ python -m build --sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for sdist...
running egg_info
...
$ ls dist
scipy-1.9.0.dev0+2035.7076a90.tar.gz $ python -m build --sdist --no-isolation
ERROR Missing dependencies:
numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy' Note that the above is actually a difference between $ python -m build --sdist --no-isolation --skip-dependency-check
* Building sdist..
$ ls dist
scipy-1.9.0.dev0+2035.7076a90.tar.gz Conclusion for
The default With $ python -m build --sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, meson-python>=0.4.0, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for sdist...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-0riomdni/build
...
* Installing packages in isolated environment... (pep621 >= 0.3.0)
* Building sdist...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-48mc7pbv/build
...
+ meson dist --no-tests --formats gztar
$ ls dist
scipy-1.9.0.dev0.tar.gz Full output of the above (only irrelevant Cython-related warnings omitted):
$ python -m build --sdist --no-isolation
ERROR Missing dependencies:
numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy'
$ python -m build --sdist --no-isolation --skip-dependency-check
* Building sdist...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-2_x1cita/build
$ ls dist
scipy-1.9.0.dev0.tar.gz Full output of the above (only irrelevant Cython-related warnings omitted): $ python -m build --sdist --no-isolation --skip-dependency-check
* Building sdist...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-2_x1cita/build
The Meson build system
Version: 0.62.1
Source dir: /home/rgommers/code/bldscipy
Build dir: /home/rgommers/code/bldscipy/.mesonpy-2_x1cita/build
Build type: native build
Project name: SciPy
Project version: 1.9.0.dev0
C compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc (gcc 9.4.0 "x86_64-conda-linux-gnu-cc (GCC) 9.4.0")
C linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc ld.bfd 2.36.1
C++ compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-c++ (gcc 9.4.0 "x86_64-conda-linux-gnu-c++ (GCC) 9.4.0")
C++ linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-c++ ld.bfd 2.36.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Compiler for C supports arguments -Wno-unused-but-set-variable: YES
Library m found: YES
Fortran compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-gfortran (gcc 9.4.0 "GNU Fortran (GCC) 9.4.0")
Fortran linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-gfortran ld.bfd 2.36.1
Program cython found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/cython)
Program pythran found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/pythran)
Program cp found: YES (/usr/bin/cp)
Program python3 found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/python3.10)
Found pkg-config: /home/rgommers/anaconda3/envs/scipy-dev/bin/pkg-config (0.29.2)
Library npymath found: YES
Library npyrandom found: YES
Run-time dependency openblas found: YES 0.3.18
Dependency openblas found: YES 0.3.18 (cached)
Program _build_utils/cythoner.py found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/python3.10 /home/rgommers/code/bldscipy/scipy/_build_utils/cythoner.py)
Checking for function "open_memstream" : NO
Configuring messagestream_config.h using configuration
Checking for size of "void*" : 8
Run-time dependency threads found: YES
Checking for size of "void*" : 8
Dependency threads found: YES unknown (cached)
Compiler for C supports arguments -Wno-unused-but-set-variable: YES (cached)
Compiler for C supports arguments -Wno-unused-but-set-variable: YES (cached)
Compiler for C++ supports arguments -Wno-format-truncation: YES
Compiler for C++ supports arguments -Wno-class-memaccess: YES
Build targets in project: 199
SciPy 1.9.0.dev0
User defined options
Native files: /home/rgommers/code/bldscipy/.mesonpy-native-file.ini
debug : false
optimization: 2
prefix : /home/rgommers/anaconda3/envs/scipy-dev
strip : true
Found ninja-1.10.2.git.kitware.jobserver-1 at /home/rgommers/anaconda3/envs/scipy-dev/bin/ninja
+ meson dist --no-tests --formats gztar
Created /home/rgommers/code/bldscipy/.mesonpy-2_x1cita/build/meson-dist/SciPy-1.9.0.dev0.tar.gz
Successfully built scipy-1.9.0.dev0.tar.gz
Conclusion for
Comparison between
Generating a wheelThese are the ways of generating a wheel, and all except the
With $ python setup.py bdist_wheel
$ ls dist
scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl $ pip wheel .
Processing /home/rgommers/code/bldscipy
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting numpy>=1.18.5
Downloading numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.8/16.8 MB 4.7 MB/s eta 0:00:00
Saved ./numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Building wheels for collected packages: scipy
Building wheel for scipy (pyproject.toml) ...
Created wheel for scipy: filename=scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl size=27155214 sha256=5f00c67ac877961a3e3c84974138e1260077ac9940f549b4414495cf66318797
Stored in directory: /tmp/pip-ephem-wheel-cache-t6yc2x4j/wheels/ac/02/47/5c5589c7e259950e575a7271d3d3625c505da9fba9ad6879c7
Successfully built scipy
$ ls *.whl
$ ls *.whl
numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl $ pip wheel . --no-build-isolation
Processing /home/rgommers/code/bldscipy
Preparing metadata (pyproject.toml) ... done
Collecting numpy>=1.18.5
Using cached numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.8 MB)
Saved ./numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Building wheels for collected packages: scipy
Building wheel for scipy (pyproject.toml) ... done
Created wheel for scipy: filename=scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl size=26948340 sha256=61fd32d04865dd38038cbb69acf21ec6255e7f04421f03591b55e7b8342939e4
Stored in directory: /tmp/pip-ephem-wheel-cache-8uhol9ge/wheels/ac/02/47/5c5589c7e259950e575a7271d3d3625c505da9fba9ad6879c7
Successfully built scipy
(scipy-dev) rgommers@machine:~/code/bldscipy (main)$ ls *.whl
numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl Note on the above: not sure what's going on there exactly, but $ python -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
$ ls dist
scipy-1.9.0.dev0+2035.7076a90.tar.gz
scipy-1.9.0.dev0+7076a90.7076a90-cp310-cp310-linux_x86_64.whl Note that something is going wrong with the wheel filename (commit hash is repeated), that seems to be a minor bug somewhere. More detailed output of the above (note that $ python -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for sdist...
running egg_info
creating scipy.egg-info
writing scipy.egg-info/PKG-INFO
writing dependency_links to scipy.egg-info/dependency_links.txt
writing requirements to scipy.egg-info/requires.txt
writing top-level names to scipy.egg-info/top_level.txt
writing manifest file 'scipy.egg-info/SOURCES.txt'
reading manifest file 'scipy.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*_subr_*.f' found under directory 'scipy/linalg/src/id_dist/src'
no previously-included directories found matching 'benchmarks/env'
no previously-included directories found matching 'benchmarks/results'
no previously-included directories found matching 'benchmarks/html'
no previously-included directories found matching 'benchmarks/scipy'
no previously-included directories found matching 'doc/build'
no previously-included directories found matching 'doc/source/generated'
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*~' found anywhere in distribution
warning: no previously-included files matching '*.bak' found anywhere in distribution
warning: no previously-included files matching '*.swp' found anywhere in distribution
warning: no previously-included files matching '*.pyo' found anywhere in distribution
adding license file 'LICENSE.txt'
adding license file 'LICENSES_bundled.txt'
writing manifest file 'scipy.egg-info/SOURCES.txt'
* Building sdist...
Running from SciPy source directory.
...
Creating tar archive
removing 'scipy-1.9.0.dev0+2035.7076a90' (and everything under it)
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for wheel...
running egg_info
...
writing manifest file 'scipy.egg-info/SOURCES.txt'
* Installing packages in isolated environment... (wheel)
* Building wheel...
Running from SciPy source directory.
Cythonizing sources
Running scipy/stats/_generate_pyx.py
Successfully built scipy-1.9.0.dev0+2035.7076a90.tar.gz and scipy-1.9.0.dev0+7076a90.7076a90-cp310-cp310-linux_x86_64.whl $ python -m build --wheel
* Creating venv isolated environment...
* Installing packages in isolated environment... (Cython>=0.29.18, numpy; python_version>='3.11', numpy; python_version>='3.8' and platform_python_implementation=='PyPy', numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.2; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy', numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_python_implementation != 'PyPy', numpy==1.20.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.20.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin', numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy', pybind11>=2.4.3, pythran>=0.9.12, setuptools<60.0, wheel)
* Getting dependencies for wheel...
running egg_info
* Installing packages in isolated environment... (wheel)
* Building wheel...
Running from SciPy source directory.
Cythonizing sources
$ ls dist
scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl $ python -m build --wheel --no-isolation
ERROR Missing dependencies:
numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy' $ python -m build --wheel --no-isolation --skip-dependency-check
* Building wheel...
$ ls dist
scipy-1.9.0.dev0+2035.7076a90-cp310-cp310-linux_x86_64.whl Conclusion for Related conclusion: if sdists are all the same and match the ones we upload to PyPI, and wheels are very different from those we upload to PyPI, there is no direct correspondence between sdist and wheels on PyPI. And this is fine/expected. For completeness, here are the libraries we vendor into released wheels (example from unpacking from PyPI):
With Note that wheel generation with
Note that this error is unexpected and should be fixed, I filed https://github.com/FFY00/meson-python/issues/52. I will update this section once that is done. For now I'll continue with $ pip wheel . --no-build-isolation
Processing /home/rgommers/code/bldscipy
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: scipy
Building wheel for scipy (pyproject.toml) ... done
Created wheel for scipy: filename=scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl size=23844483 sha256=87750bbf0eebfaab7583fea5376bb6afb3635edda35977a4e86e801e299e10ff
Stored in directory: /tmp/pip-ephem-wheel-cache-mj5tc2hi/wheels/ac/02/47/5c5589c7e259950e575a7271d3d3625c505da9fba9ad6879c7
Successfully built scipy
$ ls *.whl
scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl $ python -m build --wheel --no-isolation
ERROR Missing dependencies:
numpy==1.21.4; python_version=='3.10' and platform_python_implementation != 'PyPy'
patchelf-wrapp This is the same error as when running this wheel build command with $ python -m build --wheel --no-isolation --skip-dependency-check
* Building wheel...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/build
...
+ meson compile
[1565/1565] Linking target scipy/sparse/sparsetools/_sparsetools.cpython-310-x86_64-linux-gnu.so
+ meson install --destdir /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/install
ninja: Entering directory `/home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/build'
Installing scipy/_lib/_ccallback_c.cpython-310-x86_64-linux-gnu.so to /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/install/home/rgommers/anaconda3/envs/scipy-dev/lib/python3.10/site-packages/scipy/_lib
Stripping target 'scipy/_lib/_ccallback_c.cpython-310-x86_64-linux-gnu.so'.
Copying files to wheel...
[1213/1213] scipy/io/_harwell_boeing/tests/test_hb.pyy
Successfully built scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl
$ ls dist
scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl More detailed output: $ python -m build --wheel --no-isolation --skip-dependency-check
* Building wheel...
+ meson setup --native-file=/home/rgommers/code/bldscipy/.mesonpy-native-file.ini -Ddebug=false -Dstrip=true -Doptimization=2 --prefix=/home/rgommers/anaconda3/envs/scipy-dev /home/rgommers/code/bldscipy /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/build
The Meson build system
Version: 0.62.1
Source dir: /home/rgommers/code/bldscipy
Build dir: /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/build
Build type: native build
Project name: SciPy
Project version: 1.9.0.dev0
C compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc (gcc 9.4.0 "x86_64-conda-linux-gnu-cc (GCC) 9.4.0")
C linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc ld.bfd 2.36.1
C++ compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-c++ (gcc 9.4.0 "x86_64-conda-linux-gnu-c++ (GCC) 9.4.0")
C++ linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-c++ ld.bfd 2.36.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
Compiler for C supports arguments -Wno-unused-but-set-variable: YES
Library m found: YES
Fortran compiler for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-gfortran (gcc 9.4.0 "GNU Fortran (GCC) 9.4.0")
Fortran linker for the host machine: /home/rgommers/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-gfortran ld.bfd 2.36.1
Program cython found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/cython)
Program pythran found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/pythran)
Program cp found: YES (/usr/bin/cp)
Program python3 found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/python3.10)
Found pkg-config: /home/rgommers/anaconda3/envs/scipy-dev/bin/pkg-config (0.29.2)
Library npymath found: YES
Library npyrandom found: YES
Run-time dependency openblas found: YES 0.3.18
Dependency openblas found: YES 0.3.18 (cached)
Program _build_utils/cythoner.py found: YES (/home/rgommers/anaconda3/envs/scipy-dev/bin/python3.10 /home/rgommers/code/bldscipy/scipy/_build_utils/cythoner.py)
Checking for function "open_memstream" : NO
Configuring messagestream_config.h using configuration
Checking for size of "void*" : 8
Run-time dependency threads found: YES
Checking for size of "void*" : 8
Dependency threads found: YES unknown (cached)
Compiler for C supports arguments -Wno-unused-but-set-variable: YES (cached)
Compiler for C supports arguments -Wno-unused-but-set-variable: YES (cached)
Compiler for C++ supports arguments -Wno-format-truncation: YES
Compiler for C++ supports arguments -Wno-class-memaccess: YES
Build targets in project: 199
SciPy 1.9.0.dev0
User defined options
Native files: /home/rgommers/code/bldscipy/.mesonpy-native-file.ini
debug : false
optimization: 2
prefix : /home/rgommers/anaconda3/envs/scipy-dev
strip : true
+ meson compile
[1565/1565] Linking target scipy/sparse/sparsetools/_sparsetools.cpython-310-x86_64-linux-gnu.so
+ meson install --destdir /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/install
ninja: Entering directory `/home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/build'
Installing scipy/_lib/_ccallback_c.cpython-310-x86_64-linux-gnu.so to /home/rgommers/code/bldscipy/.mesonpy-1q_dj_tb/install/home/rgommers/anaconda3/envs/scipy-dev/lib/python3.10/site-packages/scipy/_lib
Stripping target 'scipy/_lib/_ccallback_c.cpython-310-x86_64-linux-gnu.so'.
Copying files to wheel...
[1213/1213] scipy/io/_harwell_boeing/tests/test_hb.pyy
Successfully built scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl Comparison between We get similar wheels from both build systems. The differences include:
Installing from a repo or an sdistInstalling from a repo or sdist is interesting, because (a) it still invokes the build system, and (b) many users, contributors, and packagers have to do this. I'm not considering installing from wheels, because that's unrelated to build system hooks and a much simpler problem - Ways to install from a repo or an sdist:
Side note: I'm not considering editable installs here; those are not currently possible with With I will not show the output of each of these methods, but just state that they all work today. Instead, I will explain what the key things to keep in mind are:
With $ pip install . # TODO, runs into the patchelf-wrapper issue $ pip install . --no-build-isolation
Processing /home/rgommers/code/bldscipy
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: scipy
Building wheel for scipy (pyproject.toml) ... done
Created wheel for scipy: filename=scipy-1.9.0.dev0-cp310-cp310-linux_x86_64.whl size=23844482 sha256=18c2e0e7e9ab7a140a2f2d573af3b4001432cc7c6aa1c038541508d221067fc9
Stored in directory: /tmp/pip-ephem-wheel-cache-2twxir85/wheels/ac/02/47/5c5589c7e259950e575a7271d3d3625c505da9fba9ad6879c7
Successfully built scipy
Installing collected packages: scipy
Successfully installed scipy-1.9.0.dev0 $ pip install . --no-use-pep517
Processing /home/rgommers/code/bldscipy
ERROR: Disabling PEP 517 processing is invalid: project specifies a build backend of mesonpy in pyproject.toml Added $ python -m build --wheel --no-isolation --skip-dependency-check && pip install dist/scipy*.whl
...
$ pip list
...
scipy 1.9.0.dev0 Comparison between Overall behavior is similar (aside from build performance:) ); turning build isolation on/off is the most important factor in behavior. The differences noted for wheel builds apply similarly to installs from source (repo or sdist). Update on recommendations for changesNow that I've written all this, let me get back to my "tentative conclusions" in the comment higher up. Tentative conclusion 1: meson-python should include changes to files tracked in git but not committed, that's better all around. This one I'm very confident about. It will be very confusing to continue ignoring local changes that aren't committed, plus it leads to serious issues when trying to apply patches (both for us when building release wheels, and for any downstream packagers - they all carry patches). I don't think there's a serious case to make for keeping the current behavior, the upside is very minor and the problems it creates are real. EDIT: I opened https://github.com/FFY00/meson-python/issues/53 for this. Tentative conclusion 2: SciPy sdists on PyPI should no longer contain numpy== pins, to keep sdists usable with pip install for all packaging systems. This one I'm a lot less confident about after writing all this. There's actually 3 flavors to consider:
@FFY00 first dropped these pins for I'm still convinced that (2) isn't great: numpy pins should not be different between For option (3), the pros and cons are:
So tl;dr - I think we can stay with
I will update this PR to follow these recommendations, and see if it then all works as expected or not. |
527db52
to
6ee0fd5
Compare
Ugh, the 32-bit Linux job is a real pain. It downloads The other custom I think I'll give up on that job for now. Once Ubuntu Jammy (22.04 LTS) has 32-bit Docker images available we can simply use those; that release has OpenBLAS |
6d6e542
to
4639f47
Compare
4639f47
to
d6f553e
Compare
Okay, this is finally looking more or less happy. It's not mergeable yet, there are a couple of things left to do:
|
I have been mulling over this for a bit, and... it seems that the main problem, really, is tied to using So what's happening?
That is, if you'll excuse me, a very... pythonic... way of thinking. Not everyone agrees that serious projects should do releases via CI, particularly if they need to do things like PGP-sign those releases (technically possible with PyPI, but the website will do its utmost to hide the signature files, so even the people who bothered with them, generally got the hint being messaged by PyPA, and stopped). It also lets you trivially test that patches pass a full distcheck, and But also -- it makes it very easy to manage. Files not checked into git are likely not important to be distributed. Meson can also use gitattributes to remove files (like Meson does provide functionality in case what you want to distribute isn't exactly what is in the state of the repository. You can use Alternatively, you may want to do without ... What would be the best thing to use? I don't know, there are pros and cons to a bunch of different approaches. The thing that most stands out to me, however, is not about what makes the best sdist. It's what you do with an sdist.
Either way, this bears repeating:
This has been considered an acceptable tradeoff in the initial Meson implementation, which had a target audience of project maintainers cutting new releases, but does not fit well with the idea that end users might be expected to do this in order to install the software. End users should not be running maintainer-dist processes unexpectedly. I don't know if the answer is to "not use |
Assuming no changes in the build backend or meson, the following should be more or less workable:
|
Thanks for the detailed thoughts @eli-schwartz
I wasn't saying "upload to PyPI straight from CI". We actually do things like PGP signing and adding checksums of release artifacts to release notes. But if you do everything locally, you can get subtle bugs like "new release manager was on a different OS, and now file permissions changed, and we only noticed once the bug reports started rolling in" (this one is not made up unfortunately).
Ah, I didn't realize this - that's actually the behavior I want as well. |
(I have seen lots of people that do, sorry for the confusion.)
The relevant flit code for comparison is here: |
This is actually useful for the "release sdist" part. We could indeed use it to amend the license file. For anything else that may go via sdist, like a packager applying a patch, it doesn't help. I like the "steal code from Flit" option instead of using |
And just to clarify -- I do believe that It's something I'd need to seriously consider, based on how people are using it and what the Python ecosystem wants to use it for. |
[skip github]
…y fix Closes scipygh-16219 This was never an issue for `stats.qmc.Sobol` for our wheel builds, because we used newer Cython versions. But technically it was a (minor) bug with our stated range of Cython support.
46ade1b
to
5382313
Compare
tools/build-pypi-artifacts.py
Outdated
@@ -0,0 +1,253 @@ | |||
import os |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If CI passes I will remove this script completely for now.
There are some failures on the tests that I cannot tell if were caused by the build system change or something else, and linting errors on |
It looks like this uncovered an unrelated bug in the recently merged
The only other issue is a random failure that is unrelated:
|
Is this just gh-16230 or... ? EDIT: wait, _directmodule.c, ... cannot find "PyInit__direct"? |
It shouldn't be, because I just rebased on |
The relevant changes that could be the cause of this were: 1. build against a different numpy version 2. switch to `python setup.py install` from `pip install .` [skip actions]
872fdf3
to
d92ee77
Compare
See if this works, or if it reproduces the `PyInit_direct` issue seen in scipy#16187 (comment) [skip actions]
After upstream changes in `meson-python` to be able to include uncommitted changes to tracked files, we no longer need this script (much better, this auto-committing thing was dangerous!).
871bdba
to
72add93
Compare
This is now good to go. Last call before merge, please have a look today if you want. |
Ok, I read through the entire diff again and it seems reasonable enough. I also read through most of the comments (90 %, ok maybe 80 % of the content). I've made a note to consult the release process adjustments for Do I understand all the points in the discussion above? No. Does it look like carefully crafted work to improve our build system? Yes. Let's see how it goes! Merging, with individual commits preserved, thanks. |
+100! Great work, Ralf and all! |
This switches to Meson in
pyproject.toml
(see gh-13615), by using themeson-python
build backend.There's an important conceptual change:pyproject.toml
file is now by default usable for development and does not deal with pinning numpy specifically for PyPI - that is now done in a separate script.This is an update/alternative to gh-15476, which wasn't going to quite work as planned (as in this comment). Given how the build hooks in
pyproject.toml
work, it is fundamentally not possible to have both the development/CI/etc. config in there and the PyPI-specific pins.Having a separate script for generating our PyPI artifacts isn't a problem, because this should only be used for releases in well-defined CI configs. One goal I have with this new PyPI-specific script though is to make it much easier to build such wheels locally for testing; right now that's basically impossible, given the many hoops that https://github.com/MacPython/scipy-wheels jumps through.Still TODO:
implement PyPI-specific wheel build changesEDIT: no longer needed becausemeson-python
now picks up uncommitted changes. So we should be good with whatmultibuild
does for thedistutils
-based builds.add user/packager-facing docs on usingno change here in behaviour, better guidance to users about build isolation would be nice, but is decoupled from this PR.pip
,build
, etc.implement the change to ensure wheels have the correct runtime dependency onEDIT: doing this in a follow-up, since thenumpy
(>= build-time version): gh-14541#issuecomment-968317738.meson-python
feature won't be available in time. That's not an issue, because this behavior was never available with ournumpy.distutils
based builds.There is still work to do, but the sdist generation works and I'd like some feedback now on the approach.
Cc @FFY00, @matthew-brett, @tylerjereddy, @eli-schwartz, @mattip