reactpy 2.0.0b3__py3-none-any.whl → 2.0.0b5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
reactpy/types.py CHANGED
@@ -1,22 +1,24 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Awaitable, Mapping, Sequence
3
+ import inspect
4
+ from collections.abc import Awaitable, Callable, Mapping, Sequence
4
5
  from dataclasses import dataclass
5
6
  from pathlib import Path
6
7
  from types import TracebackType
7
8
  from typing import (
8
9
  Any,
9
- Callable,
10
10
  Generic,
11
11
  Literal,
12
+ NamedTuple,
13
+ NotRequired,
12
14
  Protocol,
15
+ TypeAlias,
16
+ TypedDict,
13
17
  TypeVar,
18
+ Unpack,
14
19
  overload,
15
- runtime_checkable,
16
20
  )
17
21
 
18
- from typing_extensions import NamedTuple, NotRequired, TypeAlias, TypedDict, Unpack
19
-
20
22
  CarrierType = TypeVar("CarrierType")
21
23
  _Type = TypeVar("_Type")
22
24
 
@@ -26,54 +28,84 @@ class State(NamedTuple, Generic[_Type]):
26
28
  set_value: Callable[[_Type | Callable[[_Type], _Type]], None]
27
29
 
28
30
 
29
- ComponentConstructor = Callable[..., "ComponentType"]
31
+ ComponentConstructor = Callable[..., "Component"]
30
32
  """Simple function returning a new component"""
31
33
 
32
- RootComponentConstructor = Callable[[], "ComponentType"]
34
+ RootComponentConstructor = Callable[[], "Component"]
33
35
  """The root component should be constructed by a function accepting no arguments."""
34
36
 
35
37
 
36
38
  Key: TypeAlias = str | int
37
39
 
38
40
 
39
- @runtime_checkable
40
- class ComponentType(Protocol):
41
- """The expected interface for all component-like objects"""
42
-
43
- key: Key | None
44
- """An identifier which is unique amongst a component's immediate siblings"""
41
+ class Component:
42
+ """An object for rending component models."""
45
43
 
46
- type: Any
47
- """The function or class defining the behavior of this component
44
+ __slots__ = "__weakref__", "_args", "_func", "_kwargs", "_sig", "key", "type"
48
45
 
49
- This is used to see if two component instances share the same definition.
50
- """
46
+ def __init__(
47
+ self,
48
+ function: Callable[..., Component | VdomDict | str | None],
49
+ key: Any | None,
50
+ args: tuple[Any, ...],
51
+ kwargs: dict[str, Any],
52
+ sig: inspect.Signature,
53
+ ) -> None:
54
+ self.key = key
55
+ self.type = function
56
+ self._args = args
57
+ self._kwargs = kwargs
58
+ self._sig = sig
59
+
60
+ def render(self) -> Component | VdomDict | str | None:
61
+ return self.type(*self._args, **self._kwargs)
51
62
 
52
- def render(self) -> VdomDict | ComponentType | str | None:
53
- """Render the component's view model."""
63
+ def __repr__(self) -> str:
64
+ try:
65
+ args = self._sig.bind(*self._args, **self._kwargs).arguments
66
+ except TypeError:
67
+ return f"{self.type.__name__}(...)"
68
+ else:
69
+ items = ", ".join(f"{k}={v!r}" for k, v in args.items())
70
+ if items:
71
+ return f"{self.type.__name__}({id(self):02x}, {items})"
72
+ else:
73
+ return f"{self.type.__name__}({id(self):02x})"
54
74
 
55
75
 
56
76
  _Render_co = TypeVar("_Render_co", covariant=True)
57
77
  _Event_contra = TypeVar("_Event_contra", contravariant=True)
58
78
 
59
79
 
60
- @runtime_checkable
61
- class LayoutType(Protocol[_Render_co, _Event_contra]):
62
- """Renders and delivers, updates to views and events to handlers, respectively"""
80
+ class BaseLayout(Protocol[_Render_co, _Event_contra]):
81
+ """Renders and delivers views, and submits events to handlers."""
82
+
83
+ __slots__: tuple[str, ...] = (
84
+ "__weakref__",
85
+ "_event_handlers",
86
+ "_model_states_by_life_cycle_state_id",
87
+ "_render_tasks",
88
+ "_render_tasks_ready",
89
+ "_rendering_queue",
90
+ "_root_life_cycle_state_id",
91
+ "root",
92
+ )
63
93
 
