Skip to content

No-GIL/free-threaded compatibility is not taken into account when checking for Python compatibliity of wheels #340

@vlaci

Description

@vlaci

I distribute the lzallright package in pypi which supports free-threaded Python versions as well.

It is distributed as an abi3 wheel for most platforms, and it is distributed as a cp313t wheel for free-threaded builds. Unfortunately pyproject.nix and as a consequence uv2nix treats the cp313t compatible with regular Python 3.13 interpreters, leading to this error:

 error: Failed to determine installation plan
  Caused by: A path dependency is incompatible with the current platform: lzallright-0.2.5-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

I managed to resolve this by applying the following diff:

diff --git i/lib/pypa.nix w/lib/pypa.nix
index ae2e5d8..9b78ce3 100644
--- i/lib/pypa.nix
+++ w/lib/pypa.nix
@@ -24,7 +24,7 @@ let
     take
     splitString
     ;
-  inherit (lib.strings) hasPrefix toInt;
+  inherit (lib.strings) hasPrefix hasSuffix toInt;
 
   matchWheelFileName = match "([^-]+)-([^-]+)(-([[:digit:]][^-]*))?-([^-]+)-([^-]+)-(.+).whl";
 
@@ -384,11 +384,13 @@ lib.fix (self: {
     let
       #   inherit (python.passthru) sourceVersion implementation;
       # in
-      inherit (python.passthru) implementation pythonVersion;
+      inherit (python.passthru) implementation pythonVersion libPrefix;
 
       version' = splitString "." pythonVersion;
       major = elemAt version' 0;
       minor = elemAt version' 1;
+      freeThreadedWheel = hasSuffix pythonVersion "t";
+      freeThreadedPython = hasSuffix libPrefix "t";
     in
     assert length version' >= 2;
     # Python tag
@@ -405,7 +407,9 @@ lib.fix (self: {
       (
         pythonTag.version == null
         || pythonTag.version == major
-        || (hasPrefix major pythonTag.version && ((toInt (major + minor)) >= toInt pythonTag.version))
+        ||
+          (hasPrefix major pythonTag.version && ((toInt (major + minor)) >= toInt pythonTag.version))
+          && freeThreadedWheel == freeThreadedPython
       );
 
   /**

It looks like, the only passthru flag to check is libPrefix. The tag parsing feels very hackish, I don't know if we can do any better though. Also IMO the t suffix cannot appear without specifying the minor version, but I did not find an exact spec.

If you think, this is the correct way to approach this, I am happy to create a PR.


I think this is related to the issue mentioned in pyproject-nix/uv2nix#165 as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions