0

I'm setting up a new M2 MacBook and seem to be hitting the issue described for M1 here:

https://github.com/PyMySQL/mysqlclient/issues/496

(tl;dr: the MySQLdb shared object library installed by pip and the mysqlclient dylib installed by brew are inconsistent, apparently due to an x86/arm architecture mismatch, such that required symbols aren't common to both.)

I've been banging my head on this for a week. I've tried the multiple workarounds in the issue discussion and haven't found anything that works on my machine. I'm not that well versed in the low level library architecture topics in the issue discussion, and am hoping I'm overlooking something. There are a lot of permutations of install and execution with arch in the thread. I've tried to apply many of the reported workarounds without success, but I feel like I'm stabbing at it without a clear understanding of what I'm looking at.

python is:

$ file $(which python)
/Users/sbrown/.virtualenvs/mypkg/bin/python: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
/Users/sbrown/.virtualenvs/mypkg/bin/python (for architecture x86_64):  Mach-O 64-bit executable x86_64
/Users/sbrown/.virtualenvs/mypkg/bin/python (for architecture arm64):   Mach-O 64-bit executable arm64

brew installed libmysqlclient is:

$ file /opt/homebrew/opt/mysql-client/lib/libmysqlclient.21.dylib
/opt/homebrew/opt/mysql-client/lib/libmysqlclient.21.dylib: Mach-O 64-bit dynamically linked shared library arm64

and pip install mysqlclient resulted in:

$ file ~/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so
/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64:Mach-O 64-bit bundle arm64]
/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so (for architecture x86_64):   Mach-O 64-bit bundle x86_64
/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so (for architecture arm64):    Mach-O 64-bit bundle arm64

The GitHub thread has multiple comments referencing looking at symbols <library file> | grep mysql_affected_rows to determine whether the file is arm64 or x86, but nowhere does anyone explain how to tell from the output. I checked on an older x86 MacBook where all of this works and see the same output as shown below, which is consistent with the output shown in the GitHub thread.

❓ Can one actually tell something more about the architecture from the output of symbols that just from file?

$ symbols /opt/homebrew/opt/mysql-client/lib/libmysqlclient.21.dylib | grep mysql_affected_rows
            0x0000000000011c98 (     0x8) mysql_affected_rows [FUNC, EXT, NameNList, MangledNameNList, Merged, NList, FunctionStarts]

$ symbols ~/.virtualenvs/llatitude/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so | grep mysql_affected_rows
            0x0000000000006dcc (     0xc) DYLD-STUB$$mysql_affected_rows [DYLD-STUB, LENGTH, NameNList, MangledNameNList, NList]

❓ Also, as several of the files above are universal architecture, what determines which architecture is selected? After each of many attempted workarounds I've tried the "canary" command shown below running python under both flavors of arch, with the same failure:

$ arch -arm64 python -c 'import MySQLdb'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/__init__.py", line 17, in <module>
    from . import _mysql
ImportError: dlopen(/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '_mysql_affected_rows'

$ arch -x86_64 python -c 'import MySQLdb'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/__init__.py", line 17, in <module>
    from . import _mysql
ImportError: dlopen(/Users/sbrown/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '_mysql_affected_rows'

❓ Does the error above indicate that the symbol isn't found in the .so in the virtualenv? Or that that shared object is calling some other external library and not finding the symbol? otool -tV shows:

$ otool -tV ~/.virtualenvs/mypkg/lib/python3.11/site-packages/MySQLdb/_mysql.cpython-311-darwin.so | grep mysql_affected_rows
0000000000005711    callq   0x70b8                          ## symbol stub for: _mysql_affected_rows
0000000000004cc0    bl  0x6dcc ; symbol stub for: _mysql_affected_rows

Is there an obvious path here I'm overlooking? It seems unlikely to me that something this basic would remain just fundamentally broken at this point, but I'm not sure where to go next.

Scott
  • 1,247
  • 3
  • 10
  • 21

0 Answers0