64
94
  async def render(
65
95
  self,
66
- ) -> _Render_co: ... # Render an update to a view
96
+ ) -> _Render_co:
97
+ """Render an update to a view"""
98
+ ...
67
99
 
68
- async def deliver(
69
- self, event: _Event_contra
70
- ) -> None: ... # Relay an event to its respective handler
100
+ async def deliver(self, event: _Event_contra) -> None:
101
+ """Relay an event to its respective handler"""
102
+ ...
71
103
 
72
104
  async def __aenter__(
73
105
  self,
74
- ) -> LayoutType[
75
- _Render_co, _Event_contra
76
- ]: ... # Prepare the layout for its first render
106
+ ) -> BaseLayout[_Render_co, _Event_contra]:
107
+ """Prepare the layout for its first render"""
108
+ ...
77
109
 
78
110
  async def __aexit__(
79
111
  self,
@@ -82,6 +114,7 @@ class LayoutType(Protocol[_Render_co, _Event_contra]):
82
114
  traceback: TracebackType,
83
115
  ) -> bool | None:
84
116
  """Clean up the view after its final render"""
117
+ ...
85
118
 
86
119
 
87
120
  class CssStyleTypeDict(TypedDict, total=False):
@@ -787,7 +820,7 @@ class VdomTypeDict(TypedDict):
787
820
 
788
821
  tagName: str
789
822
  key: NotRequired[Key | None]
790
- children: NotRequired[Sequence[ComponentType | VdomChild]]
823
+ children: NotRequired[Sequence[Component | VdomChild]]
791
824
  attributes: NotRequired[VdomAttributes]
792
825
  eventHandlers: NotRequired[EventHandlerDict]
793
826
  inlineJavaScript: NotRequired[InlineJavaScriptDict]
@@ -815,7 +848,7 @@ class VdomDict(dict):
815
848
  @overload
816
849
  def __getitem__(
817
850
  self, key: Literal["children"]
818
- ) -> Sequence[ComponentType | VdomChild]: ...
851
+ ) -> Sequence[Component | VdomChild]: ...
819
852
  @overload
820
853
  def __getitem__(self, key: Literal["attributes"]) -> VdomAttributes: ...
821
854
  @overload
@@ -833,7 +866,7 @@ class VdomDict(dict):
833
866
  def __setitem__(self, key: Literal["key"], value: Key | None) -> None: ...
834
867
  @overload
835
868
  def __setitem__(
836
- self, key: Literal["children"], value: Sequence[ComponentType | VdomChild]
869
+ self, key: Literal["children"], value: Sequence[Component | VdomChild]
837
870
  ) -> None: ...
838
871
  @overload
