Python2.6 pip search 報錯需要將HTTP轉換為HTTPS的錯誤解決

輸入命令行:pip search blade
報錯信息如下:

<code python>
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/pip/basecommand.py", line 139, in main
status = self.run(options, args)
File "/usr/lib/python2.6/site-packages/pip/commands/search.py", line 38, in run
pypi_hits = self.search(query, index_url)
File "/usr/lib/python2.6/site-packages/pip/commands/search.py", line 53, in search
hits = pypi.search({'name': query, 'summary': query}, 'or')
File "/usr/lib64/python2.6/xmlrpclib.py", line 1199, in call
return self.__send(self.__name, args)
File "/usr/lib64/python2.6/xmlrpclib.py", line 1491, in __request
verbose=self.__verbose
File "/usr/lib64/python2.6/xmlrpclib.py", line 1243, in request
headers
ProtocolError: <ProtocolError for pypi.python.org/pypi: 403 Must access using HTTPS instead of HTTP>
</code>

Google上搜索了很多解決方案,例如替換某個文件中http為https(我的安裝目錄根本就沒有那個文件,如何替換)、安裝xx包(安裝了,然并軟)等等,都沒有解決我的問題。
先說解決方法:
修改文件pip/commands/search.py

<code python>
50 def search(self, query, index_url):
51 #pypi = xmlrpclib.ServerProxy(index_url, pip.download.xmlrpclib_transport)
52 pypi = xmlrpclib.ServerProxy(index_url)
53 print ""10,index_url
54 hits = pypi.search({'name': query, 'summary': query}, 'or')
55 return hits
</code>

就是修改pypi的初始化方式,因為ServerProxy類里面會根據(jù)傳入的URL自動選擇是創(chuàng)建http實例還是HTTPS實例
下面是具體的邏輯解析,不感興趣的可以直接跳過了



終極大法,追蹤源碼,最后發(fā)現(xiàn)如下代碼。

xmlrpclib.py文件中,有一個ServerProxy類,init方法中,有如下內(nèi)容:

<code python>
1457 def init(self, uri, transport=None, encoding=None, verbose=0,
1458 allow_none=0, use_datetime=0):
1459 # establish a "logical" server connection
1460
1461 # get the url
1462 import urllib
1463 type, uri = urllib.splittype(uri)
1464 if type not in ("http", "https"):
1465 raise IOError, "unsupported XML-RPC protocol"
1466 self.__host, self.__handler = urllib.splithost(uri)
1467 if not self.__handler:
1468 self.__handler = "/RPC2"
1469 print "transport:", transport
1470 if transport is None:
1471 if type == "https":
1472 transport = SafeTransport(use_datetime=use_datetime)
1473 else:
1474 transport = Transport(use_datetime=use_datetime)
1475 self.__transport = transport
1476 print "isinstance SafeTransport:",isinstance(self.__transport, SafeTransport)
1477 self.__encoding = encoding
1478 self.__verbose = verbose
1479 self.__allow_none = allow_none
</code>

在1471到1474行中,創(chuàng)建了兩個transport,如果type為https,則創(chuàng)建SafeTransport(HTTPS的實例),于是跟蹤傳進來的uri,發(fā)現(xiàn)是HTTPS的頭,但是,并沒有創(chuàng)建SafeTransport實例,再次回頭跟蹤,發(fā)現(xiàn)傳進來的參數(shù)transport并不是None,于是再往回跟蹤,發(fā)現(xiàn)上方調(diào)用層,

pip/commands/search.py 代碼如下:

<code python>
50 def search(self, query, index_url):
51 pypi = xmlrpclib.ServerProxy(index_url, pip.download.xmlrpclib_transport)
53 print ""10,index_url
54 hits = pypi.search({'name': query, 'summary': query}, 'or')
55 return hits
</code>

如此可知,已經(jīng)被指定了,我們再來看看指定的是個啥東東

pip/download.py

<code python>
24 all = ['xmlrpclib_transport', 'get_file_content', 'urlopen',
25 'is_url', 'url_to_path', 'path_to_url', 'path_to_url2',
26 'geturl', 'is_archive_file', 'unpack_vcs_link',
27 'unpack_file_url', 'is_vcs_url', 'is_file_url', 'unpack_http_url']
28
29
30 xmlrpclib_transport = xmlrpclib.Transport()
</code>

到此就明了了,由于指定了Transport,所以,不再重新創(chuàng)建transport,而Transport和SafeTransport的區(qū)別(源碼我就不貼了,源碼在xmlrpclib.py文件的,主要就一個make_connection方法的實現(xiàn)。),就是SafeTransport是Transport的子類,是HTTPS的實現(xiàn)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容