Lors de la demande d'une URL https://, la méthode request
tombe dans une récursivité infinie.
Le problème est cette méthode dans python/ssl.py
.
@options.setter
def options(self, value):
super(SSLContext, SSLContext).options.__set__(self, value)
Le commit qui a introduit cette ligne dans python est celui-ci https://hg.python.org/cpython/rev/c32e9f9b00f7.
L'erreur réelle ressemble à ceci :
File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 501, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 423, in send
timeout=timeout
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 594, in urlopen
chunked=chunked)
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 350, in _make_request
self._validate_conn(conn)
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 835, in _validate_conn
conn.connect()
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/connection.py", line 311, in connect
cert_reqs=resolve_cert_reqs(self.cert_reqs),
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/util/ssl_.py", line 264, in create_urllib3_context
context.options |= options
File "/usr/local/lib/python3.6/ssl.py", line 459, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "/usr/local/lib/python3.6/ssl.py", line 459, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "/usr/local/lib/python3.6/ssl.py", line 459, in options
super(SSLContext, SSLContext).options.__set__(self, value)
[Previous line repeated 316 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
Testé avec python 3.6.0b4
.
Cela ressemble à un bogue dans la bibliothèque standard, en fait : il semble qu'ils aient introduit une récursivité infinie lors de la définition directe des options. @tiran ?
Je ne peux pas reproduire le problème sur ma machine (Python de la dernière branche hg 3.6)
$ ./python
Python 3.6.0+ (3.6:c4f39b6f3176, Dec 7 2016, 21:55:50)
[GCC 6.2.1 20160916 (Red Hat 6.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ctx = ssl.SSLContext(ssl.PROTOCOL_TLS)
>>> ctx.options |= 5
>>> class MySSLContext(ssl.SSLContext):
... pass
...
>>> ctx = MySSLContext(ssl.PROTOCOL_TLS)
>>> ctx.options |= 5
J'ai juste essayé de le reproduire à partir de la fin des demandes; Je ne peux pas l'atteindre sur 3.6.0b4 ou 3.6.0rc1 :
$ python
Python 3.6.0b4 (v3.6.0b4:18496abdb3d5, Nov 21 2016, 20:44:47)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('https://github.com/kennethreitz/requests/issues/3752')
<Response [200]>
$ python
Python 3.6.0rc1 (v3.6.0rc1:29a273eee9a5, Dec 6 2016, 16:24:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('https://github.com/kennethreitz/requests/issues/3752')
<Response [200]>
Serait-ce quelque chose qui est spécifique à la plate-forme ou à l'URL ?
(OS X 10.12.1, 16B2659, pour ma part)
Les requêtes fonctionnent également avec Python 3.6.0 de hg :
$ ./python -m venv venv
$ venv/bin/pip install requests
Collecting requests
Using cached requests-2.12.3-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.12.3
$ venv/bin/python
Python 3.6.0+ (3.6:c4f39b6f3176, Dec 7 2016, 21:55:50)
[GCC 6.2.1 20160916 (Red Hat 6.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('https://www.python.org')
<Response [200]>
Ok, donc pour le moment, cela ressemble à une situation "impossible de reproduire". Cela vaut peut-être la peine de regarder votre installation
Après un débogage plus poussé, j'ai pu le reproduire en tant que problème gevent
(qui était le contexte dans lequel j'utilisais cela).
Je suppose que je vais devoir l'apporter à des gens pour y jeter un coup d'œil ? Merci d'avoir étudié cela, tout le monde.
root<strong i="8">@8042e3f57981</strong>:/app# python
Python 3.6.0b4 (default, Nov 23 2016, 21:34:29)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gevent.monkey
>>> gevent.monkey.patch_all()
>>>
>>> from requests.packages.urllib3.util.ssl_ import create_urllib3_context
>>> create_urllib3_context()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/requests/packages/urllib3/util/ssl_.py", line 268, in create_urllib3_context
context.options |= options
File "/usr/local/lib/python3.6/ssl.py", line 459, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "/usr/local/lib/python3.6/ssl.py", line 459, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "/usr/local/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
>>>
Oui, c'est un problème de gevent. Je suppose que gevent ne fonctionne pas encore avec Python 3.6.
L'appel super() a l'air bizarre mais c'est correct. C'est la manière générique de récupérer le descripteur d'attribut de la classe parent. C'est un mal nécessaire de changer une propriété dans une sous-classe. Demandez à Google "David Beazley subclass property" et il vous montrera la même chose, https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch08s08.html
>>> from ssl import SSLContext
>>> super(SSLContext, SSLContext).options
<attribute 'options' of '_ssl._SSLContext' objects>
>>> import _ssl
>>> super(SSLContext, SSLContext).options is _ssl._SSLContext.options
True
L'appel super(SSLContext, SSLContext).options.__set__(self, value)
est le même que la définition d'options sur une instance de la classe parent.
Voici la référence au ticket gevent pour le même problème : https://github.com/gevent/gevent/issues/903
Gevent est maintenant passé à >1.2 par défaut. Si vous rencontrez toujours ce problème, il peut être résolu avec un simple pip install --upgrade gevent
.
@pirate qui ne résout pas le problème pour moi. D'autres idées ? L'autre thread est verrouillé.
@AeroNotix s'il vous plaît ne pas utiliser ce problème ou le tracker de ce projet pour discuter des problèmes de gevent.
@pirate peux-tu débloquer ce ticket, alors ? J'ai toujours le même problème sur python 3.6 avec des versions mises à niveau de tout.
Non @AeroNotix , je ne suis contributeur sur aucun des deux projets, peut-être pouvez-vous envoyer un e-mail/irc directement à l'une des personnes de l'autre fil ?
@pirata Ce problème existe toujours avec python 3.6.1
, gevent 1.2.1
, requests 2.13.0
. Étapes à reproduire :
import requests
import gevent.monkey
gevent.monkey.patch_ssl()
requests.get("https://google.com")
Si j'importe requests
après le patch, tout fonctionne. Auparavant, cela n'avait pas d'importance et je me demande si quelque chose peut être modifié pour conserver l'ancien comportement. Qu'en penses-tu @Lukasa ?
Requests a quelques problèmes avec les correctifs de gevent et de singe car il effectue une détection de fonctionnalité sur le module de sélection au moment de l'importation. Une future version le mettra à jour avec une urllib3 plus récente qui contient des correctifs pour ce problème, mais en attendant, le patch Monkey de gevent devrait être appliqué avant d'importer les requêtes.
@Lukasa faites -vous référence à cette version ?
Commentaire le plus utile
Requests a quelques problèmes avec les correctifs de gevent et de singe car il effectue une détection de fonctionnalité sur le module de sélection au moment de l'importation. Une future version le mettra à jour avec une urllib3 plus récente qui contient des correctifs pour ce problème, mais en attendant, le patch Monkey de gevent devrait être appliqué avant d'importer les requêtes.