Skip to content

Commit 1070b80

Browse files
committed
Handle all pyright warnings
1 parent cfde802 commit 1070b80

File tree

12 files changed

+58
-38
lines changed

12 files changed

+58
-38
lines changed
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from django.db import models
2+
3+
4+
class TodoItem(models.Model): ...

src/reactpy_django/clean.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def clean_user_data(verbosity: int = 1):
8484
start_time = timezone.now()
8585
user_model = get_user_model()
8686
all_users = user_model.objects.all()
87-
all_user_pks = all_users.values_list(user_model._meta.pk.name, flat=True)
87+
all_user_pks = all_users.values_list(user_model._meta.pk.name, flat=True) # type: ignore
8888

8989
# Django doesn't support using QuerySets as an argument with cross-database relations.
9090
if user_model.objects.db != UserDataModel.objects.db:

src/reactpy_django/components.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232
from django.forms import Form, ModelForm
3333
from django.views import View
3434

35-
from reactpy_django.types import AsyncFormEvent, SyncFormEvent
35+
from reactpy_django.types import AsyncFormEvent, SyncFormEvent, ViewToComponentConstructor, ViewToIframeConstructor
3636

3737

3838
def view_to_component(
3939
view: Callable | View | str,
4040
transforms: Sequence[Callable[[VdomDict], Any]] = (),
4141
strict_parsing: bool = True,
42-
) -> Any:
42+
) -> ViewToComponentConstructor:
4343
"""Converts a Django view to a ReactPy component.
4444
4545
Keyword Args:
@@ -58,7 +58,7 @@ def constructor(
5858
*args,
5959
key: Key | None = None,
6060
**kwargs,
61-
):
61+
) -> ComponentType:
6262
return _view_to_component(
6363
view=view,
6464
transforms=transforms,
@@ -72,7 +72,7 @@ def constructor(
7272
return constructor
7373

7474

75-
def view_to_iframe(view: Callable | View | str, extra_props: dict[str, Any] | None = None):
75+
def view_to_iframe(view: Callable | View | str, extra_props: dict[str, Any] | None = None) -> ViewToIframeConstructor:
7676
"""
7777
Args:
7878
view: The view function or class to convert, or the dotted path to the view.
@@ -88,13 +88,13 @@ def constructor(
8888
*args,
8989
key: Key | None = None,
9090
**kwargs,
91-
):
91+
) -> ComponentType:
9292
return _view_to_iframe(view=view, extra_props=extra_props, args=args, kwargs=kwargs, key=key)
9393

9494
return constructor
9595

9696

