Swift REPL starts with error when homebrew python is installed

When I start Swift from the command line I get the following error:

$ swift  
Traceback (most recent call last):
    File "<input>", line 1, in <module>
    File "/usr/local/Cellar/python@2/2.7.15/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
      import weakref
    File "/usr/local/Cellar/python@2/2.7.15/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
  Welcome to Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.39.1). Type :help for assistance.

The problem goes away when uninstalling homebrew's python@2 package, but that's not a true solution.

The version from homebrew is slightly newer

$ which python        
/usr/local/bin/python
$ python --version
Python 2.7.15
$ /usr/bin/python --version
Python 2.7.10

Could it be that somewhere inside Swift, the path to python is still hardcoded?

I mentioned this when Homebrew was still in the process of its Python 3/forced upgrade of Python 2 migration. Essentially, the issue is that LLDB requires the system version of Python 2 that comes with macOS, and will have issues with any other version. Unfortunately, due to the way the Homebrew maintainers have decided to move forward with this migration process, they've made it all but necessary to install their version of Python (which overrides the system's copy of Python) causing the issue you see here. They don't seem to see it as a major issue, so the best thing we have until now is the workaround citied in the thread I linked :slightly_frowning_face:

1 Like

Thx @saagarjha, I am copying the solution here just so that other people don't have to go look for it in the rather long GitHub thread

alias swift="PATH=/System/Library/Frameworks/Python.framework/Versions/Current/bin:$PATH swift"
1 Like

You can simplify this a bit by just using /usr/bin:

alias swift='PATH="/usr/bin:$PATH" swift'

Although that's not the same thing. This unconditionally prefers /usr/bin which usually is not what you want!

Right, only when running swift though.

That would be interesting actually. Does Swift rely on anything specifically (except python which we have established)?

Yeah, I have the following in my .bash_profile, and intend to keep it until someone decides how to really fix the issue:

function fix_python() {
	path="$PATH"
	PATH="/usr/bin:$path"
	"$1" "${@:2}"
	PATH="$path"
}

function lldb() {
	fix_python "$(which lldb)" "$@"
}

function swift() {
	fix_python "$(which swift)" "$@"
}

I'm nitpicking, but you don't need to change PATH globally for this to work:

% which python
/usr/local/bin/python
% PATH="/usr/bin:$PATH" swift
Welcome to Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.39.1). Type :help for assistance.
  1> ^D
% which python
/usr/local/bin/python

Your fix_python function could be as simple as:

function fix_python() {
	PATH="/usr/bin:$PATH" $*
}
2 Likes

A similar error occurs if Python from MacPorts is installed:

$ which python
/opt/local/bin/python

$ swift
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python/lldb/__init__.py", line 98, in <module>
    import six
ImportError: No module named six
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'run_one_line' is not defined
... (more than 1000 lines omitted) ...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'run_one_line' is not defined
Welcome to Apple Swift version 4.1.2 (swiftlang-902.0.54 clang-902.0.39.2). Type :help for assistance.
  1>  

This has also been reported as SR-1061 ImportError: No module named six, however, the bug was closed as “Cannot reproduce.”

Shouldn't swift (or lldb) call the Python interpreter with an absolute path if it relies on the version that comes with macOS?

1 Like

But what if you are not using macOS?

I am interesting to use swift REPL with more modern python2 from the brew (just for fun). The most problem was solved by
pip2 install six
Now there is only one error:
$ command swift
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in
import weakref
File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in
from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Welcome to Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1). Type :help for assistance.
1>

Do anyone has any ideas how to fix it?

Okey, the problem is solved. To run swift REPL with brew python:

pip2 install six
alias swift='DYLD_FRAMEWORK_PATH=/usr/local/opt/python@2/Frameworks/ swift'

Unfortunately your method doesn't work for me.

I've figured out a way to run Swift REPL with brew Python:

cp $(which swift) .
DYLD_FRAMEWORK_PATH="$(brew --prefix python@2)/Frameworks/" ./swift

Is this considered a bug in Swift, a bug in how macOS handles installing multiple versions of the same binary, or just a hazard of installing multiple versions of the same binary?