Saat meminta https:// url, metode request
termasuk dalam rekursi tak terbatas.
Masalahnya adalah metode ini di python/ssl.py
.
@options.setter
def options(self, value):
super(SSLContext, SSLContext).options.__set__(self, value)
Komit yang memperkenalkan baris ini ke python adalah https://hg.python.org/cpython/rev/c32e9f9b00f7 ini
Kesalahan sebenarnya terlihat seperti ini:
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
Diuji menggunakan python 3.6.0b4
.
Ini terdengar seperti ini adalah bug di perpustakaan standar, sebenarnya: sepertinya mereka memperkenalkan rekursi tak terbatas saat mengatur opsi secara langsung. @tiran?
Saya tidak dapat mereproduksi masalah pada mesin saya (Python dari cabang hg 3.6 terbaru)
$ ./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
Saya baru saja mencoba mereproduksinya dari akhir permintaan; Saya tidak bisa melakukannya di 3.6.0b4 atau 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]>
Mungkinkah itu sesuatu yang khusus untuk platform atau URL?
(OS X 10.12.1, 16B2659, untuk bagian saya)
Permintaan juga berfungsi dengan Python 3.6.0 dari 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]>
Oke, jadi sekarang ini terlihat seperti situasi "tidak bisa diulang". Mungkin layak untuk melihat instal Anda @juokaz , tampaknya sedikit berperilaku buruk.
Setelah debugging lebih lanjut, saya dapat mereproduksinya sebagai masalah gevent
(yang merupakan konteks tempat saya menggunakan ini).
Saya kira saya harus mengambilnya untuk membuat orang melihatnya? Terima kasih telah menyelidiki ini, semuanya.
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
>>>
Yup, ini adalah masalah gevent. Saya berasumsi gevent belum berfungsi dengan Python 3.6.
Panggilan super() terlihat aneh tetapi benar. Ini adalah cara umum untuk mengambil deskriptor atribut dari kelas induk. Ini adalah kejahatan yang diperlukan untuk mengubah properti di subclass. Minta Google untuk "properti subkelas David Beazley" dan itu akan menunjukkan hal yang sama, 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
Panggilan super(SSLContext, SSLContext).options.__set__(self, value)
sama dengan opsi pengaturan pada instance kelas induk.
Berikut referensi ke tiket gevent untuk masalah yang sama: https://github.com/gevent/gevent/issues/903
Gevent sekarang telah diubah menjadi >1.2 secara default. Jika Anda masih mengalami masalah ini, itu dapat diperbaiki dengan pip install --upgrade gevent
.
@bajak laut yang tidak memperbaiki masalah bagi saya. Ada ide lain? Utas lainnya terkunci.
@AeroNotix tolong jangan gunakan masalah ini atau pelacak proyek ini untuk membahas masalah gevent.
@bajak laut bisakah kamu membuka kunci tiket itu? Saya masih mengalami masalah yang sama pada python 3.6 dengan versi yang ditingkatkan dari semuanya.
Tidak @AeroNotix , saya bukan kontributor di kedua proyek, mungkin Anda dapat mengirim email/irc salah satu orang di utas lainnya secara langsung?
@pirata Masalah ini masih ada dengan python 3.6.1
, gevent 1.2.1
, requests 2.13.0
. Langkah-langkah untuk mereproduksi:
import requests
import gevent.monkey
gevent.monkey.patch_ssl()
requests.get("https://google.com")
Jika saya mengimpor requests
setelah tambalan, semuanya berfungsi. Dulu kasusnya tidak masalah dan saya bertanya-tanya apakah ada sesuatu yang dapat diubah untuk mempertahankan perilaku lama. Bagaimana menurutmu @Lukasa ?
Permintaan memiliki beberapa masalah dengan tambalan gevent dan monyet karena melakukan deteksi fitur pada modul pilih pada waktu impor. Rilis mendatang akan memperbaruinya dengan urllib3 yang lebih baru yang berisi perbaikan untuk masalah ini, tetapi sementara itu tambalan monyet gevent harus diterapkan sebelum mengimpor permintaan.
@Lukasa apakah Anda mengacu pada rilis ini ?
Komentar yang paling membantu
Permintaan memiliki beberapa masalah dengan tambalan gevent dan monyet karena melakukan deteksi fitur pada modul pilih pada waktu impor. Rilis mendatang akan memperbaruinya dengan urllib3 yang lebih baru yang berisi perbaikan untuk masalah ini, tetapi sementara itu tambalan monyet gevent harus diterapkan sebelum mengimpor permintaan.