839
872
  def __setitem__(
@@ -857,7 +890,7 @@ class VdomDict(dict):
857
890
  super().__setitem__(key, value)
858
891
 
859
892
 
860
- VdomChild: TypeAlias = ComponentType | VdomDict | str | None | Any
893
+ VdomChild: TypeAlias = Component | VdomDict | str | None | Any
861
894
  """A single child element of a :class:`VdomDict`"""
862
895
 
863
896
  VdomChildren: TypeAlias = Sequence[VdomChild] | VdomChild
@@ -907,19 +940,26 @@ class EventHandlerFunc(Protocol):
907
940
  async def __call__(self, data: Sequence[Any]) -> None: ...
908
941
 
909
942
 
910
- @runtime_checkable
911
- class EventHandlerType(Protocol):
943
+ class BaseEventHandler:
912
944
  """Defines a handler for some event"""
913
945
 
946
+ __slots__ = (
947
+ "__weakref__",
948
+ "function",
949
+ "prevent_default",
950
+ "stop_propagation",
951
+ "target",
952
+ )
953
+
954
+ function: EventHandlerFunc
955
+ """A coroutine which can respond to an event and its data"""
956
+
914
957
  prevent_default: bool
915
958
  """Whether to block the event from propagating further up the DOM"""
916
959
 
917
960
  stop_propagation: bool
918
961
  """Stops the default action associate with the event from taking place."""
919
962
 
920
- function: EventHandlerFunc
921
- """A coroutine which can respond to an event and its data"""
922
-
923
963
  target: str | None
924
964
  """Typically left as ``None`` except when a static target is useful.
925
965
 
@@ -932,10 +972,10 @@ class EventHandlerType(Protocol):
932
972
  """
933
973
 
934
974
 
935
- EventHandlerMapping = Mapping[str, EventHandlerType]
975
+ EventHandlerMapping = Mapping[str, BaseEventHandler]
936
976
  """A generic mapping between event names to their handlers"""
937
977
 
938
- EventHandlerDict: TypeAlias = dict[str, EventHandlerType]
978
+ EventHandlerDict: TypeAlias = dict[str, BaseEventHandler]
939
979
  """A dict mapping between event names to their handlers"""
940
980
 
941
981
  InlineJavaScriptMapping = Mapping[str, InlineJavaScript]
@@ -991,17 +1031,30 @@ class Context(Protocol[_Type]):
991
1031
  *children: Any,
992
1032
  value: _Type = ...,
993
1033
  key: Key | None = ...,
994
- ) -> ContextProviderType[_Type]: ...
1034
+ ) -> ContextProvider[_Type]: ...
995
1035
 
996
1036
 
997
- class ContextProviderType(ComponentType, Protocol[_Type]):
998
- """A component which provides a context value to its children"""
1037
+ class ContextProvider(Component, Generic[_Type]):
1038
+ def __init__(
1039
+ self,
1040
+ *children: Any,
1041
+ value: _Type,
1042
+ key: Key | None,
1043
+ type: Context[_Type],
1044
+ ) -> None:
1045
+ self.children = children
1046
+ self.key = key
1047
+ self.type = type
1048
+ self.value = value
999
1049
 
1000
- type: Context[_Type]
1001
- """The context type"""
1050
+ def render(self) -> VdomDict:
1051
+ from reactpy.core.hooks import HOOK_STACK
1002
1052
 
1003
- @property
1004
- def value(self) -> _Type: ... # Current context value
1053
+ HOOK_STACK.current_hook().set_context_provider(self)
1054
+ return VdomDict(tagName="", children=self.children)
1055
+
1056
+ def __repr__(self) -> str:
1057
+ return f"ContextProvider({self.type})"
1005
1058
 
1006
1059
 
1007
1060
  @dataclass
@@ -1071,3 +1124,19 @@ class CustomVdomConstructor(Protocol):
1071
1124
  class EllipsisRepr:
1072
1125
  def __repr__(self) -> str:
1073
1126
  return "..."
1127
+
1128
+
1129
+ class Event(dict):
1130
+ """
1131
+ A light `dict` wrapper for event data passed to event handler functions.
1132
+ """
1133
+
1134
+ def __getattr__(self, name: str) -> Any:
1135
+ value = self.get(name)
1136
+ return Event(value) if isinstance(value, dict) else value
1137
+
1138
+ def preventDefault(self) -> None:
1139
+ """Prevent the default action of the event."""
1140
+
1141
+ def stopPropagation(self) -> None:
1142
+ """Stop the event from propagating."""
reactpy/utils.py CHANGED
@@ -1,17 +1,17 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
- from collections.abc import Iterable
4
+ from collections.abc import Callable, Iterable
5
5
  from importlib import import_module
6
6
  from itertools import chain
7
- from typing import Any, Callable, Generic, TypeVar, cast
7
+ from typing import Any, Generic, TypeVar, cast
8
8
 
9
9
  from lxml import etree
10
10
  from lxml.html import fromstring
11
11
 
12
12
  from reactpy import html
13
13
  from reactpy.transforms import RequiredTransforms, attributes_to_reactjs
14
- from reactpy.types import ComponentType, VdomDict
14
+ from reactpy.types import Component, VdomDict
15
15
 
16
16
  _RefValue = TypeVar("_RefValue")
17
17
  _ModelTransform = Callable[[VdomDict], Any]