97-
def django_css(static_path: str, key: Key | None = None):
97+
def django_css(static_path: str, key: Key | None = None) -> ComponentType:
9898
"""Fetches a CSS static file for use within ReactPy. This allows for deferred CSS loading.
9999
100100
Args:
@@ -107,7 +107,7 @@ def django_css(static_path: str, key: Key | None = None):
107107
return _django_css(static_path=static_path, key=key)
108108

109109

110-
def django_js(static_path: str, key: Key | None = None):
110+
def django_js(static_path: str, key: Key | None = None) -> ComponentType:
111111
"""Fetches a JS static file for use within ReactPy. This allows for deferred JS loading.
112112
113113
Args:
@@ -135,7 +135,7 @@ def django_form(
135135
top_children: Sequence[Any] = (),
136136
bottom_children: Sequence[Any] = (),
137137
key: Key | None = None,
138-
):
138+
) -> ComponentType:
139139
"""Converts a Django form to a ReactPy component.
140140
141141
Args:
@@ -182,7 +182,7 @@ def pyscript_component(
182182
*file_paths: str,
183183
initial: str | VdomDict | ComponentType = "",
184184
root: str = "root",
185-
):
185+
) -> ComponentType:
186186
"""
187187
Args:
188188
file_paths: File path to your client-side component. If multiple paths are \
@@ -219,7 +219,7 @@ def _view_to_component(
219219
else:
220220
_request = HttpRequest()
221221
_request.method = "GET"
222-
resolved_view: Callable = import_module(view) if isinstance(view, str) else view
222+
resolved_view: Callable = import_module(view) if isinstance(view, str) else view # type: ignore
223223

224224
# Render the view render within a hook
225225
@hooks.use_effect(
@@ -251,12 +251,12 @@ def _view_to_iframe(
251251
extra_props: dict[str, Any] | None,
252252
args: Sequence,
253253
kwargs: dict,
254-
) -> VdomDict:
254+
):
255255
"""The actual component. Used to prevent pollution of acceptable kwargs keys."""
256256
from reactpy_django.config import REACTPY_REGISTERED_IFRAME_VIEWS
257257

258258
if hasattr(view, "view_class"):
259-
view = view.view_class
259+
view = view.view_class # type: ignore
260260
dotted_path = view if isinstance(view, str) else generate_obj_name(view)
261261
registered_view = REACTPY_REGISTERED_IFRAME_VIEWS.get(dotted_path)
262262

src/reactpy_django/decorators.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ def _wrapper(*args, **kwargs):
3535

3636
return _wrapper
3737

38-
return decorator
38+
return decorator # type: ignore
3939

4040

41-
@component
41+
@component # type: ignore
4242
def _user_passes_test(component_constructor, fallback, test_func, *args, **kwargs):
4343
"""Dedicated component for `user_passes_test` to allow us to always have access to hooks."""
4444
user = use_user()

src/reactpy_django/forms/transforms.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# type: ignore
12
# TODO: Almost everything in this module should be moved to `reactpy.utils._mutate_vdom()`.
23
from __future__ import annotations
34

src/reactpy_django/hooks.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import asyncio
44
import logging
55
from collections import defaultdict
6+
from collections.abc import Awaitable
67
from typing import (
78
TYPE_CHECKING,
89
Any,
@@ -36,7 +37,7 @@
3637
from reactpy_django.utils import django_query_postprocessor, ensure_async, generate_obj_name, get_pk
3738

3839
if TYPE_CHECKING:
39-
from collections.abc import Awaitable, Sequence
40+
from collections.abc import Sequence
4041

4142
from channels_redis.core import RedisChannelLayer
4243
from django.contrib.auth.models import AbstractUser
@@ -137,13 +138,17 @@ async def execute_query() -> None:
137138
"""The main running function for `use_query`"""
138139
try:
139140
# Run the query
140-
new_data = await ensure_async(query, thread_sensitive=thread_sensitive)(**kwargs)
141+
query_async = cast(
142+
Callable[..., Awaitable[Inferred]], ensure_async(query, thread_sensitive=thread_sensitive)
143+
)
144+
new_data = await query_async(**kwargs)
141145

142146
# Run the postprocessor
143147
if postprocessor:
144-
new_data = await ensure_async(postprocessor, thread_sensitive=thread_sensitive)(
145-
new_data, **postprocessor_kwargs
148+
async_postprocessor = cast(
149+
Callable[..., Awaitable[Any]], ensure_async(postprocessor, thread_sensitive=thread_sensitive)
146150
)
151+
new_data = await async_postprocessor(new_data, **postprocessor_kwargs)
147152

148153
# Log any errors and set the error state
149154
except Exception as e:
@@ -230,7 +235,7 @@ def use_mutation(
230235
async_task_refs = use_ref(set())
231236

232237
# The main "running" function for `use_mutation`
233-
async def execute_mutation(exec_args, exec_kwargs) -> None:
238+
async def execute_mutation(*exec_args: FuncParams.args, **exec_kwargs: FuncParams.kwargs) -> None:
234239
# Run the mutation
235240
try:
236241
should_refetch = await ensure_async(mutation, thread_sensitive=thread_sensitive)(*exec_args, **exec_kwargs)
@@ -262,7 +267,7 @@ def schedule_mutation(*exec_args: FuncParams.args, **exec_kwargs: FuncParams.kwa
262267
set_loading(True)
263268

264269
# Execute the mutation in the background
265-
task = asyncio.ensure_future(execute_mutation(exec_args=exec_args, exec_kwargs=exec_kwargs))
270+
task = asyncio.ensure_future(execute_mutation(*exec_args, **exec_kwargs))
266271

267272
# Add the task to a set to prevent it from being garbage collected
268273
async_task_refs.current.add(task)
@@ -359,7 +364,7 @@ def use_channel_layer(
359364
layer: The channel layer to use. This layer must be defined in \
360365
`settings.py:CHANNEL_LAYERS`.
361366
"""
362-
channel_layer: InMemoryChannelLayer | RedisChannelLayer = get_channel_layer(layer)
367+
channel_layer: InMemoryChannelLayer | RedisChannelLayer = get_channel_layer(layer) # type: ignore
363368
channel_name = use_memo(lambda: str(name or uuid4()))
364369

365370
if not name and not group_name:

src/reactpy_django/http/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from reactpy_django.utils import FileAsyncIterator, render_view
99

1010

11-
def web_modules_file(request: HttpRequest, file: str) -> HttpResponse:
11+
def web_modules_file(request: HttpRequest, file: str) -> FileResponse:
1212
"""Gets JavaScript required for ReactPy modules at runtime."""
1313

1414
web_modules_dir = REACTPY_WEB_MODULES_DIR.current

src/reactpy_django/pyscript/layout_handler.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# type: ignore
12
import asyncio
23
import logging
34

src/reactpy_django/types.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
)
1414

1515
from django.http import HttpRequest
16-
from reactpy.types import Connection
16+
from reactpy.types import ComponentType, Connection, Key
1717
from typing_extensions import ParamSpec
1818

1919
if TYPE_CHECKING:
@@ -98,3 +98,13 @@ async def __call__(self, message: dict) -> None: ...
9898

9999
class AsyncMessageSender(Protocol):
100100
async def __call__(self, message: dict) -> None: ...
101+
102+
103+
class ViewToComponentConstructor(Protocol):
104+
def __call__(
105+
self, request: HttpRequest | None = None, *args: Any, key: Key | None = None, **kwargs: Any
106+
) -> ComponentType: ...
107+
108+
109+
class ViewToIframeConstructor(Protocol):
110+
def __call__(self, *args: Any, key: Key | None = None, **kwargs: Any) -> ComponentType: ...

src/reactpy_django/utils.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ async def render_view(
8080
"""Ingests a Django view (class or function) and returns an HTTP response object."""
8181
# Convert class-based view to function-based view
8282
if getattr(view, "as_view", None):
83-
view = view.as_view()
83+
view = view.as_view() # type: ignore
8484

8585
# Sync/Async function view
86-
response = await ensure_async(view)(request, *args, **kwargs)
86+
response = await ensure_async(view)(request, *args, **kwargs) # type: ignore
8787

8888
# TemplateView needs an extra render step
8989
if getattr(response, "render", None):
@@ -122,7 +122,7 @@ def register_iframe(view: Callable | View | str):
122122
from reactpy_django.config import REACTPY_REGISTERED_IFRAME_VIEWS
123123

124124
if hasattr(view, "view_class"):
125-
view = view.view_class
125+
view = view.view_class # type: ignore
126126
dotted_path = view if isinstance(view, str) else generate_obj_name(view)
127127
try:
128128
REACTPY_REGISTERED_IFRAME_VIEWS[dotted_path] = import_dotted_path(dotted_path)
@@ -165,7 +165,7 @@ def get_loaders(self):
165165
template_source_loaders = []
166166
for e in engines.all():
167167
if hasattr(e, "engine"):
168-
template_source_loaders.extend(e.engine.get_template_loaders(e.engine.loaders))
168+
template_source_loaders.extend(e.engine.get_template_loaders(e.engine.loaders)) # type: ignore
169169
loaders = []
170170
for loader in template_source_loaders:
171171
if hasattr(loader, "loaders"):
@@ -366,7 +366,7 @@ def __enter__(self):
366366
def __exit__(self, *_):
367367
async_to_sync(self.__aexit__)(*_)
368368

369-
def render(self):
369+
def sync_render(self):
370370
return async_to_sync(super().render)()
371371

372372

@@ -413,9 +413,9 @@ def prerender_component(
413413
),
414414
)
415415
) as layout:
416-
vdom_tree = layout.render()["model"]
416+
vdom_tree = layout.sync_render()["model"]
417417

418-
return vdom_to_html(vdom_tree)
418+
return vdom_to_html(vdom_tree) # type: ignore
419419

420420

421421
def vdom_or_component_to_string(
@@ -424,7 +424,7 @@ def vdom_or_component_to_string(
424424
"""Converts a VdomDict or component to an HTML string. If a string is provided instead, it will be
425425
automatically returned."""
426426
if isinstance(vdom_or_component, dict):
427-
return vdom_to_html(vdom_or_component)
427+
return vdom_to_html(vdom_or_component) # type: ignore
428428

429429
if hasattr(vdom_or_component, "render"):
430430
if not request:
@@ -536,17 +536,16 @@ def __init__(self, file_path: str):
536536
self.file_path = file_path
537537

538538
async def __aiter__(self):
539-
file_opened = False
539+
file_handle = None
540540
try:
541541
file_handle = FILE_ASYNC_ITERATOR_THREAD.submit(open, self.file_path, "rb").result()
542-
file_opened = True
543542
while True:
544543
chunk = FILE_ASYNC_ITERATOR_THREAD.submit(file_handle.read, 8192).result()
545544
if not chunk:
546545
break
547546
yield chunk
548547
finally:
549-
if file_opened:
548+
if file_handle:
550549
file_handle.close()
551550

552551

src/reactpy_django/websocket/consumer.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
from channels.auth import login
1717
from channels.generic.websocket import AsyncJsonWebsocketConsumer
1818
from django.utils import timezone
19-
from reactpy.backend.hooks import ConnectionContext
2019
from reactpy.backend.types import Connection, Location
20+
from reactpy.core.hooks import ConnectionContext
2121
from reactpy.core.layout import Layout
2222
from reactpy.core.serve import serve_layout
2323

@@ -210,7 +210,7 @@ async def run_dispatcher(self):
210210
# Start the ReactPy component rendering loop
211211
with contextlib.suppress(Exception):
212212
await serve_layout(
213-
Layout(ConnectionContext(root_component, value=connection)),
213+
Layout(ConnectionContext(root_component, value=connection)), # type: ignore
214214
self.send_json,
215215
self.recv_queue.get,
216216
)

src/reactpy_django/websocket/paths.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
REACTPY_WEBSOCKET_ROUTE = path(
77
f"{REACTPY_URL_PREFIX}/<str:dotted_path>/<uuid:uuid>/<int:has_args>/",
8-
ReactpyAsyncWebsocketConsumer.as_asgi(),
8+
ReactpyAsyncWebsocketConsumer.as_asgi(), # type: ignore
99
)
1010
"""A URL path for :class:`ReactpyAsyncWebsocketConsumer`.
1111

0 commit comments

Comments
 (0)