Skip to content

Commit

Permalink
mypy fixes and compatibility with aiohttp>=3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
mosquito committed Jul 6, 2022
1 parent 0069072 commit 162a39a
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 91 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
with:
args: tox

build:
tests:
needs: lint
runs-on: ubuntu-latest

Expand All @@ -38,19 +38,20 @@ jobs:

matrix:
toxenv:
- py35
- py36
- py37
- py38
- py39
- py310

steps:
- uses: actions/checkout@v2

- name: tox ${{ matrix.toxenv }}
uses: docker://snakepacker/python:all
env:
TOXENV: ${{ matrix.toxenv }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
FORCE_COLOR: yes
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TOXENV: ${{ matrix.toxenv }}
with:
args: tox
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
python_files = test_*
python_functions = test_*
python_classes = TestSuite*
asyncio_mode=auto
30 changes: 13 additions & 17 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@
).load_module()


TEST_REQUIRES = [
"async-timeout~=4.0.2",
"pytest~=7.1.2",
"pytest-aiohttp~=1.0.4",
"pytest-cov~=3.0.0",
"coverage!=4.3",
"coveralls~=3.3.1",
]


setup(
name="wsrpc-aiohttp",
version=module.__version__,
Expand All @@ -31,11 +41,10 @@
"Operating System :: Microsoft",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation :: CPython",
],
long_description=open("README.md").read(),
Expand All @@ -46,24 +55,11 @@
python_requires=">3.5.*, <4",
extras_require={
"ujson": ["ujson"],
"testing": [
"async-timeout",
"pytest",
"pytest-aiohttp",
"pytest-cov",
"coverage!=4.3",
"coveralls",
],
"testing": TEST_REQUIRES,
"develop": [
"async-timeout",
"coverage!=4.3",
"coveralls",
"pytest",
"pytest-aiohttp",
"pytest-cov",
"Sphinx",
"sphinxcontrib-plantuml",
"tox>=2.4",
],
] + TEST_REQUIRES,
},
)
8 changes: 5 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ def application(handler, socket_path):


@pytest.fixture
async def session(aiohttp_client, application, loop) -> ClientSession:
async def session(aiohttp_client, application, event_loop) -> ClientSession:
return await aiohttp_client(application)


@pytest.fixture
async def client(session: ClientSession, socket_path, loop) -> WSRPCClient:
return WSRPCClient(socket_path, session=session, loop=loop)
async def client(
session: ClientSession, socket_path, event_loop
) -> WSRPCClient:
return WSRPCClient(socket_path, session=session, loop=event_loop)
4 changes: 2 additions & 2 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ async def emitter(socket: WSRPCBase):
await socket.emit({"Hello": "world"})


async def test_emitter(client: WSRPCClient, handler, loop):
async def test_emitter(client: WSRPCClient, handler, event_loop):
handler.add_route("emitter", emitter)

async with client:
future = loop.create_future()
future = event_loop.create_future()

client.add_event_listener(future.set_result)

Expand Down
10 changes: 4 additions & 6 deletions tests/test_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,21 @@ def foobar(self):
assert "foobar" not in FooRoute.__no_proxy__


def test_route__init__(loop):
async def test_route__init__(event_loop):
socket = Mock()
socket._loop = object()

route = Route(socket)

assert route.socket is socket
assert route.loop is socket._loop
assert route.loop is event_loop

socket = object()
route = Route(socket)

assert route.socket is socket
assert route.loop is loop
assert route.loop is event_loop


