From 3e6a5988c765d80b2d62bde5f06e336666f96d4a Mon Sep 17 00:00:00 2001 From: adisbladis Date: Mon, 22 Sep 2025 16:12:05 +1200 Subject: [PATCH] pythonInterpreters: Add passthru.pythonABITags As documented in https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#abi-tag. This is useful to check whether a wheel is compatible with a certain interpreter. [Pyproject.nix](https://github.com/pyproject-nix/pyproject.nix) has [functions to perform wheel compatibility checking](https://pyproject-nix.github.io/pyproject.nix/lib/pypa.html#function-library-lib.pypa.isWheelFileCompatible) against a Python interpreter, and has computed interpreter ABI tags itself. The recent addition of free threading (`python313FreeThreading`) complicates this by not being introspectable: A GIL Python (non free-threaded) has an ABI tag `cp313` while the free-threaded Python has `cp313t`, but the package doesn't communicate whether `enableGIL` is true or false, leaving no way to compute the tag. The same goes for if debugging support was added to the derivation: A `d` suffix would need to be added. Additionally ABI tags has no defined format and can really only be accurately computed by having insight into how the ABI tags are used by a specific interpreter, meaning that the only correct place to compute ABI tags is within the context of a particular Python derivation. While this has no immediate use within nixpkgs it could be used as a basis to provide compatibility assertions regarding wheel compat at eval time. --- .../development/interpreters/python/cpython/2.7/default.nix | 4 ++++ pkgs/development/interpreters/python/cpython/default.nix | 6 ++++++ pkgs/development/interpreters/python/passthrufun.nix | 2 ++ pkgs/development/interpreters/python/pypy/default.nix | 5 +++++ pkgs/development/interpreters/python/pypy/prebuilt.nix | 5 +++++ pkgs/development/interpreters/python/pypy/prebuilt_2_7.nix | 5 +++++ 6 files changed, 27 insertions(+) diff --git a/pkgs/development/interpreters/python/cpython/2.7/default.nix b/pkgs/development/interpreters/python/cpython/2.7/default.nix index 94ff0c97dfa8..46a283bd5b2c 100644 --- a/pkgs/development/interpreters/python/cpython/2.7/default.nix +++ b/pkgs/development/interpreters/python/cpython/2.7/default.nix @@ -87,6 +87,10 @@ let pythonOnBuildForTarget = pkgsBuildTarget.${pythonAttr}; pythonOnHostForHost = pkgsHostHost.${pythonAttr}; pythonOnTargetForTarget = pkgsTargetTarget.${pythonAttr} or { }; + pythonABITags = [ + "none" + "cp${sourceVersion.major}${sourceVersion.minor}" + ]; } // { inherit ucsEncoding; diff --git a/pkgs/development/interpreters/python/cpython/default.nix b/pkgs/development/interpreters/python/cpython/default.nix index 0b2a3e1a59d8..14072ced545f 100644 --- a/pkgs/development/interpreters/python/cpython/default.nix +++ b/pkgs/development/interpreters/python/cpython/default.nix @@ -195,6 +195,12 @@ let pythonOnHostForHost pythonOnTargetForTarget ; + + pythonABITags = [ + "abi3" + "none" + "cp${sourceVersion.major}${sourceVersion.minor}${lib.optionalString (!enableGIL) "t"}" + ]; }; version = with sourceVersion; "${major}.${minor}.${patch}${suffix}"; diff --git a/pkgs/development/interpreters/python/passthrufun.nix b/pkgs/development/interpreters/python/passthrufun.nix index be5d8a11add5..451292d198e9 100644 --- a/pkgs/development/interpreters/python/passthrufun.nix +++ b/pkgs/development/interpreters/python/passthrufun.nix @@ -23,6 +23,7 @@ pythonOnHostForHost, pythonOnTargetForTarget, pythonAttr ? null, + pythonABITags ? [ "none" ], self, # is pythonOnHostForTarget }: let @@ -141,6 +142,7 @@ rec { pythonOlder = lib.versionOlder pythonVersion; inherit hasDistutilsCxxPatch; inherit pythonOnBuildForHost; + inherit pythonABITags; tests = callPackage ./tests.nix { python = self; diff --git a/pkgs/development/interpreters/python/pypy/default.nix b/pkgs/development/interpreters/python/pypy/default.nix index aa6a58ca3184..c030a464e133 100644 --- a/pkgs/development/interpreters/python/pypy/default.nix +++ b/pkgs/development/interpreters/python/pypy/default.nix @@ -67,6 +67,11 @@ let pythonOnBuildForTarget = pkgsBuildTarget.${pythonAttr}; pythonOnHostForHost = pkgsHostHost.${pythonAttr}; pythonOnTargetForTarget = pkgsTargetTarget.${pythonAttr} or { }; + + pythonABITags = [ + "none" + "pypy${lib.concatStrings (lib.take 2 (lib.splitString "." pythonVersion))}_pp${sourceVersion.major}${sourceVersion.minor}" + ]; }; pname = passthru.executable; version = with sourceVersion; "${major}.${minor}.${patch}"; diff --git a/pkgs/development/interpreters/python/pypy/prebuilt.nix b/pkgs/development/interpreters/python/pypy/prebuilt.nix index 02c7b39ad754..ef0350d93818 100644 --- a/pkgs/development/interpreters/python/pypy/prebuilt.nix +++ b/pkgs/development/interpreters/python/pypy/prebuilt.nix @@ -48,6 +48,11 @@ let pythonOnBuildForTarget = throw "${pname} does not support cross compilation"; pythonOnHostForHost = throw "${pname} does not support cross compilation"; pythonOnTargetForTarget = throw "${pname} does not support cross compilation"; + + pythonABITags = [ + "none" + "pypy${lib.concatStrings (lib.take 2 (lib.splitString "." pythonVersion))}_pp${sourceVersion.major}${sourceVersion.minor}" + ]; }; pname = "${passthru.executable}_prebuilt"; version = with sourceVersion; "${major}.${minor}.${patch}"; diff --git a/pkgs/development/interpreters/python/pypy/prebuilt_2_7.nix b/pkgs/development/interpreters/python/pypy/prebuilt_2_7.nix index 4419485b3db6..fc8fdf79208c 100644 --- a/pkgs/development/interpreters/python/pypy/prebuilt_2_7.nix +++ b/pkgs/development/interpreters/python/pypy/prebuilt_2_7.nix @@ -48,6 +48,11 @@ let pythonOnBuildForTarget = throw "${pname} does not support cross compilation"; pythonOnHostForHost = throw "${pname} does not support cross compilation"; pythonOnTargetForTarget = throw "${pname} does not support cross compilation"; + + pythonABITags = [ + "none" + "pypy${lib.concatStrings (lib.take 2 (lib.splitString "." pythonVersion))}_pp${sourceVersion.major}${sourceVersion.minor}" + ]; }; pname = "${passthru.executable}_prebuilt"; version = with sourceVersion; "${major}.${minor}.${patch}";