Description
(This is a hesitant report: I'm not 100% sure about where the issue is attributable to. Also, I'm guessing that apparent problems with the xmlsec
PyPI packages would be reportable here – please redirect me if that's wrong.)
This is on macOS 15.4, which provides Python 3.9.6.
After I install xmlsec
(1.3.15) into a venv, from PyPI, I'm unable to import it because, it appears, it contains references to homebrew libraries which don't exist.
% python
Python 3.9.6 (default, Mar 12 2025, 20:22:46)
[Clang 17.0.0 (clang-1700.0.13.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import xmlsec
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen([PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so, 0x0002): Library not loaded: /opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib
Referenced from: <FD0F84B5-77CB-3D58-9D97-52ECC5125326> [PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so
Reason: tried: '/opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib' (no such file), '/opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib' (no such file)
>>>
And sure enough, if I use dyld_info
to look at the libraries that library loads, they refer to homebrew (see below), and this is corroborated (also below) by looking at the load commands using otool -l
(there, I notice also a reference to /Users/amin
which suggests this may not have been build in an entirely clean environment). There is no homebrew cryptex on the machine, and no /opt/homebrew
.
I have had homebrew on this machine, but deleted it, which meant that my first suspicion was that there was some hangover from that, that was messing with the dyld load path (and it's been a while since I had to be fully familiar with dyld's gymnastics). But I don't think that's the explanation, since this was a pip
binary install (also there's no user amin
on my machine, ruling out that path being synthesised dynamically).
I tried a --no-binary
install of xmlsec
, but it failed (the docs note that this is a tricky build). That's fine – I'd rather install a PyPI binary than attempt to integrate a non-trivial build into my current build-system.
Thus it appears that the PyPI package depends on a homebrew library which is present on the package build machine, but not on mine. My hesitation is because I've never had to become familiar with the internal details of Python package building, and because I'm aware dyld has tricked me in the past, so I'm reluctant to make confident statements here.
% dyld_info [PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so
[PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so [arm64]:
-platform:
platform minOS sdk
macOS 13.3 15.2
-uuid:
FD0F84B5-77CB-3D58-9D97-52ECC5125326
-segments:
load-offset segment section sect-size seg-size init/max-prot
0x00000000 __TEXT 64KB r.x/r.x
0x00001A78 __text 33340
0x00009CB4 __stubs 2592
0x0000A6D4 __stub_helper 2616
0x0000B10C __cstring 11447
0x0000DDC3 __const 8394
0x0000FE90 __unwind_info 368
0x00010000 __DATA_CONST 16KB rw./rw.
0x00010000 __got 400
0x00014000 __DATA 32KB rw./rw.
0x00014000 __la_symbol_ptr 1728
0x000146C0 __data 20832
0x00019820 __bss 408
0x000199B8 __common 24
-linked_dylibs:
attributes load path
/opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib
/opt/homebrew/opt/libxmlsec1/lib/libxmlsec1.1.dylib
/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib
/usr/lib/libxslt.1.dylib
/usr/lib/libxml2.2.dylib
/usr/lib/libSystem.B.dylib
Checking the load commands seems to corroborate this:
% otool -l [PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so
[PATH-TO-VENV]/lib/python3.9/site-packages/xmlsec.cpython-39-darwin.so:
[...blah blah...]
Load command 10
cmd LC_LOAD_DYLIB
cmdsize 88
name /opt/homebrew/opt/libxmlsec1/lib/libxmlsec1-openssl.1.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 5.7.0
compatibility version 5.0.0
Load command 11
cmd LC_LOAD_DYLIB
cmdsize 80
name /opt/homebrew/opt/libxmlsec1/lib/libxmlsec1.1.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 5.7.0
compatibility version 5.0.0
Load command 12
cmd LC_LOAD_DYLIB
cmdsize 80
name /opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 3.0.0
compatibility version 3.0.0
Load command 13
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libxslt.1.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 3.26.0
compatibility version 3.0.0
Load command 14
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libxml2.2.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 10.9.0
compatibility version 10.0.0
Load command 15
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1351.0.0
compatibility version 1.0.0
Load command 16
cmd LC_RPATH
cmdsize 56
path /Users/amin/.pyenv/versions/3.9.11/lib (offset 12)
Load command 17
cmd LC_RPATH
cmdsize 32
path /opt/homebrew/lib (offset 12)
Load command 18
cmd LC_FUNCTION_STARTS
cmdsize 16
dataoff 124448
datasize 208
Load command 19
cmd LC_DATA_IN_CODE
cmdsize 16
dataoff 124656
datasize 0
Load command 20
cmd LC_CODE_SIGNATURE
cmdsize 16
dataoff 169904
datasize 1480