def test_abc_inheritance(loop):
def test_abc_inheritance(event_loop):
class AbstractMixin(ABC):
@abstractmethod
def foo(self):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_rpc_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ async def test_call_when_params_none(


async def test_broadcast(
client: WSRPCClient, handler: WebSocketAsync, route: Route, loop
client: WSRPCClient, handler: WebSocketAsync, route: Route, event_loop
):
async with client:
future = loop.create_future()
future = event_loop.create_future()

async def on_broadcast(_, result):
nonlocal future
Expand Down Expand Up @@ -229,7 +229,7 @@ def get_data(self, _):

async def test_call_timeout(client: WSRPCClient, handler: WebSocketAsync):
async def will_sleep_for(_, seconds):
with timeout(0.5):
async with timeout(0.5):
await asyncio.sleep(seconds)
return DATA_TO_RETURN

Expand Down
8 changes: 4 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[tox]
envlist = lint,mypy,py3{5,6,7,8,9}
envlist = lint,mypy,py3{7,8,9,10}

[testenv]
passenv = COVERALLS_* AMQP_*
passenv = COVERALLS_* AMQP_* GITHUB_* FORCE_COLOR

extras =
testing

commands=
py.test -vv -p no:asyncio \
py.test -vv \
--cov=wsrpc_aiohttp \
--cov-report=term-missing \
--doctest-modules \
Expand All @@ -21,7 +21,7 @@ deps =
pylava

commands=
pylava -o pylava.ini .
pylava -o pylava.ini wsrpc_aiohttp tests

[testenv:mypy]
usedevelop = true
Expand Down
2 changes: 1 addition & 1 deletion wsrpc_aiohttp/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

team_email = "[email protected]"

version_info = (3, 1, 2)
version_info = (3, 2, 1)


__author__ = ", ".join("{} <{}>".format(*info) for info in author_info)
Expand Down
88 changes: 49 additions & 39 deletions wsrpc_aiohttp/websocket/abc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import asyncio
from abc import (
ABC, abstractmethod, abstractclassmethod, abstractproperty,
abstractstaticmethod
)
from abc import ABC, abstractmethod
from enum import IntEnum
from typing import Any, Mapping, Coroutine, Union, Callable, Dict, Tuple

Expand All @@ -16,7 +13,8 @@ class AbstractWebSocket(ABC):
def __init__(self, request: Request):
raise NotImplementedError(request)

@abstractclassmethod
@classmethod
@abstractmethod
def configure(cls, keepalive_timeout: int,
client_timeout: int,
max_concurrent_requests: int) -> None:
Expand Down Expand Up @@ -55,7 +53,8 @@ async def authorize(self) -> bool:
async def __handle_request(self) -> WebSocketResponse:
raise NotImplementedError

@abstractclassmethod
@classmethod
@abstractmethod
def broadcast(
cls, func, callback=None, return_exceptions=True,
**kwargs: Mapping[str, Any]
Expand Down Expand Up @@ -115,7 +114,7 @@ def __getattr__(self, item: str):
EventListenerType = Callable[[Dict[str, Any]], Any]


class AbstactWSRPC(ABC):
class WSRPCBase(ABC):
@abstractmethod
def __init__(self, loop: asyncio.AbstractEventLoop = None,
timeout: Union[int, float] = None):
Expand All @@ -138,28 +137,31 @@ async def handle_message(self, message: WSMessage):
async def _on_message(self, msg: WSMessage):
raise NotImplementedError

@abstractclassmethod
@classmethod
@abstractmethod
def get_routes(cls) -> Mapping[str, "RouteType"]:
raise NotImplementedError

@classmethod
def get_clients(cls) -> Dict[str, "AbstactWSRPC"]:
def get_clients(cls) -> Dict[str, "AbstractWSRPC"]:
raise NotImplementedError

@abstractproperty
@property
@abstractmethod
def routes(self) -> Dict[str, "RouteType"]:
raise NotImplementedError

@property
def clients(self) -> Dict[str, "AbstactWSRPC"]:
def clients(self) -> Dict[str, "AbstractWSRPC"]:
""" Property which contains the socket clients """
raise NotImplementedError

@abstractmethod
def prepare_args(self, args) -> Tuple[Tuple[Any, ...], Dict[str, Any]]:
raise NotImplementedError

@abstractstaticmethod
@staticmethod
@abstractmethod
def is_route(func) -> bool:
raise NotImplementedError

Expand Down Expand Up @@ -217,30 +219,6 @@ async def make_something(self, foo, bar):
async def emit(self, event: Any) -> None:
pass

@abstractclassmethod
def add_route(cls, route: str,
handler: Union[AbstractRoute, Callable]) -> None:
""" Expose local function through RPC
:param route: Name which function will be aliased for this function.
Remote side should call function by this name.
:param handler: Function or Route class (classes based on
:class:`wsrpc_aiohttp.WebSocketRoute`).
For route classes the public methods will
be registered automatically.
.. note::
Route classes might be initialized only once for the each
socket instance.
In case the method of class will be called first,
:func:`wsrpc_aiohttp.WebSocketRoute.init` will be called
without params before callable method.
"""
raise NotImplementedError

@abstractmethod
def add_event_listener(self, func: EventListenerType) -> None:
raise NotImplementedError
Expand All @@ -255,7 +233,8 @@ def remove_route(cls, route: str, fail=True):

raise NotImplementedError

@abstractproperty
@property
@abstractmethod
def proxy(self) -> Proxy:
""" Special property which allow run the remote functions
by `dot` notation
Expand All @@ -272,8 +251,39 @@ def proxy(self) -> Proxy:


RouteType = Union[
Callable[[AbstactWSRPC, Any], Any],
Callable[[AbstactWSRPC, Any], Coroutine[Any, None, Any]],
Callable[[WSRPCBase, Any], Any],
Callable[[WSRPCBase, Any], Coroutine[Any, None, Any]],
AbstractRoute
]


class AbstractWSRPC(WSRPCBase, ABC):
@classmethod
@abstractmethod
def add_route(cls, route: str, handler: RouteType) -> None:
""" Expose local function through RPC
:param route: Name which function will be aliased for this function.
Remote side should call function by this name.
:param handler: Function or Route class (classes based on
:class:`wsrpc_aiohttp.WebSocketRoute`).
For route classes the public methods will
be registered automatically.
.. note::
Route classes might be initialized only once for each
socket instance.
In case the method of class will be called first,
:func:`wsrpc_aiohttp.WebSocketRoute.init` will be called
without params before callable method.
"""
raise NotImplementedError


# backward compatibility for typo
# noinspection SpellCheckingInspection
AbstactWSRPC = AbstractWSRPC
FrameMappingItemType = Mapping[IntEnum, Callable[[WSMessage], Any]]
Loading

0 comments on commit 162a39a

Please sign in to comment.