Skip to content

Multiarch reporting error in <= 3.12 musl builds + compiled packages broken in 3.11 and 3.12 #724

@nathanscain

Description

@nathanscain

Description

Combining into 1 bug report as they were found at the same time and seem related - but feel free to split up.

  • python-build-standlone musl builds for 3.9-3.12 report as multiarch of x86_64-linux-gnu instead of x86_64-linux-musl within sys.implementation. 3.13 and 3.14 report the correct multiarch.
  • Additionally, 3.11 and 3.12 musl builds are unable to load compiled dependencies. 3.13+ along with 3.9 and 3.10 can use compiled packages like lxml, cryptography, pydantic-core, and numpy; however, 3.11 and 3.12 always fail to load the modules.

I expect that before 3.11 python was using a different mechanism to identify which libc modules to load and it starts working again in 3.13+ when the multiarch setting is fixed.

Note that this is not an issue at all within the official alpine docker images - they all report the correct multiarch and load modules correctly even when the base system exhibits the issue.

Potential Fix

Looks like there was a previously identified issue with how clang prints something with --print-multiarch that confuses the CPython configure. It is being applied to all gnu builds, but only musl builds 3.13+ which lines up with the reporting I am seeing. The relevant patches are 4 years old now, so I expect that a more recent update to clang has made this issue affect musl like it does on gnu and the patch needs to be applied to both.

https://github.com/astral-sh/python-build-standalone/blob/55f3d50aee9743ea48afaa18d43ff7a96af7b056/cpython-unix/build-cpython.sh#L116C1-L130C3

diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index cc93f0a..3c252a5 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -116,17 +116,12 @@ fi
 # Clang 13 actually prints something with --print-multiarch, confusing CPython's
 # configure. This is reported as https://bugs.python.org/issue45405. We nerf the
 # check since we know what we're doing.
-if [ "${CC}" = "clang" ]; then
+if [[ "${CC}" = "clang" || "${CC}" = "musl-clang" ]]; then
     if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
         patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch
     else
         patch -p1 -i ${ROOT}/patch-disable-multiarch.patch
     fi
-elif [ "${CC}" = "musl-clang" ]; then
-  # Similarly, this is a problem for musl Clang on Python 3.13+
-  if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
-    patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch
-  fi
 fi
 
 # Python 3.11 supports using a provided Python to use during bootstrapping

System

Tested on multiple machines with rpm, deb, and from source builds of musl libc and on the latest uv release.

Issue with multi arch reporting is the same everywhere; however, my test on Fedora was able to load compiled dependencies without error - while the source build in wsl and hardware failed along with the ubuntu test on wsl. (Fedora and ubuntu both on latest release/lts update)

Details

Tests below from ubuntu LTS on WSL uv 0.8.4 (captured before 0.8.5 update). Stripped out username and cache hashes.

lxml
$ UV_LIBC=musl uvx --with lxml [email protected] -c "import sys; print(sys.implementation); from lxml import etree"
namespace(name='cpython', cache_tag='cpython-313', version=sys.version_info(major=3, minor=13, micro=5, releaselevel='final', serial=0), hexversion=51185136, _multiarch='x86_64-linux-musl')

$ UV_LIBC=musl uvx --with lxml [email protected] -c "import sys; print(sys.implementation); from lxml import etree"
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'etree' from 'lxml' (/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/lxml/__init__.py)

$ UV_LIBC=musl uvx --with lxml [email protected] -c "import sys; print(sys.implementation); from lxml import etree"
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'etree' from 'lxml' (/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/lxml/__init__.py)

$ UV_LIBC=musl uvx --with lxml [email protected] -c "import sys; print(sys.implementation); from lxml import etree"
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=18, releaselevel='final', serial=0), hexversion=50991856, _multiarch='x86_64-linux-gnu')

$ UV_LIBC=musl uvx --with lxml [email protected] -c "import sys; print(sys.implementation); from lxml import etree"
namespace(name='cpython', cache_tag='cpython-39', version=sys.version_info(major=3, minor=9, micro=23, releaselevel='final', serial=0), hexversion=50927600, _multiarch='x86_64-linux-gnu')
cryptography
$ UV_LIBC=musl uvx --with cryptography [email protected] -c "import sys; print(sys.implementation); from cryptography.fernet import Fernet"
namespace(name='cpython', cache_tag='cpython-313', version=sys.version_info(major=3, minor=13, micro=5, releaselevel='final', serial=0), hexversion=51185136, _multiarch='x86_64-linux-musl')

$ UV_LIBC=musl uvx --with cryptography [email protected] -c "import sys; print(sys.implementation); from cryptography.fernet import Fernet"
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/cryptography/fernet.py", line 15, in <module>
    from cryptography.exceptions import InvalidSignature
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/cryptography/exceptions.py", line 9, in <module>
    from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
ModuleNotFoundError: No module named '_cffi_backend'

$ UV_LIBC=musl uvx --with cryptography [email protected] -c "import sys; print(sys.implementation); from cryptography.fernet import Fernet"
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/cryptography/fernet.py", line 15, in <module>
    from cryptography.exceptions import InvalidSignature
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/cryptography/exceptions.py", line 9, in <module>
    from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
ModuleNotFoundError: No module named '_cffi_backend'

$ UV_LIBC=musl uvx --with cryptography [email protected] -c "import sys; print(sys.implementation); from cryptography.fernet import Fernet"
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=18, releaselevel='final', serial=0), hexversion=50991856, _multiarch='x86_64-linux-gnu')

