Requests: https:// funktioniert nicht mit Python 3.6

Erstellt am 7. Dez. 2016  ·  16Kommentare  ·  Quelle: psf/requests

Beim Anfordern einer https://-URL fällt die Methode request in eine unendliche Rekursion.

Das Problem ist diese Methode in python/ssl.py .

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

Der Commit, der diese Zeile in Python eingeführt hat, ist dieser https://hg.python.org/cpython/rev/c32e9f9b00f7.

Der eigentliche Fehler sieht so aus:

  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

Getestet mit python 3.6.0b4 .

Hilfreichster Kommentar

Requests hat einige Probleme mit Gevent- und Monkey-Patching, da es zum Zeitpunkt des Imports eine Feature-Erkennung auf dem ausgewählten Modul durchführt. Eine zukünftige Version wird es mit einer neueren urllib3 auf den neuesten Stand bringen, die Korrekturen für dieses Problem enthält, aber in der Zwischenzeit sollte der Monkey-Patch von Gevent angewendet werden, bevor Anfragen importiert werden.

Alle 16 Kommentare

Das klingt tatsächlich nach einem Fehler in der Standardbibliothek: Es scheint, als hätten sie beim direkten Einstellen von Optionen eine unendliche Rekursion eingeführt. @tiran?

Ich kann das Problem auf meinem Computer nicht reproduzieren (Python aus dem neuesten hg 3.6-Zweig)

$ ./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

Ich habe gerade versucht, es von der Anforderungsseite aus zu reproduzieren; Ich kann es nicht auf 3.6.0b4 oder 3.6.0rc1 treffen:

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

Könnte es etwas sein, das plattform- oder URL-spezifisch ist?

(OS X 10.12.1, 16B2659, meinerseits)

Requests funktioniert auch mit Python 3.6.0 von 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, im Moment sieht dies nach einer "Kann nicht repro"-Situation aus. Könnte einen Blick auf Ihre Installation

Nach weiterem Debuggen konnte ich es als gevent Problem reproduzieren (in diesem Kontext habe ich es verwendet).

Ich schätze, ich muss es mitnehmen, um Leute zu sehen, um es zu sehen? Danke, dass ihr euch das angeschaut habt, alle.

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

Ja, das ist ein Gevent-Problem. Ich gehe davon aus, dass gevent noch nicht mit Python 3.6 funktioniert.

Der Aufruf super() sieht komisch aus, ist aber richtig. Dies ist die generische Methode, um den Attributdeskriptor der Elternklasse abzurufen. Es ist ein notwendiges Übel, eine Eigenschaft in einer Unterklasse zu ändern. Fragen Sie Google nach "David Beazley subclass property" und es wird Ihnen dasselbe angezeigt ,

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

Der Aufruf super(SSLContext, SSLContext).options.__set__(self, value) dem Setzen von Optionen für eine Instanz der Elternklasse.

Hier ist der Verweis auf das Gevent-Ticket für das gleiche Problem: https://github.com/gevent/gevent/issues/903
Gevent wurde jetzt standardmäßig auf >1.2 erhöht. Wenn dieses Problem weiterhin besteht, kann es mit einem einfachen pip install --upgrade gevent behoben werden.

@pirate das behebt das Problem für mich nicht. Irgendwelche anderen Ideen? Der andere Thread ist gesperrt.

@AeroNotix bitte verwenden Sie dieses Problem oder den Tracker dieses Projekts nicht, um Gevent-Probleme zu diskutieren.

@pirate kannst du das Ticket dann freischalten? Ich habe immer noch das gleiche Problem mit Python 3.6 mit aktualisierten Versionen von allem.

Nein @AeroNotix , ich bin kein Mitwirkender an beiden Projekten, vielleicht kannst du einem der Leute im anderen Thread direkt eine E-Mail senden/irc?

@pirata Dieses Problem besteht immer noch bei python 3.6.1 , gevent 1.2.1 , requests 2.13.0 . Schritte zum Reproduzieren:

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

Wenn ich nach dem Patch requests importiere, funktioniert alles. Früher war es so, dass es egal ist und ich frage mich, ob etwas geändert werden kann, um das alte Verhalten beizubehalten. Was denkst du @Lukasa ?

Requests hat einige Probleme mit Gevent- und Monkey-Patching, da es zum Zeitpunkt des Imports eine Feature-Erkennung auf dem ausgewählten Modul durchführt. Eine zukünftige Version wird es mit einer neueren urllib3 auf den neuesten Stand bringen, die Korrekturen für dieses Problem enthält, aber in der Zwischenzeit sollte der Monkey-Patch von Gevent angewendet werden, bevor Anfragen importiert werden.

@Lukasa beziehst du dich auf diese Veröffentlichung ?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen