gpt4 book ai didi

python - isinstance() 意外返回 False

转载 作者:太空狗 更新时间:2023-10-29 21:00:19 25 4
gpt4 key购买 nike

我正在使用 kubernetes python client .如果我的代码启动时 kubernetes 不可用,我想重试连接。

当客户端无法连接时,它会抛出一个似乎是 urllib3.exceptions.MaxRetryError 的异常,所以我从这样的事情开始:

import time
import urllib3

import kubernetes

kubernetes.config.load_kube_config()
api = kubernetes.client.CoreV1Api()

while True:
try:
w = kubernetes.watch.Watch()
for event in w.stream(api.list_pod_for_all_namespaces):
print event
except urllib3.exceptions.HTTPError:
print('retrying in 1 second')
time.sleep(1)

但这完全失败了;它就像没有 except 语句一样,并通过以下方式退出:

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.122.140', port=8443): Max retries exceeded with url: /api/v1/pods?watch=True (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x2743110>: Failed to establish a new connection: [Errno 111] Connection refused',))

我想也许我对继承的理解并没有我想的那么好,所以我将上面的替换为:

except urllib3.exceptions.MaxRetryError:
print('retrying in 1 second')
time.sleep(1)

以同样的方式失败。为了弄清楚发生了什么,我添加了一个包罗万象的 except 并调用了 pdb:

except Exception as err:
import pdb; pdb.set_trace()

并且从pdb提示符中,我们可以看到:

(Pdb) type(err)
<class 'urllib3.exceptions.MaxRetryError'>

...看起来不错,mro 也是:

(Pdb) import inspect
(Pdb) inspect.getmro(err.__class__)
(<class 'urllib3.exceptions.MaxRetryError'>, <class 'urllib3.exceptions.RequestError'>, <class 'urllib3.exceptions.PoolError'>, <class 'urllib3.exceptions.HTTPError'>, <type 'exceptions.Exception'>, <type 'exceptions.BaseException'>, <type 'object'>)

但尽管如此:

(Pdb) isinstance(err, urllib3.exceptions.MaxRetryError)
False

而且所有的路径看起来都很合理:

(Pdb) urllib3.__file__
'/usr/lib/python2.7/site-packages/urllib3/__init__.pyc'
(Pdb) kubernetes.client.rest.urllib3.__file__
'/usr/lib/python2.7/site-packages/urllib3/__init__.pyc'

那么……这里到底发生了什么?

更新

这是完整的堆栈跟踪:

Traceback (most recent call last):
File "testkube.py", line 13, in <module>
for event in w.stream(api.list_pod_for_all_namespaces):
File "/usr/lib/python2.7/site-packages/kubernetes/watch/watch.py", line 116, in stream
resp = func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 14368, in list_pod_for_all_namespaces
(data) = self.list_pod_for_all_namespaces_with_http_info(**kwargs)
File "/usr/lib/python2.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 14464, in list_pod_for_all_namespaces_with_http_info
collection_formats=collection_formats)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 335, in call_api
_preload_content, _request_timeout)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 148, in __call_api
_request_timeout=_request_timeout)
File "/usr/lib/python2.7/site-packages/kubernetes/client/api_client.py", line 371, in request
headers=headers)
File "/usr/lib/python2.7/site-packages/kubernetes/client/rest.py", line 250, in GET
query_params=query_params)
File "/usr/lib/python2.7/site-packages/kubernetes/client/rest.py", line 223, in request
headers=headers)
File "/usr/lib/python2.7/site-packages/urllib3/request.py", line 66, in request
**urlopen_kw)
File "/usr/lib/python2.7/site-packages/urllib3/request.py", line 87, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "/usr/lib/python2.7/site-packages/urllib3/poolmanager.py", line 321, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 668, in urlopen
**response_kw)
File "/usr/lib/python2.7/site-packages/urllib3/connectionpool.py", line 639, in urlopen
_stacktrace=sys.exc_info()[2])
File "/usr/lib/python2.7/site-packages/urllib3/util/retry.py", line 388, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.122.140', port=8443): Max retries exceeded with url: /api/v1/pods?watch=True (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x3d16110>: Failed to establish a new connection: [Errno 111] Connection refused',))

最佳答案

您的代码间接依赖于 requests 包,而 requests 包有一个奇怪的子模块,名为 requests.packages。这曾经包含来自许多依赖项的复制源代码,包括 urllib3,但他们不再这样做了。不过,他们想保留 requests.packages 以实现向后兼容性,所以现在他们正在做一些奇怪的事情。

requests.packages 不再包括 urllib3 源代码的完整副本,它现在导入 urllib3 并设置 sys。模块['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 urllib3
sys.modules['requests.packages.urllib3'] = urllib3

import idna
sys.modules['requests.packages.idna'] = idna

import chardet
sys.modules['requests.packages.chardet'] = chardet

此代码与导入包的子模块交互不良。如果某些代码尝试执行 import requests.packages.urllib3.exceptions 而 Python 没有找到 sys.modules['requests.packages.urllib3.exceptions'] 条目, Python 将重新创建 urllib3.exceptions 模块并设置urllib3.exceptionssys.modules['requests.packages.urllib3. exceptions'] 到新模块(但它不会触及 sys.modules['urllib3.exceptions']。这将生成所涉及类的新副本,从而导致您的错误。

具有相同原因的相关问题是 reported回到 5 月,导致 2.18.4 中显示的新代码。 2.18.4 应该不会导致您看到的特定问题,但它仍然很脆弱,因为如果 urllib3 的任何子模块当时尚未加载 requests.packages 拧紧 sys.modules,这些子模块会出现您今天看到的相同问题。

关于python - isinstance() 意外返回 False,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46715586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com