$ UV_LIBC=musl uvx --with cryptography [email protected] -c "import sys; print(sys.implementation); from cryptography.fernet import Fernet"
namespace(name='cpython', cache_tag='cpython-39', version=sys.version_info(major=3, minor=9, micro=23, releaselevel='final', serial=0), hexversion=50927600, _multiarch='x86_64-linux-gnu')
pydantic-core
$ UV_LIBC=musl uvx --with pydantic-core [email protected] -c "import sys; print(sys.implementation); from pydantic_core import SchemaValidator"
namespace(name='cpython', cache_tag='cpython-313', version=sys.version_info(major=3, minor=13, micro=5, releaselevel='final', serial=0), hexversion=51185136, _multiarch='x86_64-linux-musl')

$ UV_LIBC=musl uvx --with pydantic-core [email protected] -c "import sys; print(sys.implementation); from pydantic_core import SchemaValidator"
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/pydantic_core/__init__.py", line 8, in <module>
    from ._pydantic_core import (
ModuleNotFoundError: No module named 'pydantic_core._pydantic_core'

$ UV_LIBC=musl uvx --with pydantic-core [email protected] -c "import sys; print(sys.implementation); from pydantic_core import SchemaValidator"
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/pydantic_core/__init__.py", line 8, in <module>
    from ._pydantic_core import (
ModuleNotFoundError: No module named 'pydantic_core._pydantic_core'

$ UV_LIBC=musl uvx --with pydantic-core [email protected] -c "import sys; print(sys.implementation); from pydantic_core import SchemaValidator"
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=18, releaselevel='final', serial=0), hexversion=50991856, _multiarch='x86_64-linux-gnu')

$ UV_LIBC=musl uvx --with pydantic-core [email protected] -c "import sys; print(sys.implementation); from pydantic_core import SchemaValidator"
namespace(name='cpython', cache_tag='cpython-39', version=sys.version_info(major=3, minor=9, micro=23, releaselevel='final', serial=0), hexversion=50927600, _multiarch='x86_64-linux-gnu')
numpy
$ UV_LIBC=musl uvx --with numpy [email protected] -c "import sys; print(sys.implementation); import numpy"
namespace(name='cpython', cache_tag='cpython-313', version=sys.version_info(major=3, minor=13, micro=5, releaselevel='final', serial=0), hexversion=51185136, _multiarch='x86_64-linux-musl')

$ UV_LIBC=musl uvx --with numpy [email protected] -c "import sys; print(sys.implementation); import numpy"
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/numpy/_core/__init__.py", line 22, in <module>
    from . import multiarray
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/numpy/_core/multiarray.py", line 11, in <module>
    from . import _multiarray_umath, overrides
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.12/site-packages/numpy/_core/overrides.py", line 5, in <module>
    from numpy._core._multiarray_umath import (
ModuleNotFoundError: No module named 'numpy._core._multiarray_umath'
...

$ UV_LIBC=musl uvx --with numpy [email protected] -c "import sys; print(sys.implementation); import numpy"
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-gnu')
Traceback (most recent call last):
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/numpy/_core/__init__.py", line 22, in <module>
    from . import multiarray
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/numpy/_core/multiarray.py", line 11, in <module>
    from . import _multiarray_umath, overrides
  File "/home/username/.cache/uv/archive-v0/hash/lib/python3.11/site-packages/numpy/_core/overrides.py", line 5, in <module>
    from numpy._core._multiarray_umath import (
ModuleNotFoundError: No module named 'numpy._core._multiarray_umath'
...

$ UV_LIBC=musl uvx --with numpy [email protected] -c "import sys; print(sys.implementation); import numpy"
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=18, releaselevel='final', serial=0), hexversion=50991856, _multiarch='x86_64-linux-gnu')

$ UV_LIBC=musl uvx --with numpy [email protected] -c "import sys; print(sys.implementation); import numpy"
namespace(name='cpython', cache_tag='cpython-39', version=sys.version_info(major=3, minor=9, micro=23, releaselevel='final', serial=0), hexversion=50927600, _multiarch='x86_64-linux-gnu')
official alpine images working
$ podman run -it --rm python:3.12-alpine sh -c "pip install lxml; python -c 'import sys; print(sys.implementation); from lxml import etree'"
...
Successfully installed lxml-6.0.0
...
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-musl')

$ podman run -it --rm python:3.12-alpine sh -c "pip install cryptography; python -c 'import sys; print(sys.implementation); from cryptography.fernet import Fernet'"
...
Successfully installed cffi-1.17.1 cryptography-45.0.5 pycparser-2.22
...
namespace(name='cpython', cache_tag='cpython-312', version=sys.version_info(major=3, minor=12, micro=11, releaselevel='final', serial=0), hexversion=51121136, _multiarch='x86_64-linux-musl')

$ podman run -it --rm python:3.11-alpine sh -c "pip install pydantic-core; python -c 'import sys; print(sys.implementation); from pydantic_core import SchemaValidator'"
...
Successfully installed pydantic-core-2.38.0 typing-extensions-4.14.1
...
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-musl')

$ podman run -it --rm python:3.11-alpine sh -c "pip install numpy; python -c 'import sys; print(sys.implementation); import numpy'"
...
Successfully installed numpy-2.3.2
...
namespace(name='cpython', cache_tag='cpython-311', version=sys.version_info(major=3, minor=11, micro=13, releaselevel='final', serial=0), hexversion=51056112, _multiarch='x86_64-linux-musl')

Metadata

Metadata

Assignees

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