您的代码对
requests程序包具有间接依赖关系,并且
requests程序包具有名为的奇怪子模块
requests.packages。它曾经包含来自多个依赖项(包括)的复制源代码
urllib3,但他们停止这样做。他们想保持
requests.packages向后兼容性,所以现在他们做的事情很奇怪。
相反的requests.packages
,包括一个完整的复制urllib3
的源代码,现在进口urllib3
和套`sys.modules[‘requests.packages.urllib3’]
urllib3
。根据requests
版本的不同,它可能还会设置许多其他sys.modules`条目。例如,从请求2.18.4开始,源代码会
for package in ('urllib3', 'idna', 'chardet'): locals()[package] = __import__(package) # This traversal is apparently necessary such that the identities are # preserved (requests.packages.urllib3.* is urllib3.*) for mod in list(sys.modules): if mod == package or mod.startswith(package + '.'): sys.modules['requests.packages.' + mod] = sys.modules[mod]但在2.17.0中,
import urllib3sys.modules['requests.packages.urllib3'] = urllib3import idnasys.modules['requests.packages.idna'] = idnaimport chardetsys.modules['requests.packages.chardet'] = chardet
此代码与导入包的子模块交互不良。如果某些代码尝试执行该操作,
importrequests.packages.urllib3.exceptions而Python找不到
sys.modules['requests.packages.urllib3.exceptions']条目,则Python将
重新创建
该
urllib3.exceptions模块并进行设置
urllib3.exceptions,并设置
sys.modules['requests.packages.urllib3.exceptions']到新模块(但不会涉及
sys.modules['urllib3.exceptions']。这将生成所涉及类的新副本,从而导致您的错误)。
早在5月份就报告了一个具有相同原因的相关问题,导致了2.18.4中显示的新代码。2.18.4不应引起您所看到的特定问题,但是它仍然很脆弱,因为如果
urllib3在用
requests.packages拧紧时尚未加载的任何子模块
sys.modules,这些子模块将表现出与您今天看到的相同的问题。



