Requests: https:// ne fonctionne pas avec Python 3.6

Créé le 7 déc. 2016  ·  16Commentaires  ·  Source: psf/requests

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 .

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.

Tous les 16 commentaires

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 ?

Cette page vous a été utile?
0 / 5 - 0 notes