@@ -63,7 +63,7 @@ class Ref(Generic[_RefValue]):
63
63
  return f"{type(self).__name__}({current})"
64
64
 
65
65
 
66
- def reactpy_to_string(root: VdomDict | ComponentType) -> str:
66
+ def reactpy_to_string(root: VdomDict | Component) -> str:
67
67
  """Convert a ReactPy component or `reactpy.html` element into an HTML string.
68
68
 
69
69
  Parameters:
@@ -186,7 +186,7 @@ def _add_vdom_to_etree(parent: etree._Element, vdom: VdomDict | dict[str, Any])
186
186
 
187
187
  for c in vdom.get("children", []):
188
188
  if hasattr(c, "render"):
189
- c = component_to_vdom(cast(ComponentType, c))
189
+ c = component_to_vdom(cast(Component, c))
190
190
  if isinstance(c, dict):
191
191
  _add_vdom_to_etree(element, c)
192
192
 
@@ -232,14 +232,14 @@ def _generate_vdom_children(
232
232
  )
233
233
 
234
234
 
235
- def component_to_vdom(component: ComponentType) -> VdomDict:
235
+ def component_to_vdom(component: Component) -> VdomDict:
236
236
  """Convert the first render of a component into a VDOM dictionary"""
237
237
  result = component.render()
238
238
 
239
239
  if isinstance(result, dict):
240
240
  return result
241
241
  if hasattr(result, "render"):
242
- return component_to_vdom(cast(ComponentType, result))
242
+ return component_to_vdom(cast(Component, result))
243
243
  elif isinstance(result, str):
244
244
  return html.div(result)
245
245
  return html.fragment()
reactpy/web/module.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import filecmp
4
+ import hashlib
4
5
  import logging
5
6
  import shutil
6
7
  from dataclasses import dataclass
@@ -33,6 +34,30 @@ _FILE_WEB_MODULE_CACHE: dict[str, WebModule] = {}
33
34
  _STRING_WEB_MODULE_CACHE: dict[str, WebModule] = {}
34
35
 
35
36
 
37
+ @overload
38
+ def reactjs_component_from_url(
39
+ url: str,
40
+ import_names: str,
41
+ fallback: Any | None = ...,
42
+ resolve_imports: bool | None = ...,
43
+ resolve_imports_depth: int = ...,
44
+ unmount_before_update: bool = ...,
45
+ allow_children: bool = ...,
46
+ ) -> VdomConstructor: ...
47
+
48
+
49
+ @overload
50
+ def reactjs_component_from_url(
51
+ url: str,
52
+ import_names: list[str] | tuple[str, ...],
53
+ fallback: Any | None = ...,
54
+ resolve_imports: bool | None = ...,
55
+ resolve_imports_depth: int = ...,
56
+ unmount_before_update: bool = ...,
57
+ allow_children: bool = ...,
58
+ ) -> list[VdomConstructor]: ...
59
+
60
+
36
61
  def reactjs_component_from_url(
37
62
  url: str,
38
63
  import_names: str | list[str] | tuple[str, ...],
@@ -80,10 +105,38 @@ def reactjs_component_from_url(
80
105
  return _vdom_from_web_module(module, import_names, fallback, allow_children)
81
106
 
82
107
 
108
+ @overload
109
+ def reactjs_component_from_file(
110
+ file: str | Path,
111
+ import_names: str,
112
+ name: str = "",
113
+ fallback: Any | None = ...,
114
+ resolve_imports: bool | None = ...,
115
+ resolve_imports_depth: int = ...,
116
+ unmount_before_update: bool = ...,
117
+ symlink: bool = ...,
118
+ allow_children: bool = ...,
119
+ ) -> VdomConstructor: ...
120
+
121
+
122
+ @overload
123
+ def reactjs_component_from_file(
124
+ file: str | Path,
125
+ import_names: list[str] | tuple[str, ...],
126
+ name: str = "",
127
+ fallback: Any | None = ...,
128
+ resolve_imports: bool | None = ...,
129
+ resolve_imports_depth: int = ...,
130
+ unmount_before_update: bool = ...,
131
+ symlink: bool = ...,
132
+ allow_children: bool = ...,
133
+ ) -> list[VdomConstructor]: ...
134
+
135
+
83
136
  def reactjs_component_from_file(
84
- name: str,
85
137
  file: str | Path,
86
138
  import_names: str | list[str] | tuple[str, ...],
139
+ name: str = "",
87
140
  fallback: Any | None = None,
88
141
  resolve_imports: bool | None = None,
89
142
  resolve_imports_depth: int = 5,
@@ -94,14 +147,14 @@ def reactjs_component_from_file(
94
147
  """Import a component from a file.
