Requests: https://はPython3.6では機能しません

作成日 2016年12月07日  ·  16コメント  ·  ソース: psf/requests

https:// urlをリクエストすると、 requestメソッドは無限再帰に分類されます。

問題は、 python/ssl.pyこのメソッドです。

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

この行をpythonに導入したコミットは、このhttps://hg.python.org/cpython/rev/c32e9f9b00f7です。

実際のエラーは次のようになります。

  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

python 3.6.0b4を使用してテストしました。

最も参考になるコメント

Requestsは、インポート時にselectモジュールで機能検出を実行するため、geventとmonkeyのパッチ適用に関していくつかの問題があります。 将来のリリースでは、この問題の修正を含む新しいurllib3で最新の状態になりますが、それまでの間、リクエストをインポートする前にgeventのモンキーパッチを適用する必要があります。

全てのコメント16件

これは、実際には標準ライブラリのバグのように聞こえます。オプションを直接設定すると、無限再帰が導入されたようです。 @tiran?

自分のマシンで問題を再現できません(最新のhg 3.6ブランチのPython)

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

リクエストの最後からそれを再現しようとしました。 3.6.0b4または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]>

プラットフォームまたはURL固有のものでしょうか?

(OS X 10.12.1、16B2659、私の部分)

リクエストは、hgのPython3.6.0でも機能します。

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

さて、今のところ、これは「再現できない」状況のように見えます。 インストール@juokazを見る価値があるかもしれませんが、少し誤動作しているようです。

さらにデバッグした後、 gevent問題として再現することができました(これは私がこれを使用していたコンテキストでした)。

私はそれを見てもらうために人々にそれを持って行かなければならないだろうと思いますか? みなさん、これを調べてくれてありがとう。

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

うん、これは重大な問題です。 geventはまだPython3.6では機能しないと思います。

super()呼び出しは奇妙に見えますが、正しいです。 これは、親クラスの属性記述子をフェッチする一般的な方法です。 サブクラスのプロパティを変更することは必要悪です。 Googleに「DavidBeazleyサブクラスプロパティ」を要求すると、同じように表示されます、 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

super(SSLContext, SSLContext).options.__set__(self, value)の呼び出しは、親クラスのインスタンスにオプションを設定するのと同じです。

同じ問題のgeventチケットへの参照は次のとおりです:https://github.com/gevent/gevent/issues/903
Geventは、デフォルトで> 1.2にバンプされました。 それでもこの問題が発生する場合は、簡単なpip install --upgrade geventで修正できます。

私の問題を解決しない@pirate 。 他のアイデアはありますか? もう一方のスレッドはロックされています。

@AeroNotixは、この問題またはこのプロジェクトのトラッカーを使用してgeventの問題を議論しないでください。

@pirateでは、そのチケットのロックを解除できますか? 私はまだすべてのアップグレードされたバージョンでPython3.6で同じ問題を抱えています。

いいえ、 @ AeroNotix 、私はどちらのプロジェクトにも貢献していません。おそらく、他のスレッドの人の1人に直接メール/ ircを送信できますか?

@pirataこの問題は、 python 3.6.1gevent 1.2.1requests 2.13.0でも引き続き発生します。 再現する手順:

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

パッチの後にrequestsをインポートすると、すべてが機能します。 以前は問題ではなかったので、古い動作を維持するために何かを変更できるかどうか疑問に思っています。 @Lukasaはどう思い

Requestsは、インポート時にselectモジュールで機能検出を実行するため、geventとmonkeyのパッチ適用に関していくつかの問題があります。 将来のリリースでは、この問題の修正を含む新しいurllib3で最新の状態になりますが、それまでの間、リクエストをインポートする前にgeventのモンキーパッチを適用する必要があります。

@Lukasaこのリリースを参照し

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

cnicodeme picture cnicodeme  ·  3コメント

iLaus picture iLaus  ·  3コメント

ReimarBauer picture ReimarBauer  ·  4コメント

eromoe picture eromoe  ·  3コメント

NoahCardoza picture NoahCardoza  ·  4コメント