Requests: https: // no funciona con Python 3.6

Creado en 7 dic. 2016  ·  16Comentarios  ·  Fuente: psf/requests

Al solicitar una URL https: //, el método request cae en una recursividad infinita.

El problema es este método en python/ssl.py .

    @options.setter
    def options(self, value):
        super(SSLContext, SSLContext).options.__set__(self, value)

La confirmación que introdujo esta línea en Python es https://hg.python.org/cpython/rev/c32e9f9b00f7.

El error real se ve así:

  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

Probado usando python 3.6.0b4 .

Comentario más útil

Requests tiene algunos problemas con los parches gevent y monkey porque realiza la detección de características en el módulo seleccionado en el momento de la importación. Una versión futura lo actualizará con un urllib3 más nuevo que contiene soluciones para este problema, pero mientras tanto, el parche mono de gevent debe aplicarse antes de importar solicitudes.

Todos 16 comentarios

Esto suena a que esto es un error en la biblioteca estándar, en realidad: parece que introdujeron una recursividad infinita al configurar las opciones directamente. @tiran?

No puedo reproducir el problema en mi máquina (Python de la última rama 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

Intenté reproducirlo desde el final de las solicitudes; No puedo golpearlo en 3.6.0b4 o 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]>

¿Podría ser algo específico de la plataforma o de la URL?

(OS X 10.12.1, 16B2659, por mi parte)

Las solicitudes también funcionan con Python 3.6.0 desde 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]>

Bien, ahora mismo parece una situación de "no se puede reproducir". Podría valer la pena mirar tu instalación @juokaz , parece que se está

Después de una mayor depuración, pude reproducirlo como un problema gevent (que era el contexto en el que estaba usando esto).

Supongo que tendré que llevárselo a la gente para que le eche un vistazo. Gracias a todos por investigar esto.

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
>>>

Sí, este es un tema gentil. Asumiría que gevent aún no funciona con Python 3.6.

La llamada super () parece extraña pero es correcta. Es la forma genérica de obtener el descriptor de atributo de la clase principal. Es un mal necesario cambiar una propiedad en una subclase. Pregunte a Google por la "propiedad de subclase de David Beazley" y le mostrará lo mismo, 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

La llamada super(SSLContext, SSLContext).options.__set__(self, value) es lo mismo que configurar opciones en una instancia de la clase principal.

Aquí está la referencia al ticket de gevent para el mismo problema: https://github.com/gevent/gevent/issues/903
Gevent ahora se ha incrementado a> 1.2 por defecto. Si aún tiene este problema, puede solucionarlo con un simple pip install --upgrade gevent .

@pirate que no me soluciona el problema. ¿Alguna otra idea? El otro hilo está bloqueado.

@AeroNotix, por favor no use este problema o el rastreador de este proyecto para discutir problemas gevent.

@pirate, ¿puedes desbloquear ese boleto, entonces? Sigo teniendo el mismo problema en Python 3.6 con versiones mejoradas de todo.

No, @AeroNotix , no soy un colaborador en ninguno de los proyectos, ¿quizás puedas enviar un correo electrónico / irc a una de las personas en el otro hilo directamente?

@pirata Este problema todavía existe con python 3.6.1 , gevent 1.2.1 , requests 2.13.0 . Pasos para reproducir:

import requests
import gevent.monkey
gevent.monkey.patch_ssl()
requests.get("https://google.com")

Si importo requests después del parche, todo funciona. Solía ​​ser el caso que no importaba y me pregunto si se puede cambiar algo para mantener el comportamiento anterior. ¿Qué opinas @Lukasa ?

Requests tiene algunos problemas con los parches gevent y monkey porque realiza la detección de características en el módulo seleccionado en el momento de la importación. Una versión futura lo actualizará con un urllib3 más nuevo que contiene soluciones para este problema, pero mientras tanto, el parche mono de gevent debe aplicarse antes de importar solicitudes.

@Lukasa, ¿te refieres a este lanzamiento ?

¿Fue útil esta página
0 / 5 - 0 calificaciones