Skip to content

Commit 84fcc1d

Browse files
committed
fix type annotations
1 parent 3b821a7 commit 84fcc1d

File tree

8 files changed

+42
-44
lines changed

8 files changed

+42
-44
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ jobs:
2525
- name: Install Python Dependencies
2626
run: pip install -r requirements/test-run.txt
2727
- name: Run Tests
28-
run: HEADLESS_BROWSER=1 nox
28+
run: HEADLESS=1 nox

docs/source/installation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ If you prefer to run the tests using a headless browser:
101101

102102
.. code-block:: bash
103103
104-
HEADLESS_BROWSER=1 nox
104+
HEADLESS=1 nox
105105
106106
107107
Building The Documentation

idom/dialect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pyalect import DialectError, Dialect
66

77

8-
class HtmlDialectTranspiler(Dialect, name="html"): # type: ignore
8+
class HtmlDialectTranspiler(Dialect, name="html"):
99
"""An HTML dialect transpiler for Python."""
1010

1111
def __init__(self, filename: Optional[str] = None):

idom/server/flask.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from asyncio import Queue as AsyncQueue
66
from threading import Event as ThreadEvent, Thread
77
from queue import Queue as ThreadQueue
8-
from typing import Union, Tuple, Dict, Any, Optional, Callable, NamedTuple
8+
from typing import Union, Tuple, Dict, Any, Optional, Callable, NamedTuple, Type, cast
99

1010
from typing_extensions import TypedDict
1111
from flask import Flask, Blueprint, send_from_directory, redirect, url_for
@@ -17,7 +17,7 @@
1717

1818
import idom
1919
from idom.client.manage import BUILD_DIR
20-
from idom.core.layout import LayoutEvent, Layout
20+
from idom.core.layout import LayoutEvent, Layout, LayoutUpdate
2121
from idom.core.dispatcher import AbstractDispatcher, SingleViewDispatcher
2222

2323
from .base import AbstractRenderServer
@@ -36,7 +36,7 @@ class Config(TypedDict, total=False):
3636
class FlaskRenderServer(AbstractRenderServer[Flask, Config]):
3737
"""Base class for render servers which use Flask"""
3838

39-
_dispatcher_type: AbstractDispatcher
39+
_dispatcher_type: Type[AbstractDispatcher]
4040
_wsgi_server: pywsgi.WSGIServer
4141

4242
def stop(self, timeout: Optional[float] = None) -> None:
@@ -56,10 +56,8 @@ def _create_config(self, config: Optional[Config]) -> Config:
5656
"cors": False,
5757
"serve_static_files": True,
5858
"redirect_root_to_index": True,
59+
**(config or {}), # type: ignore
5960
}
60-
if config is not None:
61-
# BUG: https://github.com/python/mypy/issues/6462
62-
new_config.update(config) # type: ignore
6361
return new_config
6462

6563
def _default_application(self, config: Config) -> Flask:
@@ -79,12 +77,12 @@ def _setup_application(self, config: Config, app: Flask) -> None:
7977

8078
sockets = Sockets(app)
8179

82-
@sockets.route(urljoin(config["url_prefix"], "/stream"))
80+
@sockets.route(urljoin(config["url_prefix"], "/stream")) # type: ignore
8381
def model_stream(ws: WebSocket) -> None:
8482
def send(value: Any) -> None:
8583
ws.send(json.dumps(value))
8684

87-
def recv() -> LayoutEvent:
85+
def recv() -> Optional[LayoutEvent]:
8886
event = ws.receive()
8987
if event is not None:
9088
return LayoutEvent(**json.loads(event))
@@ -104,20 +102,20 @@ def _setup_blueprint_routes(self, config: Config, blueprint: Blueprint) -> None:
104102
if config["serve_static_files"]:
105103

106104
@blueprint.route("/client/<path:path>")
107-
def send_build_dir(path):
105+
def send_build_dir(path: str) -> Any:
108106
return send_from_directory(str(BUILD_DIR), path)
109107

110108
if config["redirect_root_to_index"]:
111109

112110
@blueprint.route("/")
113-
def redirect_to_index():
111+
def redirect_to_index() -> Any:
114112
return redirect(url_for("idom.send_build_dir", path="index.html"))
115113

