diff --git a/.travis.yml b/.travis.yml index b1b79d8fd70..e69ffd02fb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,5 +64,4 @@ deploy: on: tags: true all_branches: true - python: - - 3.5 + python: 3.5 diff --git a/README.rst b/README.rst index 86c28b1c697..70ce9a565ba 100644 --- a/README.rst +++ b/README.rst @@ -72,9 +72,9 @@ This is simple usage example: async for msg in ws: if msg.type == web.MsgType.text: - ws.send_str("Hello, {}".format(msg.data)) + await ws.send_str("Hello, {}".format(msg.data)) elif msg.type == web.MsgType.binary: - ws.send_bytes(msg.data) + await ws.send_bytes(msg.data) elif msg.type == web.MsgType.close: break diff --git a/aiohttp/_ws_impl.py b/aiohttp/_ws_impl.py index 0e5c9abca33..5004e25ee77 100644 --- a/aiohttp/_ws_impl.py +++ b/aiohttp/_ws_impl.py @@ -11,6 +11,7 @@ from struct import Struct from aiohttp import errors, hdrs, helpers +from aiohttp.helpers import noop from aiohttp.log import ws_logger __all__ = ('WebSocketReader', 'WebSocketWriter', 'do_handshake', @@ -454,7 +455,7 @@ def _send_frame(self, message, opcode): self._output_size = 0 return self.stream.drain() - return () + return noop() def pong(self, message=b''): """Send pong message.""" diff --git a/aiohttp/helpers.py b/aiohttp/helpers.py index e351fb5d01f..47281142606 100644 --- a/aiohttp/helpers.py +++ b/aiohttp/helpers.py @@ -39,13 +39,20 @@ __all__ = ('BasicAuth', 'create_future', 'FormData', 'parse_mimetype', - 'Timeout', 'ensure_future') + 'Timeout', 'ensure_future', 'noop') sentinel = object() Timeout = timeout NO_EXTENSIONS = bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')) +if sys.version_info < (3, 5): + noop = tuple +else: + @asyncio.coroutine + def noop(*args, **kwargs): + pass + class BasicAuth(namedtuple('BasicAuth', ['login', 'password', 'encoding'])): """Http basic authentication helper. diff --git a/tests/test_py35/test_client_websocket_35.py b/tests/test_py35/test_client_websocket_35.py index 80e597a2428..4ebd94c631e 100644 --- a/tests/test_py35/test_client_websocket_35.py +++ b/tests/test_py35/test_client_websocket_35.py @@ -54,6 +54,31 @@ async def handler(request): assert ws.closed +async def test_client_ws_async_with_send(loop, test_server): + # send_xxx methods have to return awaitable objects + + async def handler(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + msg = await ws.receive() + ws.send_str(msg.data + '/answer') + await ws.close() + return ws + + app = web.Application(loop=loop) + app.router.add_route('GET', '/', handler) + + server = await test_server(app) + + async with aiohttp.ClientSession(loop=loop) as client: + async with client.ws_connect(server.make_url('/')) as ws: + await ws.send_str('request') + msg = await ws.receive() + assert msg.data == 'request/answer' + + assert ws.closed + + async def test_client_ws_async_with_shortcut(loop, test_server): async def handler(request): diff --git a/tests/test_py35/test_web_websocket_35.py b/tests/test_py35/test_web_websocket_35.py index 08922473a44..1894b10b48d 100644 --- a/tests/test_py35/test_web_websocket_35.py +++ b/tests/test_py35/test_web_websocket_35.py @@ -12,7 +12,7 @@ async def handler(request): async for msg in ws: assert msg.type == aiohttp.MsgType.TEXT s = msg.data - ws.send_str(s + '/answer') + await ws.send_str(s + '/answer') await ws.close() closed.set_result(1) return ws