报错信息

源码位置

分析

很尴尬,完全看不出原因导致这个报错

解决方法

通过删除代码的方式一部一部删除,找到了问题出处

原因是包的顺序出现了问题,把位置互换一下,发现没有报错了,但是很明确的告诉你这两个包没有交互关系,没有依赖关系,但是就是这么神奇,为什么这么神奇

看一个实例解释

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 SSLContextgevent.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无限递归错误)的问题解决相关推荐

  1. np.argwhere报错maximum recursion depth exceeded while calling

    完整的报错是:RecursionError: maximum recursion depth exceeded while calling a Python object 解决方法 建议根据代码逻辑修 ...

  2. python递归深度报错--RuntimeError: maximum recursion depth exceeded

    代码上传至https://github.com/gatieme/AderXCoding/blob/master/python/error/depth-exceeded.py 问题 这段时间用Pytho ...

  3. python递归报错 RuntimeError: maximum recursion depth exceeded

    递归是我们常用的一种编程方法,通俗的说就是样一个方法自己调用自己. 今天写爬虫的时候,使用递归出现如下错误 RuntimeError: maximum recursion depth exceeded ...

  4. python编译器报错:“RecursionError: maximum recursion depth exceeded in comparison”解决方案

    python编译器报错:"RecursionError: maximum recursion depth exceeded in comparison"解决方案 在使用递归迭代语句 ...

  5. python RuntimeError: maximum recursion depth exceeded

    QListWidget 使用的时候出现了异常: RuntimeError: maximum recursion depth exceeded 原因:先设置itemSelectionChanged绑定事 ...

  6. Python:pyinstaller报错【A RecursionError maximum recursion depth exceeded occurred】

    pyinstaller demo.py时出现如下问题: ============================================================= A Recursio ...

  7. RecursionError: maximum recursion depth exceeded

    pyinstaller打包报错: RecursionError: maximum recursion depth exceeded 放开那禽兽冲我来 2018-07-13 14:53:41  1036 ...

  8. RuntimeError: maximum recursion depth exceeded

    RuntimeError: maximum recursion depth exceeded 然后长时间运行后出现 RuntimeError: maximum recursion depth exce ...

  9. Django 页面报错 Maximum recursion depth exceeded

    Django 页面报错 Maximum recursion depth exceeded 原因: 视图中某个方法或函数的名称与django模块里的方法重名,而且在内部又调用了同名的方法导致重复调用自己 ...

最新文章

  1. 好书征集第2弹 | 你pick哪本人工智能好书
  2. BZOJ5340 [Ctsc2018]假面 【概率dp】
  3. Microsoft .net 框架开发平台体系架构
  4. 股骨截骨php钢板,股骨远端截骨(DFO)术前设计及手术步骤【附视频】
  5. OPENCV-PYTHON将.GIF格式的图像转为PNG格式
  6. JAVA I/O流工具类TextFile
  7. 2020最详细安装Ubuntu指南
  8. asp.net mvc 使用bootstrap的模态框插件modal
  9. request获得请求参数
  10. js 负数移位运算究竟如何进行
  11. appium+python自动化51-adb文件导入和导出(pull push)
  12. 《5》CentOS7.0+OpenStack+kvm云平台部署—配置Horizon
  13. Android系统信息获取 之三:IMSI号和IMEI解释
  14. COGS2421 简单的Treap
  15. 算下平均分:Excel中Average 、Averagea 函数的使用
  16. 信息论基础 原书第二版 中文版
  17. JavaScript实现按钮点击上/下一张切换图片
  18. 【数值计算方法】学习笔记
  19. Ubuntu18 Cuda10升级Cuda11+Cudnn8+TensorRT7.1+Opencv3
  20. 远程访问树莓派的摄像头实现远程监控

热门文章

  1. 什么样的研究有价值?
  2. Mac文件共享不起作用时该怎么办
  3. 洛谷 深基 第1部分 语言入门 第4章 循环结构程序设计(2022.02.14)
  4. 1.7 编程基础之字符串 27 单词翻转 4分 python
  5. 第62课 捉迷藏 《小学生C++趣味编程》
  6. settimeout需要清除吗_前端20个真正灵魂拷问,前端初级到中级你还需要这个!
  7. python实例 优化目标函数_Scipy优化算法--scipy.optimize.fmin_tnc()/minimize()
  8. birt脚本for循环语句_如何使用 for 循环语句嵌套方法!
  9. Java笔记-RestTemplate(Java进程)配置代理Fiddler抓包
  10. Leaflet笔记-把leaflet-tilelayer-wmts移植到vue cli中(含思路)