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.
153 lines
4.3 KiB
Nix
153 lines
4.3 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
callPackage,
|
|
pythonPackagesExtensions,
|
|
config,
|
|
makeScopeWithSplicing',
|
|
...
|
|
}:
|
|
|
|
{
|
|
implementation,
|
|
libPrefix,
|
|
executable,
|
|
sourceVersion,
|
|
pythonVersion,
|
|
packageOverrides,
|
|
sitePackages,
|
|
hasDistutilsCxxPatch,
|
|
pythonOnBuildForBuild,
|
|
pythonOnBuildForHost,
|
|
pythonOnBuildForTarget,
|
|
pythonOnHostForHost,
|
|
pythonOnTargetForTarget,
|
|
pythonAttr ? null,
|
|
pythonABITags ? [ "none" ],
|
|
self, # is pythonOnHostForTarget
|
|
}:
|
|
let
|
|
pythonPackages =
|
|
let
|
|
ensurePythonModules =
|
|
items:
|
|
let
|
|
exceptions = [
|
|
stdenv
|
|
];
|
|
providesSetupHook = lib.attrByPath [ "provides" "setupHook" ] false;
|
|
valid =
|
|
value: pythonPackages.hasPythonModule value || providesSetupHook value || lib.elem value exceptions;
|
|
func =
|
|
name: value:
|
|
if lib.isDerivation value then
|
|
lib.extendDerivation (
|
|
valid value
|
|
|| throw "${name} should use `buildPythonPackage` or `toPythonModule` if it is to be part of the Python packages set."
|
|
) { } value
|
|
else
|
|
value;
|
|
in
|
|
lib.mapAttrs func items;
|
|
in
|
|
ensurePythonModules (
|
|
callPackage
|
|
# Function that when called
|
|
# - imports python-packages.nix
|
|
# - adds spliced package sets to the package set
|
|
# - applies overrides from `packageOverrides` and `pythonPackagesOverlays`.
|
|
(
|
|
{
|
|
pkgs,
|
|
stdenv,
|
|
python,
|
|
overrides,
|
|
}:
|
|
let
|
|
pythonPackagesFun = import ./python-packages-base.nix {
|
|
inherit stdenv pkgs lib;
|
|
python = self;
|
|
};
|
|
otherSplices = {
|
|
selfBuildBuild = pythonOnBuildForBuild.pkgs;
|
|
selfBuildHost = pythonOnBuildForHost.pkgs;
|
|
selfBuildTarget = pythonOnBuildForTarget.pkgs;
|
|
selfHostHost = pythonOnHostForHost.pkgs;
|
|
selfTargetTarget = pythonOnTargetForTarget.pkgs or { }; # There is no Python TargetTarget.
|
|
};
|
|
hooks = import ./hooks/default.nix;
|
|
keep = self: hooks self { };
|
|
optionalExtensions = cond: as: lib.optionals cond as;
|
|
pythonExtension = import ../../../top-level/python-packages.nix;
|
|
python2Extension = import ../../../top-level/python2-packages.nix;
|
|
extensions = lib.composeManyExtensions (
|
|
[
|
|
hooks
|
|
pythonExtension
|
|
]
|
|
++ (optionalExtensions (!self.isPy3k) [
|
|
python2Extension
|
|
])
|
|
++ pythonPackagesExtensions
|
|
++ [
|
|
overrides
|
|
]
|
|
);
|
|
aliases =
|
|
self: super:
|
|
lib.optionalAttrs config.allowAliases (import ../../../top-level/python-aliases.nix lib self super);
|
|
in
|
|
makeScopeWithSplicing' {
|
|
inherit otherSplices keep;
|
|
f = lib.extends (lib.composeExtensions aliases extensions) pythonPackagesFun;
|
|
}
|
|
)
|
|
{
|
|
overrides = packageOverrides;
|
|
python = self;
|
|
}
|
|
);
|
|
in
|
|
rec {
|
|
isPy27 = pythonVersion == "2.7";
|
|
isPy37 = pythonVersion == "3.7";
|
|
isPy38 = pythonVersion == "3.8";
|
|
isPy39 = pythonVersion == "3.9";
|
|
isPy310 = pythonVersion == "3.10";
|
|
isPy311 = pythonVersion == "3.11";
|
|
isPy312 = pythonVersion == "3.12";
|
|
isPy313 = pythonVersion == "3.13";
|
|
isPy314 = pythonVersion == "3.14";
|
|
isPy2 = lib.strings.substring 0 1 pythonVersion == "2";
|
|
isPy3 = lib.strings.substring 0 1 pythonVersion == "3";
|
|
isPy3k = isPy3;
|
|
isPyPy = lib.hasInfix "pypy" interpreter;
|
|
|
|
buildEnv = callPackage ./wrapper.nix {
|
|
python = self;
|
|
inherit (pythonPackages) requiredPythonModules;
|
|
};
|
|
withPackages = import ./with-packages.nix { inherit buildEnv pythonPackages; };
|
|
pkgs = pythonPackages;
|
|
interpreter = "${self}/bin/${executable}";
|
|
inherit
|
|
executable
|
|
implementation
|
|
libPrefix
|
|
pythonVersion
|
|
sitePackages
|
|
;
|
|
inherit sourceVersion;
|
|
pythonAtLeast = lib.versionAtLeast pythonVersion;
|
|
pythonOlder = lib.versionOlder pythonVersion;
|
|
inherit hasDistutilsCxxPatch;
|
|
inherit pythonOnBuildForHost;
|
|
inherit pythonABITags;
|
|
|
|
tests = callPackage ./tests.nix {
|
|
python = self;
|
|
};
|
|
|
|
inherit pythonAttr;
|
|
}
|