95
148
 
96
149
  Parameters:
97
- name:
98
- The name of the package
99
150
  file:
100
151
  The file from which the content of the web module will be created.
101
152
  import_names:
102
153
  One or more component names to import. If given as a string, a single component
103
154
  will be returned. If a list is given, then a list of components will be
104
155
  returned.
156
+ name:
157
+ The human-readable name of the ReactJS package
105
158
  fallback:
106
159
  What to temporarily display while the module is being loaded.
107
160
  resolve_imports:
@@ -118,6 +171,7 @@ def reactjs_component_from_file(
118
171
  allow_children:
119
172
  Whether or not these components can have children.
120
173
  """
174
+ name = name or hashlib.sha256(str(file).encode()).hexdigest()[:10]
121
175
  key = f"{name}{resolve_imports}{resolve_imports_depth}{unmount_before_update}"
122
176
  if key in _FILE_WEB_MODULE_CACHE:
123
177
  module = _FILE_WEB_MODULE_CACHE[key]
@@ -135,10 +189,36 @@ def reactjs_component_from_file(
135
189
  return _vdom_from_web_module(module, import_names, fallback, allow_children)
136
190
 
137
191
 
192
+ @overload
193
+ def reactjs_component_from_string(
194
+ content: str,
195
+ import_names: str,
196
+ name: str = "",
197
+ fallback: Any | None = ...,
198
+ resolve_imports: bool | None = ...,
199
+ resolve_imports_depth: int = ...,
200
+ unmount_before_update: bool = ...,
201
+ allow_children: bool = ...,
202
+ ) -> VdomConstructor: ...
203
+
204
+
205
+ @overload
206
+ def reactjs_component_from_string(
207
+ content: str,
208
+ import_names: list[str] | tuple[str, ...],
209
+ name: str = "",
210
+ fallback: Any | None = ...,
211
+ resolve_imports: bool | None = ...,
212
+ resolve_imports_depth: int = ...,
213
+ unmount_before_update: bool = ...,
214
+ allow_children: bool = ...,
215
+ ) -> list[VdomConstructor]: ...
216
+
217
+
138
218
  def reactjs_component_from_string(
139
- name: str,
140
219
  content: str,
141
220
  import_names: str | list[str] | tuple[str, ...],
221
+ name: str = "",
142
222
  fallback: Any | None = None,
143
223
  resolve_imports: bool | None = None,
144
224
  resolve_imports_depth: int = 5,
@@ -148,14 +228,14 @@ def reactjs_component_from_string(
148
228
  """Import a component from a string.
149
229
 
150
230
  Parameters:
151
- name:
152
- The name of the package
153
231
  content:
154
232
  The contents of the web module
155
233
  import_names:
156
234
  One or more component names to import. If given as a string, a single component
157
235
  will be returned. If a list is given, then a list of components will be
158
236
  returned.
237
+ name:
238
+ The human-readable name of the ReactJS package
159
239
  fallback:
160
240
  What to temporarily display while the module is being loaded.
161
241
  resolve_imports:
@@ -170,6 +250,7 @@ def reactjs_component_from_string(
170
250
  allow_children:
171
251
  Whether or not these components can have children.
172
252
  """
253
+ name = name or hashlib.sha256(content.encode()).hexdigest()[:10]
173
254
  key = f"{name}{resolve_imports}{resolve_imports_depth}{unmount_before_update}"
174
255
  if key in _STRING_WEB_MODULE_CACHE:
175
256
  module = _STRING_WEB_MODULE_CACHE[key]
reactpy/widgets.py CHANGED
@@ -1,13 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from base64 import b64encode
4
- from collections.abc import Sequence
5
- from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar
4
+ from collections.abc import Callable, Sequence
5
+ from typing import Any, Protocol, TypeVar
6
6
 
7
7
  import reactpy
8
8
  from reactpy._html import html
9
- from reactpy._warnings import warn
10
- from reactpy.types import ComponentConstructor, VdomAttributes, VdomDict
9
+ from reactpy.types import VdomAttributes, VdomDict
11
10
 
12
11
 
13
12
  def image(
@@ -22,11 +21,7 @@ def image(
22
21
  if format == "svg":
23
22
  format = "svg+xml" # noqa: A001
24
23
 
25
- if isinstance(value, str):
26
- bytes_value = value.encode()
27
- else:
28
- bytes_value = value
29
-
24
+ bytes_value = value.encode() if isinstance(value, str) else value
30
25
  base64_value = b64encode(bytes_value).decode()
31
26
  src = f"data:image/{format};base64,{base64_value}"
32
27
 
@@ -83,20 +78,3 @@ _CastTo_co = TypeVar("_CastTo_co", covariant=True)
83
78
 
84
79
  class _CastFunc(Protocol[_CastTo_co]):
85
80
  def __call__(self, value: str) -> _CastTo_co: ...
86
-
87
-
88
- if TYPE_CHECKING:
89
- from reactpy.testing.backend import _MountFunc
90
-
91
-
92
- def hotswap(
93
- update_on_change: bool = False,
94
- ) -> tuple[_MountFunc, ComponentConstructor]: # nocov
95
- warn(
96
- "The 'hotswap' function is deprecated and will be removed in a future release",
97
- DeprecationWarning,
98
- stacklevel=2,
99
- )
100
- from reactpy.testing.backend import _hotswap
101
-
102
- return _hotswap(update_on_change)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reactpy
3
- Version: 2.0.0b3
3
+ Version: 2.0.0b5
4
4
  Summary: It's React, but in Python.
5
5
  Project-URL: Changelog, https://reactpy.dev/docs/about/changelog.html
6
6
  Project-URL: Documentation, https://reactpy.dev/
@@ -8,28 +8,26 @@ Project-URL: Source, https://github.com/reactive-python/reactpy
8
8
  Author-email: Mark Bakhit <archiethemonger@gmail.com>, Ryan Morshead <ryan.morshead@gmail.com>
9
9
  License-Expression: MIT
10
10
  License-File: LICENSE
11
- Keywords: component,javascript,react,reactpy
11
+ Keywords: asgi,components,interactive,javascript,react,reactive,reactjs,reactpy,server,website,wsgi
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
16
15
  Classifier: Programming Language :: Python :: 3.12
17
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
19
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
20
- Requires-Python: >=3.9
20
+ Requires-Python: >=3.11
21
21
  Requires-Dist: anyio>=3
22
22
  Requires-Dist: fastjsonschema>=2.14.5
23
23
  Requires-Dist: lxml>=4
24
24
  Requires-Dist: requests>=2
25
- Requires-Dist: typing-extensions>=3.10
26
25
  Provides-Extra: all
27
26
  Requires-Dist: asgi-tools; extra == 'all'
28
27
  Requires-Dist: asgiref; extra == 'all'
29
28
  Requires-Dist: jinja2-simple-tags; extra == 'all'
30
29
  Requires-Dist: jinja2>=3; extra == 'all'
31
30
  Requires-Dist: orjson; extra == 'all'
32
- Requires-Dist: pip; extra == 'all'
33
31
  Requires-Dist: playwright; extra == 'all'
34
32
  Requires-Dist: servestatic; extra == 'all'
35
33
  Requires-Dist: uvicorn[standard]; extra == 'all'
@@ -37,7 +35,6 @@ Provides-Extra: asgi
37
35
  Requires-Dist: asgi-tools; extra == 'asgi'
38
36
  Requires-Dist: asgiref; extra == 'asgi'
39
37
  Requires-Dist: orjson; extra == 'asgi'
40
- Requires-Dist: pip; extra == 'asgi'
41
38
  Requires-Dist: servestatic; extra == 'asgi'
42
39
  Provides-Extra: jinja
43
40
  Requires-Dist: jinja2-simple-tags; extra == 'jinja'