Requests: https://λŠ” Python 3.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)

이 라인을 νŒŒμ΄μ¬μ— λ„μž…ν•œ 컀밋은 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 μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈν–ˆμŠ΅λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μš”μ²­μ€ κ°€μ Έμ˜¬ λ•Œ 선택 λͺ¨λ“ˆμ—μ„œ κΈ°λŠ₯ 감지λ₯Ό μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ— gevent 및 monkey νŒ¨μΉ˜μ— λͺ‡ 가지 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. ν–₯ν›„ λ¦΄λ¦¬μŠ€μ—μ„œλŠ” 이 λ¬Έμ œμ— λŒ€ν•œ μˆ˜μ • 사항이 ν¬ν•¨λœ μ΅œμ‹  urllib3둜 μ—…λ°μ΄νŠΈν•  μ˜ˆμ •μ΄μ§€λ§Œ κ·Έ λ™μ•ˆ μš”μ²­μ„ κ°€μ Έμ˜€κΈ° 전에 gevent의 μ›μˆ­μ΄ 패치λ₯Ό μ μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

λͺ¨λ“  16 λŒ“κΈ€

이것은 ν‘œμ€€ 라이브러리의 버그인 κ²ƒμ²˜λŸΌ λ“€λ¦¬μ§€λ§Œ μ‹€μ œλ‘œλŠ” μ˜΅μ…˜μ„ 직접 μ„€μ •ν•  λ•Œ λ¬΄ν•œ μž¬κ·€λ₯Ό λ„μž…ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. @ν‹°λž€?

λ‚΄ μ»΄ν“¨ν„°μ—μ„œ 문제λ₯Ό μž¬ν˜„ν•  수 μ—†μŠ΅λ‹ˆλ‹€(μ΅œμ‹  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의 Python 3.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 문제둜 μž¬ν˜„ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€(μ΄λŠ” λ‚΄κ°€ 이것을 μ‚¬μš©ν–ˆλ˜ μ»¨ν…μŠ€νŠΈμ˜€μŠ΅λ‹ˆλ‹€).

제 생각엔 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 λ¬Έμ œμž…λ‹ˆλ‹€. λ‚˜λŠ” geventκ°€ 아직 Python 3.6μ—μ„œ μž‘λ™ν•˜μ§€ μ•ŠλŠ”λ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.

super() 호좜이 이상해 λ³΄μ΄μ§€λ§Œ λ§žμŠ΅λ‹ˆλ‹€. λΆ€λͺ¨ 클래슀의 속성 μ„€λͺ…μžλ₯Ό κ°€μ Έμ˜€λŠ” 일반적인 λ°©λ²•μž…λ‹ˆλ‹€. ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ 속성을 λ³€κ²½ν•˜λŠ” 것은 ν•„μš”μ•…μž…λ‹ˆλ‹€. Google에 "David Beazley ν•˜μœ„ 클래슀 속성"을 μš”μ²­ν•˜λ©΄ λ™μΌν•œ λ‚΄μš©μ΄ ν‘œμ‹œλ©λ‹ˆλ‹€( 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 그럼 κ·Έ 티켓을 잠금 ν•΄μ œν•  수 μžˆλ‚˜μš”? λ‚˜λŠ” μ—¬μ „νžˆ λͺ¨λ“  것이 μ—…κ·Έλ ˆμ΄λ“œ 된 λ²„μ „μœΌλ‘œ python 3.6μ—μ„œ λ™μΌν•œ 문제λ₯Ό κ²ͺκ³  μžˆμŠ΅λ‹ˆλ‹€.

μ•„λ‹ˆμš” @AeroNotix , μ €λŠ” 두 ν”„λ‘œμ νŠΈμ˜ κΈ°μ—¬μžκ°€ μ•„λ‹™λ‹ˆλ‹€. λ‹€λ₯Έ μŠ€λ ˆλ“œμ— μžˆλŠ” μ‚¬λžŒ 쀑 ν•œ λͺ…μ—κ²Œ 직접 이메일/IRCλ₯Ό 보낼 수 μžˆμŠ΅λ‹ˆκΉŒ?

@pirata 이 λ¬Έμ œλŠ” python 3.6.1 , gevent 1.2.1 , requests 2.13.0 μ—¬μ „νžˆ μ‘΄μž¬ν•©λ‹ˆλ‹€. μž¬ν˜„ 단계:

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

패치 ν›„ requests κ°€μ Έμ˜€λ©΄ λͺ¨λ“  것이 μž‘λ™ν•©λ‹ˆλ‹€. μ˜ˆμ „μ—λŠ” 상관없을 μ •λ„μ˜€λŠ”λ° μ˜ˆμ „ 행동을 μœ μ§€ν•˜κΈ° μœ„ν•΄ λ­”κ°€λ₯Ό λ°”κΏ€ 수 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€. @Lukasa μ–΄λ–»κ²Œ 생각

μš”μ²­μ€ κ°€μ Έμ˜¬ λ•Œ 선택 λͺ¨λ“ˆμ—μ„œ κΈ°λŠ₯ 감지λ₯Ό μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ— gevent 및 monkey νŒ¨μΉ˜μ— λͺ‡ 가지 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. ν–₯ν›„ λ¦΄λ¦¬μŠ€μ—μ„œλŠ” 이 λ¬Έμ œμ— λŒ€ν•œ μˆ˜μ • 사항이 ν¬ν•¨λœ μ΅œμ‹  urllib3둜 μ—…λ°μ΄νŠΈν•  μ˜ˆμ •μ΄μ§€λ§Œ κ·Έ λ™μ•ˆ μš”μ²­μ„ κ°€μ Έμ˜€κΈ° 전에 gevent의 μ›μˆ­μ΄ 패치λ₯Ό μ μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

@Lukasa 이번 릴리슀 λ₯Ό λ§μ”€ν•˜μ‹œλŠ” κ±΄κ°€μš”?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