Skip to content

Commit

Permalink
MAINT: detect free-threaded CPython ("nogil") and handle limited API
Browse files Browse the repository at this point in the history
The free-threaded CPython build does not support the limited API yet,
and won't in the near future. To avoid either cryptic build failures
or a successfull build yielding an `abi3` tag which would not be
correct, raise a clear error and don't attempt to build.
  • Loading branch information
rgommers authored and dnicolodi committed Apr 23, 2024
1 parent d940353 commit ce9982a
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
7 changes: 6 additions & 1 deletion mesonpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ def __init__(
self._metadata.requires_python.prereleases = True
if platform.python_version().rstrip('+') not in self._metadata.requires_python:
raise MesonBuilderError(
f'Package requires Python version {self._metadata.requires_python}, '
f'The package requires Python version {self._metadata.requires_python}, '
f'running on {platform.python_version()}')

# limited API
Expand All @@ -759,6 +759,11 @@ def __init__(
if not value:
self._limited_api = False

if self._limited_api and bool(sysconfig.get_config_var('Py_GIL_DISABLED')):
raise BuildError(
'The package targets Python\'s Limited API, which is not supported by free-threaded CPython. '
'The "python.allow_limited_api" Meson build option may be used to override the package default.')

def _run(self, cmd: Sequence[str]) -> None:
"""Invoke a subprocess."""
# Flush the line to ensure that the log line with the executed
Expand Down
2 changes: 1 addition & 1 deletion tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


def test_unsupported_python_version(package_unsupported_python_version):
with pytest.raises(mesonpy.MesonBuilderError, match='Package requires Python version ==1.0.0'):
with pytest.raises(mesonpy.MesonBuilderError, match='The package requires Python version ==1.0.0'):
with mesonpy._project():
pass

Expand Down
4 changes: 4 additions & 0 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
'win32': '.dll',
}.get(sys.platform, '.so')

NOGIL_BUILD = bool(sysconfig.get_config_var('Py_GIL_DISABLED'))

# Test against the wheel tag generated by packaging module.
tag = next(packaging.tags.sys_tags())
ABI = tag.abi
Expand Down Expand Up @@ -287,6 +289,7 @@ def test_skip_subprojects(package_subproject, tmp_path, arg):

# Requires Meson 1.3.0, see https://github.com/mesonbuild/meson/pull/11745.
@pytest.mark.skipif(MESON_VERSION < (1, 2, 99), reason='Meson version too old')
@pytest.mark.skipif(NOGIL_BUILD, reason='Free-threaded CPython does not support the limited API')
def test_limited_api(wheel_limited_api):
artifact = wheel.wheelfile.WheelFile(wheel_limited_api)
name = artifact.parsed_filename
Expand All @@ -297,6 +300,7 @@ def test_limited_api(wheel_limited_api):

# Requires Meson 1.3.0, see https://github.com/mesonbuild/meson/pull/11745.
@pytest.mark.skipif(MESON_VERSION < (1, 2, 99), reason='Meson version too old')
@pytest.mark.skipif(NOGIL_BUILD, reason='Free-threaded CPython does not support the limited API')
@pytest.mark.xfail('__pypy__' in sys.builtin_module_names, reason='PyPy does not use special modules suffix for stable ABI')
def test_limited_api_bad(package_limited_api, tmp_path):
with pytest.raises(mesonpy.BuildError, match='The package declares compatibility with Python limited API but '):
Expand Down

0 comments on commit ce9982a

Please sign in to comment.