From e71fb6e616e08838df55dddb494c96a80454f812 Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Fri, 17 Jun 2022 14:11:21 -0400 Subject: [PATCH] setup: Build wheels with the stable ABI (abi3) This will produce cross-version wheels so we won't have to do releases just to make new wheels when new versions of Python are available. Also modernize the build process a bit to require setuptools and use the native "optional" flag for extensions. --- .github/workflows/build.yml | 2 +- pyproject.toml | 4 ++ setup.py | 124 ++++++++---------------------------- 3 files changed, 31 insertions(+), 99 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77e61fbd6..3f5656424 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: platforms: all - name: Build wheels - uses: pypa/cibuildwheel@v2.3.1 + uses: pypa/cibuildwheel@v2.6.1 - uses: actions/upload-artifact@v2 with: diff --git a/pyproject.toml b/pyproject.toml index 29e9dab68..b2095ed6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + [tool.cibuildwheel] build = "cp3[789]* cp310*" test-command = "python -m tornado.test" diff --git a/setup.py b/setup.py index 404090fcf..3a157b541 100644 --- a/setup.py +++ b/setup.py @@ -17,98 +17,12 @@ import os import platform -import sys -import warnings +import setuptools try: - # Use setuptools if available, for install_requires (among other things). - import setuptools - from setuptools import setup + import wheel.bdist_wheel except ImportError: - setuptools = None - from distutils.core import setup - -from distutils.core import Extension - -# The following code is copied from -# https://github.com/mongodb/mongo-python-driver/blob/master/setup.py -# to support installing without the extension on platforms where -# no compiler is available. -from distutils.command.build_ext import build_ext - - -class custom_build_ext(build_ext): - """Allow C extension building to fail. - - The C extension speeds up websocket masking, but is not essential. - """ - - warning_message = """ -******************************************************************** -WARNING: %s could not -be compiled. No C extensions are essential for Tornado to run, -although they do result in significant speed improvements for -websockets. -%s - -Here are some hints for popular operating systems: - -If you are seeing this message on Linux you probably need to -install GCC and/or the Python development package for your -version of Python. - -Debian and Ubuntu users should issue the following command: - - $ sudo apt-get install build-essential python-dev - -RedHat and CentOS users should issue the following command: - - $ sudo yum install gcc python-devel - -Fedora users should issue the following command: - - $ sudo dnf install gcc python-devel - -MacOS users should run: - - $ xcode-select --install - -******************************************************************** -""" - - def run(self): - try: - build_ext.run(self) - except Exception: - e = sys.exc_info()[1] - sys.stdout.write("%s\n" % str(e)) - warnings.warn( - self.warning_message - % ( - "Extension modules", - "There was an issue with " - "your platform configuration" - " - see above.", - ) - ) - - def build_extension(self, ext): - name = ext.name - try: - build_ext.build_extension(self, ext) - except Exception: - e = sys.exc_info()[1] - sys.stdout.write("%s\n" % str(e)) - warnings.warn( - self.warning_message - % ( - "The %s extension " "module" % (name,), - "The output above " - "this warning shows how " - "the compilation " - "failed.", - ) - ) + wheel = None kwargs = {} @@ -129,22 +43,36 @@ if ( # This extension builds and works on pypy as well, although pypy's jit # produces equivalent performance. kwargs["ext_modules"] = [ - Extension("tornado.speedups", sources=["tornado/speedups.c"]) + setuptools.Extension( + "tornado.speedups", + sources=["tornado/speedups.c"], + # Unless the user has specified that the extension is mandatory, + # fall back to the pure-python implementation on any build failure. + optional=os.environ.get("TORNADO_EXTENSION") != "1", + # Use the stable ABI so our wheels are compatible across python + # versions. + py_limited_api=True, + define_macros=[("Py_LIMITED_API", "0x03070000")], + ) ] - if os.environ.get("TORNADO_EXTENSION") != "1": - # Unless the user has specified that the extension is mandatory, - # fall back to the pure-python implementation on any build failure. - kwargs["cmdclass"] = {"build_ext": custom_build_ext} +if wheel is not None: + # From https://github.com/joerick/python-abi3-package-sample/blob/main/setup.py + class bdist_wheel_abi3(wheel.bdist_wheel.bdist_wheel): + def get_tag(self): + python, abi, plat = super().get_tag() + + if python.startswith("cp"): + return "cp37", "abi3", plat + return python, abi, plat + kwargs["cmdclass"] = {"bdist_wheel": bdist_wheel_abi3} -if setuptools is not None: - python_requires = ">= 3.7" - kwargs["python_requires"] = python_requires -setup( +setuptools.setup( name="tornado", version=version, + python_requires=">= 3.7", packages=["tornado", "tornado.test", "tornado.platform"], package_data={ # data files need to be listed both here (which determines what gets -- 2.47.2