116114
def _setup_application_did_start_event(
117115
self, config: Config, app: Flask, event: ThreadEvent
118116
) -> None:
119117
@app.before_first_request
120-
def server_did_start():
118+
def server_did_start() -> None:
121119
event.set()
122120

123121
def _run_application(
@@ -149,8 +147,8 @@ def _generic_run_application(
149147
port: int = 5000,
150148
debug: bool = False,
151149
*args: Any,
152-
**kwargs,
153-
):
150+
**kwargs: Any,
151+
) -> None:
154152
if debug:
155153
logging.basicConfig(level=logging.DEBUG) # pragma: no cover
156154
logging.debug("Starting server...")
@@ -180,20 +178,20 @@ def run_dispatcher_in_thread(
180178
dispatch_thread_info_created = ThreadEvent()
181179
dispatch_thread_info_ref: idom.Ref[Optional[_DispatcherThreadInfo]] = idom.Ref(None)
182180

183-
def run_dispatcher():
181+
def run_dispatcher() -> None:
184182
loop = asyncio.new_event_loop()
185183
asyncio.set_event_loop(loop)
186184

187-
thread_send_queue = ThreadQueue()
188-
async_recv_queue = AsyncQueue()
185+
thread_send_queue: "ThreadQueue[LayoutUpdate]" = ThreadQueue()
186+
async_recv_queue: "AsyncQueue[LayoutEvent]" = AsyncQueue()
189187

190188
async def send_coro(value: Any) -> None:
191189
thread_send_queue.put(value)
192190

193191
async def recv_coro() -> Any:
194192
return await async_recv_queue.get()
195193

196-
async def main():
194+
async def main() -> None:
197195
async with make_dispatcher() as dispatcher:
198196
await dispatcher.run(send_coro, recv_coro, context)
199197

@@ -212,12 +210,12 @@ async def main():
212210
Thread(target=run_dispatcher, daemon=True).start()
213211

214212
dispatch_thread_info_created.wait()
215-
dispatch_thread_info = dispatch_thread_info_ref.current
213+
dispatch_thread_info = cast(_DispatcherThreadInfo, dispatch_thread_info_ref.current)
216214
assert dispatch_thread_info is not None
217215

218216
stop = ThreadEvent()
219217

220-
def run_send():
218+
def run_send() -> None:
221219
while not stop.is_set():
222220
send(dispatch_thread_info.thread_send_queue.get())
223221

@@ -242,17 +240,19 @@ def run_send():
242240

243241
class _DispatcherThreadInfo(NamedTuple):
244242
dispatch_loop: asyncio.AbstractEventLoop
245-
dispatch_future: asyncio.Future
246-
thread_send_queue: ThreadQueue
247-
async_recv_queue: AsyncQueue
243+
dispatch_future: "asyncio.Future[Any]"
244+
thread_send_queue: "ThreadQueue[LayoutUpdate]"
245+
async_recv_queue: "AsyncQueue[LayoutEvent]"
248246

249247

250-
class _StartCallbackWSGIServer(pywsgi.WSGIServer):
251-
def __init__(self, before_first_request: Callable[[], None], *args, **kwargs):
248+
class _StartCallbackWSGIServer(pywsgi.WSGIServer): # type: ignore
249+
def __init__(
250+
self, before_first_request: Callable[[], None], *args: Any, **kwargs: Any
251+
) -> None:
252252
self._before_first_request_callback = before_first_request
253253
super().__init__(*args, **kwargs)
254254

255-
def update_environ(self):
255+
def update_environ(self) -> None:
256256
"""
257257
Called before the first request is handled to fill in WSGI environment values.
258258

idom/server/sanic.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ def _create_config(self, config: Optional[Config]) -> Config:
4848
"url_prefix": "",
4949
"serve_static_files": True,
5050
"redirect_root_to_index": True,
51+
**(config or {}), # type: ignore
5152
}
52-
if config is not None:
53-
new_config.update(config)
5453
return new_config
5554

5655
def _default_application(self, config: Config) -> Sanic:

idom/server/tornado.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from threading import Event as ThreadEvent
44
from urllib.parse import urljoin
55
from asyncio import Queue as AsyncQueue
6-
from typing import Optional, Type, Any, List, Tuple, Dict
6+
from typing import Optional, Type, Any, List, Tuple, Dict, Union
77

88
from tornado.web import Application, StaticFileHandler, RedirectHandler, RequestHandler
99
from tornado.websocket import WebSocketHandler
@@ -49,9 +49,8 @@ def _create_config(self, config: Optional[Config]) -> Config:
4949
"base_url": "",
5050
"serve_static_files": True,
5151
"redirect_root_to_index": True,
52+
**(config or {}), # type: ignore
5253
}
53-
if config is not None:
54-
new_config.update(config)
5554
return new_config
5655

5756
def _default_application(self, config: Config) -> Application:
@@ -66,7 +65,7 @@ def _setup_application(
6665
app.add_handlers(
6766
r".*",
6867
[
69-
(urljoin(base_url, route_pattern),) + tuple(handler_info)
68+
(urljoin(base_url, route_pattern),) + tuple(handler_info) # type: ignore
7069
for route_pattern, *handler_info in self._create_route_handlers(config)
7170
],
7271
)
@@ -122,7 +121,7 @@ def _run_application_in_thread(
122121
self._run_application(config, app, host, port, args, kwargs)
123122

124123

125-
class PerClientStateModelStreamHandler(WebSocketHandler): # type: ignore
124+
class PerClientStateModelStreamHandler(WebSocketHandler):
126125
"""A web-socket handler that serves up a new model stream to each new client"""
127126

128127
_dispatcher_type: Type[AbstractDispatcher] = SingleViewDispatcher
@@ -132,7 +131,7 @@ class PerClientStateModelStreamHandler(WebSocketHandler): # type: ignore
132131
def initialize(self, component_constructor: ComponentConstructor) -> None:
133132
self._component_constructor = component_constructor
134133

135-
async def open(self) -> None:
134+
async def open(self, *args: str, **kwargs: str) -> None:
136135
message_queue: "AsyncQueue[str]" = AsyncQueue()
137136
query_params = {k: v[0].decode() for k, v in self.request.arguments.items()}
138137
dispatcher = self._dispatcher_type(
@@ -154,8 +153,10 @@ async def run() -> None:
154153
self._dispatcher_inst = dispatcher
155154
self._message_queue = message_queue
156155

157-
async def on_message(self, message: str) -> None:
158-
await self._message_queue.put(message)
156+
async def on_message(self, message: Union[str, bytes]) -> None:
157+
await self._message_queue.put(
158+
message if isinstance(message, str) else message.decode()
159+
)
159160

160161
def on_close(self) -> None:
161162
asyncio.ensure_future(self._dispatcher_inst.__aexit__(None, None, None))

noxfile.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from nox.sessions import Session
66

77

8-
HEADLESS_BROWSER = bool(int(os.environ.get("HEADLESS_BROWSER", "0")))
8+
HEADLESS = bool(int(os.environ.get("HEADLESS", "0")))
99
BLACK_DEFAULT_EXCLUDE = r"\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|\.svn|_build|buck-out|build|dist"
1010

1111

@@ -26,10 +26,8 @@ def test_with_coverage(session: Session) -> None:
2626
@nox.session
2727
def check_types(session: Session) -> None:
2828
session.install("-r", "requirements/check-types.txt")
29-
session.log("Check Packages (strict)")
29+
session.install(".[all]")
3030
session.run("mypy", "--strict", "idom")
31-
session.log("Check Tests (lenient)")
32-
session.run("mypy", "tests")
3331

3432

3533
@nox.session
@@ -60,7 +58,7 @@ def _test_setup(session: Session) -> None:
6058

6159
def _test_run(session: Session, extra_args: Iterable[str] = ()) -> None:
6260
args = ["pytest", "tests"]
63-
if HEADLESS_BROWSER:
61+
if HEADLESS:
6462
args.append("--headless")
6563
args.extend(extra_args)
6664
session.run(*args)

tests/driver_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ def no_such_element(driver: WebDriver, method: str, param: Any) -> bool:
1515
except NoSuchElementException:
1616
return True
1717
else:
18-
raise False
18+
return False

0 commit comments

Comments
 (0)