When I attempt to run the Python interpretter within lldb
, I'm seeing:
$ lldb
(lldb) script
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
import weakref
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in <module>
from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
When I inspect what version of Python was launched, Python reports that it should be the Homebrew Python (which is symlinked into this location):
>>> sys.executable
'/usr/local/opt/python/bin/python2.7'
However, asking the Python version returns the version associated with the default system Python installation, e.g.
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=10, releaselevel='final', serial=0)
And, just to confirm, the Python version at the binary path above is indeed different (note the difference in the micro version):
$ /usr/local/opt/python/bin/python2.7 --version
Python 2.7.14
$ /usr/bin/python --version
Python 2.7.10
To make things more confusing, the name _remove_dead_weakref
does exist in the _weakref
module for my Homebrew Python installation, but not the default system installation:
$ /usr/bin/python -c "import _weakref; print _weakref._remove_dead_weakref"
Traceback (most recent call last):
File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute '_remove_dead_weakref'
$ /usr/local/opt/python/bin/python2.7 -c "import _weakref; print _weakref._remove_dead_weakref"
<built-in function _remove_dead_weakref>
Any idea what could be causing this apparent cross-talk between my Python installations with LLDB? How can I prevent this?
One workaround to this issue is to explicitly launch LLDB with only the system Python installation on the PATH, e.g.
PATH=/usr/bin /usr/bin/lldb
It appears as though LLDB queries the PATH
for the 'active' Python installation; if you have a Homebrew installation of Python available on the PATH
then you can run into this sort of cross-talk when LLDB attempts to launch Python.
If we run lldb with DYLD_PRINT_LIBRARIES=1
set, then we can see that it's loading the Python.framework from /System/Library, but then some other Python libraries from Homebrew:
dyld: loaded: /System/Library/Frameworks/Python.framework/Versions/2.7/Python
...
dyld: loaded: /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_locale.so
But if we tell DYLD to specifically load Python.framework from Homebrew, then it works:
DYLD_FRAMEWORK_PATH="$(brew --prefix python@2)/Frameworks/" "$(xcrun -f lldb)"
Tested on macOS 10.13.6 with brew'd Python 2.7.15.
Update: When System Integrity Protection is enabled, using DYLD_FRAMEWORK_PATH
may be prohibited on the Xcode Command Line Tools trampoline executables running from /usr/bin
. To work around that, we run xcrun -f lldb
to use the real LLDB executable instead.
You can simply run brew unlink python@2
instead of uninstalling it. This will remove Homebrew's Python 2.x from your PATH. A lot of Homebrew formulas depend on Homebrew's Python 2.x, so you can keep the brew-installed Python 2.x while also fixing the error with lldb.
If you manage your Homebrew setup with Homebrew Bundle, you can add this line to your Brewfile
:
brew "python@2", link: false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With