Skip to content

Commit

Permalink
Drop await aiohttp.request() syntax for sake of context manager (#2541)
Browse files Browse the repository at this point in the history
* Get rid of more yield froms

* Fix #2540: Drop await aiohttp.request() syntax for sake of context manager

* Fix typo

* Work on dropping Python 3.4 functionality

* Fix typo

* Fix flake8

* Fix spelling

* Code cleanup
  • Loading branch information
asvetlov authored Nov 21, 2017
1 parent 39ea168 commit 439c732
Show file tree
Hide file tree
Showing 15 changed files with 201 additions and 292 deletions.
2 changes: 2 additions & 0 deletions CHANGES/2540.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Drop `resp = await aiohttp.request(...)` syntax for sake of `async
with aiohttp.request(...) as resp:`.
190 changes: 96 additions & 94 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import sys
import traceback
import warnings
from collections.abc import Coroutine

from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr
from yarl import URL
Expand All @@ -23,8 +24,7 @@
from .connector import * # noqa
from .connector import TCPConnector
from .cookiejar import CookieJar
from .helpers import (CeilTimeout, TimeoutHandle, _BaseCoroMixin,
deprecated_noop, proxies_from_env, sentinel,
from .helpers import (CeilTimeout, TimeoutHandle, proxies_from_env, sentinel,
strip_auth_from_url)
from .http import WS_KEY, WebSocketReader, WebSocketWriter
from .http_websocket import WSHandshakeError, ws_ext_gen, ws_ext_parse
Expand Down Expand Up @@ -145,29 +145,28 @@ def request(self, method, url, **kwargs):
"""Perform HTTP request."""
return _RequestContextManager(self._request(method, url, **kwargs))

@asyncio.coroutine
def _request(self, method, url, *,
params=None,
data=None,
json=None,
headers=None,
skip_auto_headers=None,
auth=None,
allow_redirects=True,
max_redirects=10,
encoding=None,
compress=None,
chunked=None,
expect100=False,
read_until_eof=True,
proxy=None,
proxy_auth=None,
timeout=sentinel,
verify_ssl=None,
fingerprint=None,
ssl_context=None,
proxy_headers=None,
trace_request_ctx=None):
async def _request(self, method, url, *,
params=None,
data=None,
json=None,
headers=None,
skip_auto_headers=None,
auth=None,
allow_redirects=True,
max_redirects=10,
encoding=None,
compress=None,
chunked=None,
expect100=False,
read_until_eof=True,
proxy=None,
proxy_auth=None,
timeout=sentinel,
verify_ssl=None,
fingerprint=None,
ssl_context=None,
proxy_headers=None,
trace_request_ctx=None):

# NOTE: timeout clamps existing connect and read timeouts. We cannot
# set the default to None because we need to detect if the user wants
Expand Down Expand Up @@ -234,7 +233,7 @@ def _request(self, method, url, *,
]

for trace in traces:
yield from trace.send_request_start(
await trace.send_request_start(
method,
url,
headers
Expand Down Expand Up @@ -288,7 +287,7 @@ def _request(self, method, url, *,
# connection timeout
try:
with CeilTimeout(self._conn_timeout, loop=self._loop):
conn = yield from self._connector.connect(
conn = await self._connector.connect(
req,
traces=traces
)
Expand All @@ -301,7 +300,7 @@ def _request(self, method, url, *,
try:
resp = req.send(conn)
try:
yield from resp.start(conn, read_until_eof)
await resp.start(conn, read_until_eof)
except Exception:
resp.close()
conn.close()
Expand All @@ -318,7 +317,7 @@ def _request(self, method, url, *,
301, 302, 303, 307, 308) and allow_redirects:

for trace in traces:
yield from trace.send_request_redirect(
await trace.send_request_redirect(
method,
url,
headers,
Expand Down Expand Up @@ -390,7 +389,7 @@ def _request(self, method, url, *,
resp._history = tuple(history)

for trace in traces:
yield from trace.send_request_end(
await trace.send_request_end(
method,
url,
headers,
Expand All @@ -406,7 +405,7 @@ def _request(self, method, url, *,
handle = None

for trace in traces:
yield from trace.send_request_exception(
await trace.send_request_exception(
method,
url,
headers,
Expand Down Expand Up @@ -451,24 +450,23 @@ def ws_connect(self, url, *,
proxy_headers=proxy_headers,
compress=compress))

@asyncio.coroutine
def _ws_connect(self, url, *,
protocols=(),
timeout=10.0,
receive_timeout=None,
autoclose=True,
autoping=True,
heartbeat=None,
auth=None,
origin=None,
headers=None,
proxy=None,
proxy_auth=None,
verify_ssl=None,
fingerprint=None,
ssl_context=None,
proxy_headers=None,
compress=0):
async def _ws_connect(self, url, *,
protocols=(),
timeout=10.0,
receive_timeout=None,
autoclose=True,
autoping=True,
heartbeat=None,
auth=None,
origin=None,
headers=None,
proxy=None,
proxy_auth=None,
verify_ssl=None,
fingerprint=None,
ssl_context=None,
proxy_headers=None,
compress=0):

if headers is None:
headers = CIMultiDict()
Expand All @@ -495,15 +493,15 @@ def _ws_connect(self, url, *,
headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr

# send request
resp = yield from self.get(url, headers=headers,
read_until_eof=False,
auth=auth,
proxy=proxy,
proxy_auth=proxy_auth,
verify_ssl=verify_ssl,
fingerprint=fingerprint,
ssl_context=ssl_context,
proxy_headers=proxy_headers)
resp = await self.get(url, headers=headers,
read_until_eof=False,
auth=auth,
proxy=proxy,
proxy_auth=proxy_auth,
verify_ssl=verify_ssl,
fingerprint=fingerprint,
ssl_context=ssl_context,
proxy_headers=proxy_headers)

try:
# check handshake
Expand Down Expand Up @@ -663,7 +661,7 @@ def delete(self, url, **kwargs):
self._request(hdrs.METH_DELETE, url,
**kwargs))

def close(self):
async def close(self):
"""Close underlying connector.
Release all acquired resources.
Expand All @@ -673,8 +671,6 @@ def close(self):
self._connector.close()
self._connector = None

return deprecated_noop('ClientSession.close() is a coroutine')

@property
def closed(self):
"""Is client session closed.
Expand Down Expand Up @@ -717,32 +713,45 @@ def __exit__(self, exc_type, exc_val, exc_tb):
# __exit__ should exist in pair with __enter__ but never executed
pass # pragma: no cover

@asyncio.coroutine
def __aenter__(self):
async def __aenter__(self):
return self

@asyncio.coroutine
def __aexit__(self, exc_type, exc_val, exc_tb):
yield from self.close()
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close()


class _BaseRequestContextManager(_BaseCoroMixin):
class _BaseRequestContextManager(Coroutine):

__slots__ = ('_resp',)
__slots__ = ('_coro', '_resp')

def __init__(self, coro):
super().__init__(coro)
self._coro = coro

@asyncio.coroutine
def __aenter__(self):
self._resp = yield from self._coro
async def __aenter__(self):
self._resp = await self._coro
return self._resp

# @asyncio.coroutine
# def __iter__(self):
# ret = yield from self._coro.__await__()
# return ret

def send(self, arg):
return self._coro.send(arg)

def throw(self, arg):
return self._coro.throw(arg)

def close(self):
return self._coro.close()

def __await__(self):
ret = self._coro.__await__()
return ret


class _RequestContextManager(_BaseRequestContextManager):
@asyncio.coroutine
def __aexit__(self, exc_type, exc, tb):
async def __aexit__(self, exc_type, exc, tb):
# We're basing behavior on the exception as it can be caused by
# user code unrelated to the status of the connection. If you
# would like to close a connection you must do that
Expand All @@ -752,33 +761,26 @@ def __aexit__(self, exc_type, exc, tb):


class _WSRequestContextManager(_BaseRequestContextManager):
@asyncio.coroutine
def __aexit__(self, exc_type, exc, tb):
yield from self._resp.close()
async def __aexit__(self, exc_type, exc, tb):
await self._resp.close()


class _SessionRequestContextManager(_RequestContextManager):
class _SessionRequestContextManager:

__slots__ = _RequestContextManager.__slots__ + ('_session', )
__slots__ = ('_coro', '_resp', '_session')

def __init__(self, coro, session):
super().__init__(coro)
self._coro = coro
self._resp = None
self._session = session

@asyncio.coroutine
def __iter__(self):
try:
return (yield from self._coro)
except Exception:
yield from self._session.close()
raise
async def __aenter__(self):
self._resp = await self._coro
return self._resp

def __await__(self):
try:
return (yield from self._coro)
except Exception:
yield from self._session.close()
raise
async def __aexit__(self, exc_type, exc_val, exc_tb):
self._resp.close()
await self._session.close()


def request(method, url, *,
Expand Down Expand Up @@ -859,4 +861,4 @@ def request(method, url, *,
read_until_eof=read_until_eof,
proxy=proxy,
proxy_auth=proxy_auth,),
session=session)
session)
Loading

0 comments on commit 439c732

Please sign in to comment.