輸入命令行:pip search blade
報(bào)錯(cuò)信息如下:
<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上搜索了很多解決方案,例如替換某個(gè)文件中http為https(我的安裝目錄根本就沒有那個(gè)文件认境,如何替換)左权、安裝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的初始化方式,因?yàn)镾erverProxy類里面會(huì)根據(jù)傳入的URL自動(dòng)選擇是創(chuàng)建http實(shí)例還是HTTPS實(shí)例
下面是具體的邏輯解析届良,不感興趣的可以直接跳過了
終極大法笆凌,追蹤源碼,最后發(fā)現(xiàn)如下代碼士葫。
xmlrpclib.py文件中乞而,有一個(gè)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)建了兩個(gè)transport,如果type為https荚藻,則創(chuàng)建SafeTransport(HTTPS的實(shí)例)屋灌,于是跟蹤傳進(jìn)來的uri,發(fā)現(xiàn)是HTTPS的頭应狱,但是共郭,并沒有創(chuàng)建SafeTransport實(shí)例,再次回頭跟蹤疾呻,發(fā)現(xiàn)傳進(jì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)被指定了,我們?cè)賮砜纯粗付ǖ氖莻€(gè)啥東東
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文件的,主要就一個(gè)make_connection方法的實(shí)現(xiàn)枚冗。)缓溅,就是SafeTransport是Transport的子類,是HTTPS的實(shí)現(xiàn)赁温。