問題
概要
pipをアップデートしようと思い、コマンドを実行したところ、sslがねーぞということでアップデートできなかった。
解決策
アップグレードが原因で、pythonをインストールした時点に入っていたopensslのライブラリを見つけることができなかったことが原因とわかった。
今回は、古いバージョンのopensslが残っていたため、install_name_toolを使って共有ライブラリの場所を教えてあげるか、シンボリックリンクを貼り直すことで解決できた。
環境
- MacOS Mojave
- python 3.6.3
- openssl(ver1.0と1.1が共存)
問題発生
pipをアップデートしようと思い、コマンドを実行したところ、sslがねーぞというエラーが出てきてアップデートできなかった。
hoge-Macbook:~ hoge$ pip install -U pip
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/pip/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/pip/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/pip/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/pip/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/pip/
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)) - skipping
Requirement already up-to-date: pip in ./.pyenv/versions/3.6.3/lib/python3.6/site-packages (19.3.1)
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)) - skipping
試しにpythonのシェルからimport sslを実行すると、ライブラリが見つからんっぽいエラーが出た。
>>> import ssl
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/ssl.py", line 101, in <module>
import _ssl # if we can't import it, let the error propagate
ImportError: dlopen(/Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so, 2): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
Referenced from: /Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so
Reason: image not found
原因追求
/Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.soという動的ライブラリでこけているようなので、otoolで依存しているライブラリの確認を行った。その結果、opensslでバージョン1.0.0のライブラリを必要としていることがわかった。
hoge-Macbook:Users hoge$ otool -L /Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so
/Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so:
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
が、しかし、1.0.0のライブラリが入っているはずのディレクトリ(/usr/local/opt/openssl/lib)には1.1が入っていた。
hoge-Macbook:Users hoge$ ls /usr/local/opt/openssl/lib
engines-1.1 libcrypto.a libssl.1.1.dylib libssl.dylib
libcrypto.1.1.dylib libcrypto.dylib libssl.a pkgconfig
ls -l /usr/local/opt/
lrwxr-xr-x 1 hoge admin 28 4 29 12:41 openssl -> ../Cellar/openssl@1.1/1.1.1f
ということは、1.0.0がなくて、エラーが出ているということなので、opensslを探し出さなければならない。
対処
探してみると、openssl(ver1.0.0)はmacにまだ残っていたようなので、1.0.0があるディレクトリを教えてあげることにした。
対処法1. install_name_toolを使ってライブラリの場所を書き換える
otoolを実行した際に出てきた依存している2つのライブラリlibssl.1.0.0.dylib, libcrypto.1.0.0.dylibの場所をinstall_name_toolを使って正しい場所に書き換えた。
install_name_tool -change /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/Cellar/openssl/1.0.2s/lib/libssl.1.0.0.dylib /Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so
install_name_tool -change /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/Cellar/openssl/1.0.2s/lib/libcrypto.1.0.0.dylib /Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so
hoge-Macbook:procon hoge$ otool -L /Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so
/Users/hoge/.pyenv/versions/3.6.3/lib/python3.6/lib-dynload/_ssl.cpython-36m-darwin.so:
/usr/local/Cellar/openssl/1.0.2s/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/openssl/1.0.2s/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
対処法2. シンボリックリンクを書き換える
install_name_toolを使わなくても、シンボリックリンクを張り直して、1.0.0の方を指すようにすれば対処できる。
ln -nfs /usr/local/Cellar/openssl/1.0.2s/ /usr/local/opt/openssl
結果
1か2のいずれかの対処法を行うことでimport sslできるようになり、pipも
アップデートできた。