Pip 安装失败:需要 SSL

Pip install fails: SSL required

Collecting rsa==3.1.1 (from -r /racetrack/.requirements.txt (line 41))
eval (python -m virtualfish)
  Downloading rsa-3.1.1.tar.gz
    Complete output from command python setup.py egg_info:
    Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.10.tar.gz
    Traceback (most recent call last):          
      File "/usr/lib/python2.7/urllib2.py", line 558, in http_error_default
        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
    urllib2.HTTPError: HTTP Error 403: SSL is required

解决方案:升级到最新版本的库。

一切都从这里开始,Distutils 团队突然(2017 年 10 月)决定撤销对非 https 请求的支持,而不用担心破坏许多 python 库早期版本的向后兼容性。有点不专业,但嘿这是 Python 世界。

所以这是修复,只需在任何库(nltk==3.2.5 等)

上继续使用最新版本的库(在我的情况下为 rsa==3.4.2

替代解决方案:分叉(或本地复制)repo 版本并将 http url 修改为 https

尽管如此,请注意您是否在维护另一个项目的同时执行此操作,因为您正在升级的依赖项可能与作者预期的原始库不兼容,例如在我的上下文中 rsa 被用于另一个库作为依赖项。因此,解决方案是升级父库,以便自动解决此问题。

使用 easy_install 而不是 pip 对我有用:

easy_install funkload

我正在尝试 pip install funkload 并得到:

Collecting funkload
  Using cached funkload-1.17.1.tar.gz
  Complete output from command python setup.py egg_info:
  Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz
  Traceback (most recent call last):
...<snip>
  urllib2.HTTPError: HTTP Error 403: SSL is required

由于 funkload 从 2011 年开始,旧的 easy_install 有效。

只需 easy_install rsa==3.1.1 即可。

接受的答案在我的情况下不起作用(在长辈 Raspbian 上),但是提供下载 URL 和命令帮助了我 [=14] =]:

sudo pip install paho-mqtt -i https://pypi.python.org/simple

不幸的是,none 之前的答案对我有用。

恕我直言,pip / distutils 选择破坏 http repos 上的包是非常愚蠢的。

我认为更好的选择是:

  • pip/distutils 默认使用 https

  • 如果出现错误,比如403,pip必须提示你"the package repo is on http, do you want to download it?"

2020 年仍有许多 Python 2 个软件包在 http 存储库上;根据他们的决定,这些软件包的安装被破坏了。


我的工作解决方案是一个 python 核心模块的非常简单的补丁:

--- /usr/local/lib/python2.7/urllib2.py.original
+++ /usr/local/lib/python2.7/urllib2.py
@@ -427,6 +427,9 @@
             req = meth(req)

         response = self._open(req, data)
+        if protocol == "http" and response.code == 403 :
+            if isinstance(fullurl, basestring) and fullurl.startswith("http://pypi.python.org/packages/source/d/distribute/") :
+                return    self.open(fullurl.replace("http://", "https://"), data = data, timeout = timeout)

         # post-process response
         meth_name = protocol+"_response"

有效:如果失败 url 在 http 上,请在 https 上重试。

我知道它有点难看,但它很清楚,你也可以快速恢复到原来的模块(复制/usr/local/lib/python2.7/urllib2.py 应用此补丁之前)。