Skip to content

Commit e771686

Browse files
Merge pull request #5179 from neutrinoceros/whl/abi3-wheels
2 parents 0aaa6d5 + 6a9c5f7 commit e771686

File tree

5 files changed

+47
-8
lines changed

5 files changed

+47
-8
lines changed

.github/workflows/wheels.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ on:
1212
- '.github/workflows/wheels.yaml'
1313
- MANIFEST.in
1414
- pyproject.toml
15+
- setup.py
16+
- setupext.py
1517
workflow_dispatch:
1618

1719

doc/source/installing.rst

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,23 @@ Note that all format names are normalized to lower case.
110110
Building from source
111111
++++++++++++++++++++
112112

113-
To build yt from source, you need ``git``, and a C compiler (such as ``gcc``
114-
or ``clang``).
115-
116-
Then run
117-
113+
There are a couple ways to build yt from source with e.g., ``pip``, all of which
114+
require a C compiler (such as ``gcc`` or ``clang``).
115+
116+
yt is primarily distributed on PyPI, in the form of pre-built binaries (wheels).
117+
Since version 4.5.0, these binaries are optimized for portability accross Python versions.
118+
119+
If you need a stable release, but pre-built binaries are not available for your platform,
120+
``pip install`` will automatically select a source distribution and compile the package
121+
for you. You may opt-into this behavior deliberately by specifying the ``--no-binary``
122+
flag, in which case the resulting installation might be slightly more performant, because
123+
it will be compiled specifically for your Python version.
124+
If, on the other hand, you *specifically* want a portable binary (as the ones we provide on
125+
PyPI), this is achieved by setting ``YT_LIMITED_API=1`` in your build environment.
126+
127+
You may also want to build yt directly from the github repository (which requires ``git``),
128+
for instance if you need the latest development version, or if you want to contribute to
129+
the project. Run
118130
.. code-block:: bash
119131
120132
$ git clone https://github.com/yt-project/yt

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ requires = [
55
"Cython>=3.0.3",
66
"numpy>=2.0.0",
77
"ewah-bool-utils>=1.2.0",
8+
"wheel>=0.38.0",
89
]
910
build-backend = "setuptools.build_meta"
1011

@@ -466,6 +467,7 @@ test-extras = "test"
466467
test-command = [
467468
"python -m pytest -c {project}/pyproject.toml --rootdir . --color=yes --pyargs yt -ra",
468469
]
470+
environment = {"YT_LIMITED_API" = "1"}
469471

470472
[[tool.cibuildwheel.overrides]]
471473
# Install nightly wheels for matplotlib, not yet available on PyPI.

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
lib_exts += embree_libs
8484

8585
# This overrides using lib_exts, so it has to happen after lib_exts is fully defined
86-
build_ext, sdist = create_build_ext(lib_exts, cythonize_aliases)
86+
build_ext, sdist, bdist_wheel = create_build_ext(lib_exts, cythonize_aliases)
8787

8888

8989
# Force setuptools to consider that there are ext modules, even if empty.
@@ -122,7 +122,7 @@ def has_ext_modules(self):
122122
)
123123

124124
setup(
125-
cmdclass={"sdist": sdist, "build_ext": build_ext},
125+
cmdclass={"sdist": sdist, "build_ext": build_ext, "bdist_wheel": bdist_wheel},
126126
distclass=BinaryDistribution,
127127
libraries=[fixed_interp_lib],
128128
ext_modules=[], # !!! We override this inside build_ext above

setupext.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,19 @@
1919
from setuptools.command.sdist import sdist as _sdist
2020
from setuptools.errors import CompileError, LinkError
2121
import importlib.resources as importlib_resources
22+
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
2223

2324
log = logging.getLogger("setupext")
2425

26+
USE_PY_LIMITED_API = (
27+
os.getenv('YT_LIMITED_API', '0') == '1'
28+
and sys.version_info >= (3, 11)
29+
and not sysconfig.get_config_var("Py_GIL_DISABLED")
30+
)
31+
ABI3_TARGET_VERSION = "".join(str(_) for _ in sys.version_info[:2])
32+
ABI3_TARGET_HEX = hex(sys.hexversion & 0xFFFF00F0)
33+
34+
2535
@contextlib.contextmanager
2636
def stdchannel_redirected(stdchannel, dest_filename):
2737
"""
@@ -433,6 +443,10 @@ def finalize_options(self):
433443
self.include_dirs.append(ewah_bool_utils.get_include())
434444

435445
define_macros = NUMPY_MACROS
446+
if USE_PY_LIMITED_API:
447+
define_macros.append(("Py_LIMITED_API", ABI3_TARGET_HEX))
448+
for ext in self.extensions:
449+
ext.py_limited_api = True
436450

437451
if self.define is None:
438452
self.define = define_macros
@@ -477,4 +491,13 @@ def run(self):
477491
)
478492
_sdist.run(self)
479493

480-
return build_ext, sdist
494+
class bdist_wheel(_bdist_wheel):
495+
def get_tag(self):
496+
python, abi, plat = super().get_tag()
497+
498+
if python.startswith("cp") and USE_PY_LIMITED_API:
499+
return f"cp{ABI3_TARGET_VERSION}", "abi3", plat
500+
501+
return python, abi, plat
502+
503+
return build_ext, sdist, bdist_wheel

0 commit comments

Comments
 (0)