strawberry-graphql 0.224.1__py3-none-any.whl → 0.224.2__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.
- strawberry/extensions/context.py +60 -56
- {strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/METADATA +1 -1
- {strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/RECORD +6 -6
- {strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/entry_points.txt +0 -0
strawberry/extensions/context.py
CHANGED
@@ -2,14 +2,15 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import contextlib
|
4
4
|
import inspect
|
5
|
+
import types
|
5
6
|
import warnings
|
6
7
|
from asyncio import iscoroutinefunction
|
7
8
|
from typing import (
|
8
9
|
TYPE_CHECKING,
|
9
10
|
Any,
|
10
|
-
|
11
|
+
AsyncContextManager,
|
11
12
|
Callable,
|
12
|
-
|
13
|
+
ContextManager,
|
13
14
|
List,
|
14
15
|
NamedTuple,
|
15
16
|
Optional,
|
@@ -28,12 +29,18 @@ if TYPE_CHECKING:
|
|
28
29
|
|
29
30
|
class WrappedHook(NamedTuple):
|
30
31
|
extension: SchemaExtension
|
31
|
-
|
32
|
+
hook: Callable[..., Union[AsyncContextManager[None], ContextManager[None]]]
|
32
33
|
is_async: bool
|
33
34
|
|
34
35
|
|
35
36
|
class ExtensionContextManagerBase:
|
36
|
-
__slots__ = (
|
37
|
+
__slots__ = (
|
38
|
+
"hooks",
|
39
|
+
"deprecation_message",
|
40
|
+
"default_hook",
|
41
|
+
"async_exit_stack",
|
42
|
+
"exit_stack",
|
43
|
+
)
|
37
44
|
|
38
45
|
def __init_subclass__(cls):
|
39
46
|
cls.DEPRECATION_MESSAGE = (
|
@@ -73,10 +80,20 @@ class ExtensionContextManagerBase:
|
|
73
80
|
|
74
81
|
if hook_fn:
|
75
82
|
if inspect.isgeneratorfunction(hook_fn):
|
76
|
-
|
83
|
+
context_manager = contextlib.contextmanager(
|
84
|
+
types.MethodType(hook_fn, extension)
|
85
|
+
)
|
86
|
+
return WrappedHook(
|
87
|
+
extension=extension, hook=context_manager, is_async=False
|
88
|
+
)
|
77
89
|
|
78
90
|
if inspect.isasyncgenfunction(hook_fn):
|
79
|
-
|
91
|
+
context_manager_async = contextlib.asynccontextmanager(
|
92
|
+
types.MethodType(hook_fn, extension)
|
93
|
+
)
|
94
|
+
return WrappedHook(
|
95
|
+
extension=extension, hook=context_manager_async, is_async=True
|
96
|
+
)
|
80
97
|
|
81
98
|
if callable(hook_fn):
|
82
99
|
return self.from_callable(extension, hook_fn)
|
@@ -96,27 +113,31 @@ class ExtensionContextManagerBase:
|
|
96
113
|
) -> WrappedHook:
|
97
114
|
if iscoroutinefunction(on_start) or iscoroutinefunction(on_end):
|
98
115
|
|
116
|
+
@contextlib.asynccontextmanager
|
99
117
|
async def iterator():
|
100
118
|
if on_start:
|
101
119
|
await await_maybe(on_start())
|
120
|
+
|
102
121
|
yield
|
122
|
+
|
103
123
|
if on_end:
|
104
124
|
await await_maybe(on_end())
|
105
125
|
|
106
|
-
|
107
|
-
return WrappedHook(extension, hook, True)
|
126
|
+
return WrappedHook(extension=extension, hook=iterator, is_async=True)
|
108
127
|
|
109
128
|
else:
|
110
129
|
|
111
|
-
|
130
|
+
@contextlib.contextmanager
|
131
|
+
def iterator_async():
|
112
132
|
if on_start:
|
113
133
|
on_start()
|
134
|
+
|
114
135
|
yield
|
136
|
+
|
115
137
|
if on_end:
|
116
138
|
on_end()
|
117
139
|
|
118
|
-
hook =
|
119
|
-
return WrappedHook(extension, hook, False)
|
140
|
+
return WrappedHook(extension=extension, hook=iterator_async, is_async=False)
|
120
141
|
|
121
142
|
@staticmethod
|
122
143
|
def from_callable(
|
@@ -125,59 +146,34 @@ class ExtensionContextManagerBase:
|
|
125
146
|
) -> WrappedHook:
|
126
147
|
if iscoroutinefunction(func):
|
127
148
|
|
128
|
-
|
149
|
+
@contextlib.asynccontextmanager
|
150
|
+
async def iterator():
|
129
151
|
await func(extension)
|
130
152
|
yield
|
131
153
|
|
132
|
-
hook =
|
133
|
-
return WrappedHook(extension, hook, True)
|
154
|
+
return WrappedHook(extension=extension, hook=iterator, is_async=True)
|
134
155
|
else:
|
135
156
|
|
157
|
+
@contextlib.contextmanager
|
136
158
|
def iterator():
|
137
159
|
func(extension)
|
138
160
|
yield
|
139
161
|
|
140
|
-
|
141
|
-
return WrappedHook(extension, hook, False)
|
162
|
+
return WrappedHook(extension=extension, hook=iterator, is_async=False)
|
142
163
|
|
143
|
-
def
|
144
|
-
|
145
|
-
ctx = (
|
146
|
-
contextlib.suppress(StopIteration, StopAsyncIteration)
|
147
|
-
if is_exit
|
148
|
-
else contextlib.nullcontext()
|
149
|
-
)
|
150
|
-
for hook in self.hooks:
|
151
|
-
with ctx:
|
152
|
-
if hook.is_async:
|
153
|
-
raise RuntimeError(
|
154
|
-
f"SchemaExtension hook {hook.extension}.{self.HOOK_NAME} "
|
155
|
-
"failed to complete synchronously."
|
156
|
-
)
|
157
|
-
else:
|
158
|
-
hook.initialized_hook.__next__() # type: ignore[union-attr]
|
159
|
-
|
160
|
-
async def run_hooks_async(self, is_exit: bool = False) -> None:
|
161
|
-
"""Run extensions asynchronously with support for sync lifecycle hooks.
|
162
|
-
|
163
|
-
The ``is_exit`` flag is required as a `StopIteration` cannot be raised from
|
164
|
-
within a coroutine.
|
165
|
-
"""
|
166
|
-
ctx = (
|
167
|
-
contextlib.suppress(StopIteration, StopAsyncIteration)
|
168
|
-
if is_exit
|
169
|
-
else contextlib.nullcontext()
|
170
|
-
)
|
164
|
+
def __enter__(self) -> None:
|
165
|
+
self.exit_stack = contextlib.ExitStack()
|
171
166
|
|
172
|
-
|
173
|
-
with ctx:
|
174
|
-
if hook.is_async:
|
175
|
-
await hook.initialized_hook.__anext__() # type: ignore[union-attr]
|
176
|
-
else:
|
177
|
-
hook.initialized_hook.__next__() # type: ignore[union-attr]
|
167
|
+
self.exit_stack.__enter__()
|
178
168
|
|
179
|
-
|
180
|
-
|
169
|
+
for hook in self.hooks:
|
170
|
+
if hook.is_async:
|
171
|
+
raise RuntimeError(
|
172
|
+
f"SchemaExtension hook {hook.extension}.{self.HOOK_NAME} "
|
173
|
+
"failed to complete synchronously."
|
174
|
+
)
|
175
|
+
else:
|
176
|
+
self.exit_stack.enter_context(hook.hook()) # type: ignore
|
181
177
|
|
182
178
|
def __exit__(
|
183
179
|
self,
|
@@ -185,10 +181,18 @@ class ExtensionContextManagerBase:
|
|
185
181
|
exc_val: Optional[BaseException],
|
186
182
|
exc_tb: Optional[TracebackType],
|
187
183
|
):
|
188
|
-
self.
|
184
|
+
self.exit_stack.__exit__(exc_type, exc_val, exc_tb)
|
189
185
|
|
190
|
-
async def __aenter__(self):
|
191
|
-
|
186
|
+
async def __aenter__(self) -> None:
|
187
|
+
self.async_exit_stack = contextlib.AsyncExitStack()
|
188
|
+
|
189
|
+
await self.async_exit_stack.__aenter__()
|
190
|
+
|
191
|
+
for hook in self.hooks:
|
192
|
+
if hook.is_async:
|
193
|
+
await self.async_exit_stack.enter_async_context(hook.hook()) # type: ignore
|
194
|
+
else:
|
195
|
+
self.async_exit_stack.enter_context(hook.hook()) # type: ignore
|
192
196
|
|
193
197
|
async def __aexit__(
|
194
198
|
self,
|
@@ -196,7 +200,7 @@ class ExtensionContextManagerBase:
|
|
196
200
|
exc_val: Optional[BaseException],
|
197
201
|
exc_tb: Optional[TracebackType],
|
198
202
|
):
|
199
|
-
await self.
|
203
|
+
await self.async_exit_stack.__aexit__(exc_type, exc_val, exc_tb)
|
200
204
|
|
201
205
|
|
202
206
|
class OperationContextManager(ExtensionContextManagerBase):
|
@@ -100,7 +100,7 @@ strawberry/ext/mypy_plugin.py,sha256=0ojGmGM9zorviaQVEC6DCzVQx_4o9uUNKm_rn9qcPxk
|
|
100
100
|
strawberry/extensions/__init__.py,sha256=IfICBQvMNNrulV-mD4Y3HKLE9yDyHi_UFWxWbck_Urg,1199
|
101
101
|
strawberry/extensions/add_validation_rules.py,sha256=U-_U3aTNGqWd88zbzqedrLGjP1R-Pv1KyF8x_hIOoEw,1358
|
102
102
|
strawberry/extensions/base_extension.py,sha256=IRsssFnsipe2FJyZ3gK6fZPhB4TjUCpGVra7iWU77-8,1992
|
103
|
-
strawberry/extensions/context.py,sha256=
|
103
|
+
strawberry/extensions/context.py,sha256=3jH8Uw355xd1QQBw9NKt_426stzRFHCxhmqIYCNUo8I,7069
|
104
104
|
strawberry/extensions/directives.py,sha256=ulS80mDTDE-pM8d9IEk16O84kzjkXM1P4vMcqYp5Q1U,2968
|
105
105
|
strawberry/extensions/disable_validation.py,sha256=eLlZ0SEuvK3HUSvLm4PpdgrtP30ckG25sV3hGd2W-sM,720
|
106
106
|
strawberry/extensions/field_extension.py,sha256=1UXGdrPEz9y1m6OcsZTKTnPD1vMvWph3YOsk6QYtG5k,5643
|
@@ -241,8 +241,8 @@ strawberry/utils/logging.py,sha256=flS7hV0JiIOEdXcrIjda4WyIWix86cpHHFNJL8gl1y4,7
|
|
241
241
|
strawberry/utils/operation.py,sha256=Um-tBCPl3_bVFN2Ph7o1mnrxfxBes4HFCj6T0x4kZxE,1135
|
242
242
|
strawberry/utils/str_converters.py,sha256=avIgPVLg98vZH9mA2lhzVdyyjqzLsK2NdBw9mJQ02Xk,813
|
243
243
|
strawberry/utils/typing.py,sha256=Qxz1LwyVsNGV7LQW1dFsaUbsswj5LHBOdKLMom5eyEA,13491
|
244
|
-
strawberry_graphql-0.224.
|
245
|
-
strawberry_graphql-0.224.
|
246
|
-
strawberry_graphql-0.224.
|
247
|
-
strawberry_graphql-0.224.
|
248
|
-
strawberry_graphql-0.224.
|
244
|
+
strawberry_graphql-0.224.2.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
|
245
|
+
strawberry_graphql-0.224.2.dist-info/METADATA,sha256=HK0p-p7CbffXGWVDcoe8Ka2NV7bTvd8LaVoYNB3Y0VY,7740
|
246
|
+
strawberry_graphql-0.224.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
247
|
+
strawberry_graphql-0.224.2.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
|
248
|
+
strawberry_graphql-0.224.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{strawberry_graphql-0.224.1.dist-info → strawberry_graphql-0.224.2.dist-info}/entry_points.txt
RENAMED
File without changes
|