Python maximum recursion depth exceeded while calling a Python object (gevent的SSL无限递归错误)的问题解决
报错信息
源码位置
分析
很尴尬,完全看不出原因导致这个报错
解决方法
通过删除代码的方式一部一部删除,找到了问题出处
原因是包的顺序出现了问题,把位置互换一下,发现没有报错了,但是很明确的告诉你这两个包没有交互关系,没有依赖关系,但是就是这么神奇,为什么这么神奇
看一个实例解释
vim test.py
:
import gevent.monkey
from requests.packages.urllib3.util.ssl_ import create_urllib3_context# 将monkey patch置于create_urllib3_context引入之前可防止此错误出现。
gevent.monkey.patch_all()create_urllib3_context()
# output:
# Traceback (most recent call last):
# File "test.py", line 7, in <module>
# create_urllib3_context()
# File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/util/ssl_.py", line 265, in create_urllib3_context
# context.options |= options
# File "/usr/lib/python3.6/ssl.py", line 459, in options
# super(SSLContext, SSLContext).options.__set__(self, value)
# File "/usr/lib/python3.6/ssl.py", line 459, in options
# super(SSLContext, SSLContext).options.__set__(self, value)
# File "/usr/lib/python3.6/ssl.py", line 459, in options
# super(SSLContext, SSLContext).options.__set__(self, value)
# [Previous line repeated 329 more times]
# RecursionError: maximum recursion depth exceeded while calling a Python object
debug
create_urllib3_context
代码片段:
...
# requests/packages/urllib3/util/ssl_.py#L250context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)# Setting the default here, as we may have no ssl module on import
cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqsif options is None:options = 0# SSLv2 is easily broken and is considered harmful and dangerousoptions |= OP_NO_SSLv2# SSLv3 has several problems and is now dangerousoptions |= OP_NO_SSLv3# Disable compression to prevent CRIME attacks for OpenSSL 1.0+# (issue #309)options |= OP_NO_COMPRESSIONcontext.options |= options
...
这里的SSLContext
的类型为ssl.SSLContext'
,而不是gevent._ssl3.SSLContext
。 即gevent.monkey.patch_all
对其没起作用。
查看SSLContext
相关代码:
...
# requests/packages/urllib3/util/ssl_.py#L86try:from ssl import SSLContext # Modern SSL?
except ImportError:import sysclass SSLContext(object): # Platform-specific: Python 2 & 3.1supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or(3, 2) <= sys.version_info)
...
from ssl import SSLContext
是gevent.monkey.patch_all
失效的原因所在。 修正为:
import ssl
SSLContext = lambda *args, **kw: ssl.SSLContext(*args, **kw)
当然最好的方案还是在引入gevent
库后立即执行monkey patch
代码。
analysis
gevent.monkey.patch_all
的位置放错导致了create_urllib3_context
中的context
的类型为ssl.SSLContext
而不是gevent._ssl3.SSLContext
。
因此,context.options |= options
最后会调用:
# ssl.py#L457@options.setter
def options(self, value):super(SSLContext, SSLContext).options.__set__(self, value)
而不是:
# gevent/_ssl3.py#L67# In 3.6, these became properties. They want to access the
# property __set__ method in the superclass, and they do so by using
# super(SSLContext, SSLContext). But we rebind SSLContext when we monkey
# patch, which causes infinite recursion.
# https://github.com/python/cpython/commit/328067c468f82e4ec1b5c510a4e84509e010f296
# pylint:disable=no-member
@orig_SSLContext.options.setter
def options(self, value):super(orig_SSLContext, orig_SSLContext).options.__set__(self, value)
但是,由于已经调用过了monkey patch
代码,故此时的SSLContext
实际上是gevent._ssl3.SSLContext
, 是ssl.SSLContext
的子类。
所以,super(SSLContext, SSLContext).options
实际上是super(gevent._ssl3.SSLContext, gevent._ssl3.SSLContext).options
, 得到的结果是ssl.SSLContext.options
,而不是我们所希望的_ssl._SSLContext.options
。
同时,这也造成了无限递归。
Python maximum recursion depth exceeded while calling a Python object (gevent的SSL无限递归错误)的问题解决相关推荐
- np.argwhere报错maximum recursion depth exceeded while calling
完整的报错是:RecursionError: maximum recursion depth exceeded while calling a Python object 解决方法 建议根据代码逻辑修 ...
- python递归深度报错--RuntimeError: maximum recursion depth exceeded
代码上传至https://github.com/gatieme/AderXCoding/blob/master/python/error/depth-exceeded.py 问题 这段时间用Pytho ...
- python递归报错 RuntimeError: maximum recursion depth exceeded
递归是我们常用的一种编程方法,通俗的说就是样一个方法自己调用自己. 今天写爬虫的时候,使用递归出现如下错误 RuntimeError: maximum recursion depth exceeded ...
- python编译器报错:“RecursionError: maximum recursion depth exceeded in comparison”解决方案
python编译器报错:"RecursionError: maximum recursion depth exceeded in comparison"解决方案 在使用递归迭代语句 ...
- python RuntimeError: maximum recursion depth exceeded
QListWidget 使用的时候出现了异常: RuntimeError: maximum recursion depth exceeded 原因:先设置itemSelectionChanged绑定事 ...
- Python:pyinstaller报错【A RecursionError maximum recursion depth exceeded occurred】
pyinstaller demo.py时出现如下问题: ============================================================= A Recursio ...
- RecursionError: maximum recursion depth exceeded
pyinstaller打包报错: RecursionError: maximum recursion depth exceeded 放开那禽兽冲我来 2018-07-13 14:53:41 1036 ...
- RuntimeError: maximum recursion depth exceeded
RuntimeError: maximum recursion depth exceeded 然后长时间运行后出现 RuntimeError: maximum recursion depth exce ...
- Django 页面报错 Maximum recursion depth exceeded
Django 页面报错 Maximum recursion depth exceeded 原因: 视图中某个方法或函数的名称与django模块里的方法重名,而且在内部又调用了同名的方法导致重复调用自己 ...
最新文章
- 好书征集第2弹 | 你pick哪本人工智能好书
- BZOJ5340 [Ctsc2018]假面 【概率dp】
- Microsoft .net 框架开发平台体系架构
- 股骨截骨php钢板,股骨远端截骨(DFO)术前设计及手术步骤【附视频】
- OPENCV-PYTHON将.GIF格式的图像转为PNG格式
- JAVA I/O流工具类TextFile
- 2020最详细安装Ubuntu指南
- asp.net mvc 使用bootstrap的模态框插件modal
- request获得请求参数
- js 负数移位运算究竟如何进行
- appium+python自动化51-adb文件导入和导出(pull push)
- 《5》CentOS7.0+OpenStack+kvm云平台部署—配置Horizon
- Android系统信息获取 之三:IMSI号和IMEI解释
- COGS2421 简单的Treap
- 算下平均分:Excel中Average 、Averagea 函数的使用
- 信息论基础 原书第二版 中文版
- JavaScript实现按钮点击上/下一张切换图片
- 【数值计算方法】学习笔记
- Ubuntu18 Cuda10升级Cuda11+Cudnn8+TensorRT7.1+Opencv3
- 远程访问树莓派的摄像头实现远程监控
热门文章
- 什么样的研究有价值?
- Mac文件共享不起作用时该怎么办
- 洛谷 深基 第1部分 语言入门 第4章 循环结构程序设计(2022.02.14)
- 1.7 编程基础之字符串 27 单词翻转 4分 python
- 第62课 捉迷藏 《小学生C++趣味编程》
- settimeout需要清除吗_前端20个真正灵魂拷问,前端初级到中级你还需要这个!
- python实例 优化目标函数_Scipy优化算法--scipy.optimize.fmin_tnc()/minimize()
- birt脚本for循环语句_如何使用 for 循环语句嵌套方法!
- Java笔记-RestTemplate(Java进程)配置代理Fiddler抓包
- Leaflet笔记-把leaflet-tilelayer-wmts移植到vue cli中(含思路)