strawberry-graphql 0.254.1__py3-none-any.whl → 0.256.0__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/__init__.py +9 -9
- strawberry/aiohttp/test/client.py +10 -8
- strawberry/aiohttp/views.py +5 -7
- strawberry/annotation.py +13 -16
- strawberry/asgi/__init__.py +3 -6
- strawberry/asgi/test/client.py +9 -8
- strawberry/chalice/views.py +4 -2
- strawberry/channels/__init__.py +1 -1
- strawberry/channels/handlers/base.py +3 -7
- strawberry/channels/handlers/http_handler.py +5 -6
- strawberry/channels/handlers/ws_handler.py +3 -4
- strawberry/channels/testing.py +5 -9
- strawberry/cli/commands/codegen.py +9 -9
- strawberry/cli/commands/upgrade/__init__.py +2 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +7 -5
- strawberry/codegen/exceptions.py +2 -2
- strawberry/codegen/plugins/print_operation.py +6 -6
- strawberry/codegen/plugins/python.py +6 -6
- strawberry/codegen/plugins/typescript.py +3 -3
- strawberry/codegen/query_codegen.py +29 -34
- strawberry/codegen/types.py +35 -34
- strawberry/codemods/annotated_unions.py +5 -2
- strawberry/dataloader.py +13 -20
- strawberry/directive.py +12 -5
- strawberry/django/test/client.py +4 -4
- strawberry/django/views.py +4 -5
- strawberry/exceptions/__init__.py +24 -24
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +3 -3
- strawberry/exceptions/handler.py +7 -7
- strawberry/exceptions/invalid_union_type.py +2 -2
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/syntax.py +4 -4
- strawberry/exceptions/utils/source_finder.py +7 -6
- strawberry/experimental/pydantic/__init__.py +3 -3
- strawberry/experimental/pydantic/_compat.py +14 -14
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +3 -3
- strawberry/experimental/pydantic/error_type.py +18 -16
- strawberry/experimental/pydantic/exceptions.py +5 -5
- strawberry/experimental/pydantic/fields.py +2 -13
- strawberry/experimental/pydantic/object_type.py +20 -22
- strawberry/experimental/pydantic/utils.py +6 -10
- strawberry/ext/dataclasses/dataclasses.py +3 -3
- strawberry/ext/mypy_plugin.py +6 -9
- strawberry/extensions/__init__.py +7 -8
- strawberry/extensions/add_validation_rules.py +5 -3
- strawberry/extensions/base_extension.py +4 -4
- strawberry/extensions/context.py +15 -14
- strawberry/extensions/directives.py +2 -2
- strawberry/extensions/disable_validation.py +1 -1
- strawberry/extensions/field_extension.py +2 -1
- strawberry/extensions/mask_errors.py +3 -2
- strawberry/extensions/max_aliases.py +2 -2
- strawberry/extensions/max_tokens.py +1 -1
- strawberry/extensions/parser_cache.py +2 -1
- strawberry/extensions/pyinstrument.py +4 -1
- strawberry/extensions/query_depth_limiter.py +13 -13
- strawberry/extensions/runner.py +7 -7
- strawberry/extensions/tracing/apollo.py +11 -9
- strawberry/extensions/tracing/datadog.py +3 -1
- strawberry/extensions/tracing/opentelemetry.py +7 -10
- strawberry/extensions/utils.py +3 -3
- strawberry/extensions/validation_cache.py +2 -1
- strawberry/fastapi/context.py +3 -3
- strawberry/fastapi/router.py +9 -14
- strawberry/federation/__init__.py +4 -4
- strawberry/federation/argument.py +2 -1
- strawberry/federation/enum.py +8 -8
- strawberry/federation/field.py +25 -28
- strawberry/federation/object_type.py +24 -26
- strawberry/federation/scalar.py +7 -8
- strawberry/federation/schema.py +30 -36
- strawberry/federation/schema_directive.py +5 -5
- strawberry/federation/schema_directives.py +14 -14
- strawberry/federation/union.py +3 -2
- strawberry/field_extensions/input_mutation.py +1 -2
- strawberry/file_uploads/utils.py +4 -3
- strawberry/flask/views.py +3 -2
- strawberry/http/__init__.py +6 -6
- strawberry/http/async_base_view.py +9 -14
- strawberry/http/base.py +5 -4
- strawberry/http/ides.py +1 -1
- strawberry/http/parse_content_type.py +1 -2
- strawberry/http/sync_base_view.py +3 -5
- strawberry/http/temporal_response.py +1 -2
- strawberry/http/types.py +3 -2
- strawberry/litestar/controller.py +8 -14
- strawberry/parent.py +1 -2
- strawberry/permission.py +6 -8
- strawberry/printer/ast_from_value.py +2 -1
- strawberry/printer/printer.py +50 -30
- strawberry/quart/views.py +3 -3
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +43 -63
- strawberry/relay/types.py +29 -27
- strawberry/relay/utils.py +4 -4
- strawberry/sanic/utils.py +4 -4
- strawberry/sanic/views.py +5 -7
- strawberry/scalars.py +2 -2
- strawberry/schema/base.py +16 -11
- strawberry/schema/compat.py +4 -4
- strawberry/schema/execute.py +6 -10
- strawberry/schema/name_converter.py +3 -3
- strawberry/schema/schema.py +37 -25
- strawberry/schema/schema_converter.py +22 -24
- strawberry/schema/subscribe.py +5 -4
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +2 -2
- strawberry/schema/types/scalar.py +3 -4
- strawberry/schema_codegen/__init__.py +4 -4
- strawberry/schema_directive.py +8 -8
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +8 -9
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +16 -16
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +6 -5
- strawberry/subscriptions/protocols/graphql_ws/types.py +13 -13
- strawberry/test/__init__.py +1 -1
- strawberry/test/client.py +21 -19
- strawberry/tools/create_type.py +4 -3
- strawberry/tools/merge_types.py +1 -2
- strawberry/types/__init__.py +1 -1
- strawberry/types/arguments.py +10 -12
- strawberry/types/auto.py +2 -2
- strawberry/types/base.py +17 -21
- strawberry/types/enum.py +3 -5
- strawberry/types/execution.py +8 -12
- strawberry/types/field.py +26 -31
- strawberry/types/fields/resolver.py +15 -17
- strawberry/types/graphql.py +2 -2
- strawberry/types/info.py +5 -9
- strawberry/types/lazy_type.py +3 -5
- strawberry/types/mutation.py +25 -28
- strawberry/types/nodes.py +11 -9
- strawberry/types/object_type.py +14 -16
- strawberry/types/private.py +1 -2
- strawberry/types/scalar.py +2 -2
- strawberry/types/type_resolver.py +5 -5
- strawberry/types/union.py +8 -11
- strawberry/types/unset.py +3 -3
- strawberry/utils/aio.py +3 -8
- strawberry/utils/await_maybe.py +3 -2
- strawberry/utils/debug.py +2 -2
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/inspect.py +3 -5
- strawberry/utils/str_converters.py +1 -1
- strawberry/utils/typing.py +38 -67
- {strawberry_graphql-0.254.1.dist-info → strawberry_graphql-0.256.0.dist-info}/METADATA +3 -6
- strawberry_graphql-0.256.0.dist-info/RECORD +236 -0
- strawberry_graphql-0.254.1.dist-info/RECORD +0 -236
- {strawberry_graphql-0.254.1.dist-info → strawberry_graphql-0.256.0.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.254.1.dist-info → strawberry_graphql-0.256.0.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.254.1.dist-info → strawberry_graphql-0.256.0.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Any
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
|
5
5
|
if TYPE_CHECKING:
|
6
6
|
from pydantic import BaseModel
|
@@ -8,7 +8,7 @@ if TYPE_CHECKING:
|
|
8
8
|
|
9
9
|
|
10
10
|
class MissingFieldsListError(Exception):
|
11
|
-
def __init__(self, type:
|
11
|
+
def __init__(self, type: type[BaseModel]) -> None:
|
12
12
|
message = (
|
13
13
|
f"List of fields to copy from {type} is empty. Add fields with the "
|
14
14
|
f"`auto` type annotation"
|
@@ -22,7 +22,7 @@ class UnsupportedTypeError(Exception):
|
|
22
22
|
|
23
23
|
|
24
24
|
class UnregisteredTypeException(Exception):
|
25
|
-
def __init__(self, type:
|
25
|
+
def __init__(self, type: type[BaseModel]) -> None:
|
26
26
|
message = (
|
27
27
|
f"Cannot find a Strawberry Type for {type} did you forget to register it?"
|
28
28
|
)
|
@@ -43,9 +43,9 @@ class BothDefaultAndDefaultFactoryDefinedError(Exception):
|
|
43
43
|
class AutoFieldsNotInBaseModelError(Exception):
|
44
44
|
def __init__(
|
45
45
|
self,
|
46
|
-
fields:
|
46
|
+
fields: list[str],
|
47
47
|
cls_name: str,
|
48
|
-
model:
|
48
|
+
model: type[BaseModel],
|
49
49
|
) -> None:
|
50
50
|
message = (
|
51
51
|
f"{cls_name} defines {fields} with strawberry.auto. "
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import builtins
|
2
|
-
from typing import Any, Union
|
3
|
-
from typing_extensions import Annotated
|
2
|
+
from typing import Annotated, Any, Union
|
4
3
|
|
5
4
|
from pydantic import BaseModel
|
6
5
|
|
@@ -25,17 +24,7 @@ except ImportError:
|
|
25
24
|
else:
|
26
25
|
raise
|
27
26
|
|
28
|
-
|
29
|
-
from typing import GenericAlias as TypingGenericAlias # type: ignore
|
30
|
-
except ImportError:
|
31
|
-
import sys
|
32
|
-
|
33
|
-
# python < 3.9 does not have GenericAlias (list[int], tuple[str, ...] and so on)
|
34
|
-
# we do this under a conditional to avoid a mypy :)
|
35
|
-
if sys.version_info < (3, 9):
|
36
|
-
TypingGenericAlias = ()
|
37
|
-
else:
|
38
|
-
raise
|
27
|
+
from typing import GenericAlias as TypingGenericAlias # type: ignore
|
39
28
|
|
40
29
|
|
41
30
|
def replace_pydantic_types(type_: Any, is_input: bool) -> Any:
|
@@ -7,12 +7,7 @@ from typing import (
|
|
7
7
|
TYPE_CHECKING,
|
8
8
|
Any,
|
9
9
|
Callable,
|
10
|
-
Dict,
|
11
|
-
List,
|
12
10
|
Optional,
|
13
|
-
Sequence,
|
14
|
-
Set,
|
15
|
-
Type,
|
16
11
|
cast,
|
17
12
|
)
|
18
13
|
|
@@ -39,6 +34,9 @@ from strawberry.types.object_type import _process_type, _wrap_dataclass
|
|
39
34
|
from strawberry.types.type_resolver import _get_fields
|
40
35
|
|
41
36
|
if TYPE_CHECKING:
|
37
|
+
import builtins
|
38
|
+
from collections.abc import Sequence
|
39
|
+
|
42
40
|
from graphql import GraphQLResolveInfo
|
43
41
|
|
44
42
|
|
@@ -59,8 +57,8 @@ def get_type_for_field(field: CompatModelField, is_input: bool, compat: Pydantic
|
|
59
57
|
def _build_dataclass_creation_fields(
|
60
58
|
field: CompatModelField,
|
61
59
|
is_input: bool,
|
62
|
-
existing_fields:
|
63
|
-
auto_fields_set:
|
60
|
+
existing_fields: dict[str, StrawberryField],
|
61
|
+
auto_fields_set: set[str],
|
64
62
|
use_pydantic_alias: bool,
|
65
63
|
compat: PydanticCompat,
|
66
64
|
) -> DataclassCreationFields:
|
@@ -118,9 +116,9 @@ if TYPE_CHECKING:
|
|
118
116
|
|
119
117
|
|
120
118
|
def type(
|
121
|
-
model:
|
119
|
+
model: builtins.type[PydanticModel],
|
122
120
|
*,
|
123
|
-
fields: Optional[
|
121
|
+
fields: Optional[list[str]] = None,
|
124
122
|
name: Optional[str] = None,
|
125
123
|
is_input: bool = False,
|
126
124
|
is_interface: bool = False,
|
@@ -128,8 +126,8 @@ def type(
|
|
128
126
|
directives: Optional[Sequence[object]] = (),
|
129
127
|
all_fields: bool = False,
|
130
128
|
use_pydantic_alias: bool = True,
|
131
|
-
) -> Callable[...,
|
132
|
-
def wrap(cls: Any) ->
|
129
|
+
) -> Callable[..., builtins.type[StrawberryTypeFromPydantic[PydanticModel]]]:
|
130
|
+
def wrap(cls: Any) -> builtins.type[StrawberryTypeFromPydantic[PydanticModel]]:
|
133
131
|
compat = PydanticCompat.from_model(model)
|
134
132
|
model_fields = compat.get_model_fields(model)
|
135
133
|
original_fields_set = set(fields) if fields else set()
|
@@ -177,12 +175,12 @@ def type(
|
|
177
175
|
|
178
176
|
wrapped = _wrap_dataclass(cls)
|
179
177
|
extra_strawberry_fields = _get_fields(wrapped, {})
|
180
|
-
extra_fields = cast(
|
178
|
+
extra_fields = cast(list[dataclasses.Field], extra_strawberry_fields)
|
181
179
|
private_fields = get_private_fields(wrapped)
|
182
180
|
|
183
181
|
extra_fields_dict = {field.name: field for field in extra_strawberry_fields}
|
184
182
|
|
185
|
-
all_model_fields:
|
183
|
+
all_model_fields: list[DataclassCreationFields] = [
|
186
184
|
_build_dataclass_creation_fields(
|
187
185
|
field,
|
188
186
|
is_input,
|
@@ -208,7 +206,7 @@ def type(
|
|
208
206
|
# Implicitly define `is_type_of` to support interfaces/unions that use
|
209
207
|
# pydantic objects (not the corresponding strawberry type)
|
210
208
|
@classmethod # type: ignore
|
211
|
-
def is_type_of(cls:
|
209
|
+
def is_type_of(cls: builtins.type, obj: Any, _info: GraphQLResolveInfo) -> bool:
|
212
210
|
return isinstance(obj, (cls, model))
|
213
211
|
|
214
212
|
namespace = {"is_type_of": is_type_of}
|
@@ -232,7 +230,7 @@ def type(
|
|
232
230
|
if hasattr(cls, "resolve_reference"):
|
233
231
|
namespace["resolve_reference"] = cls.resolve_reference
|
234
232
|
|
235
|
-
kwargs:
|
233
|
+
kwargs: dict[str, object] = {}
|
236
234
|
|
237
235
|
# Python 3.10.1 introduces the kw_only param to `make_dataclass`.
|
238
236
|
# If we're on an older version then generate our own custom init function
|
@@ -273,7 +271,7 @@ def type(
|
|
273
271
|
cls._pydantic_type = model
|
274
272
|
|
275
273
|
def from_pydantic_default(
|
276
|
-
instance: PydanticModel, extra: Optional[
|
274
|
+
instance: PydanticModel, extra: Optional[dict[str, Any]] = None
|
277
275
|
) -> StrawberryTypeFromPydantic[PydanticModel]:
|
278
276
|
ret = convert_pydantic_model_to_strawberry_class(
|
279
277
|
cls=cls, model_instance=instance, extra=extra
|
@@ -302,16 +300,16 @@ def type(
|
|
302
300
|
|
303
301
|
|
304
302
|
def input(
|
305
|
-
model:
|
303
|
+
model: builtins.type[PydanticModel],
|
306
304
|
*,
|
307
|
-
fields: Optional[
|
305
|
+
fields: Optional[list[str]] = None,
|
308
306
|
name: Optional[str] = None,
|
309
307
|
is_interface: bool = False,
|
310
308
|
description: Optional[str] = None,
|
311
309
|
directives: Optional[Sequence[object]] = (),
|
312
310
|
all_fields: bool = False,
|
313
311
|
use_pydantic_alias: bool = True,
|
314
|
-
) -> Callable[...,
|
312
|
+
) -> Callable[..., builtins.type[StrawberryTypeFromPydantic[PydanticModel]]]:
|
315
313
|
"""Convenience decorator for creating an input type from a Pydantic model.
|
316
314
|
|
317
315
|
Equal to `partial(type, is_input=True)`
|
@@ -332,16 +330,16 @@ def input(
|
|
332
330
|
|
333
331
|
|
334
332
|
def interface(
|
335
|
-
model:
|
333
|
+
model: builtins.type[PydanticModel],
|
336
334
|
*,
|
337
|
-
fields: Optional[
|
335
|
+
fields: Optional[list[str]] = None,
|
338
336
|
name: Optional[str] = None,
|
339
337
|
is_input: bool = False,
|
340
338
|
description: Optional[str] = None,
|
341
339
|
directives: Optional[Sequence[object]] = (),
|
342
340
|
all_fields: bool = False,
|
343
341
|
use_pydantic_alias: bool = True,
|
344
|
-
) -> Callable[...,
|
342
|
+
) -> Callable[..., builtins.type[StrawberryTypeFromPydantic[PydanticModel]]]:
|
345
343
|
"""Convenience decorator for creating an interface type from a Pydantic model.
|
346
344
|
|
347
345
|
Equal to `partial(type, is_interface=True)`
|
@@ -4,11 +4,7 @@ import dataclasses
|
|
4
4
|
from typing import (
|
5
5
|
TYPE_CHECKING,
|
6
6
|
Any,
|
7
|
-
List,
|
8
7
|
NamedTuple,
|
9
|
-
Set,
|
10
|
-
Tuple,
|
11
|
-
Type,
|
12
8
|
Union,
|
13
9
|
cast,
|
14
10
|
)
|
@@ -38,9 +34,9 @@ if TYPE_CHECKING:
|
|
38
34
|
from pydantic.typing import NoArgAnyCallable
|
39
35
|
|
40
36
|
|
41
|
-
def normalize_type(type_:
|
37
|
+
def normalize_type(type_: type) -> Any:
|
42
38
|
if is_list(type_):
|
43
|
-
return
|
39
|
+
return list[normalize_type(get_list_annotation(type_))] # type: ignore
|
44
40
|
|
45
41
|
if is_optional(type_):
|
46
42
|
return get_optional_annotation(type_)
|
@@ -55,7 +51,7 @@ def get_strawberry_type_from_model(type_: Any) -> Any:
|
|
55
51
|
raise UnregisteredTypeException(type_)
|
56
52
|
|
57
53
|
|
58
|
-
def get_private_fields(cls:
|
54
|
+
def get_private_fields(cls: type) -> list[dataclasses.Field]:
|
59
55
|
return [field for field in dataclasses.fields(cls) if is_private(field.type)]
|
60
56
|
|
61
57
|
|
@@ -63,10 +59,10 @@ class DataclassCreationFields(NamedTuple):
|
|
63
59
|
"""Fields required for the fields parameter of make_dataclass."""
|
64
60
|
|
65
61
|
name: str
|
66
|
-
field_type:
|
62
|
+
field_type: type
|
67
63
|
field: dataclasses.Field
|
68
64
|
|
69
|
-
def to_tuple(self) ->
|
65
|
+
def to_tuple(self) -> tuple[str, type, dataclasses.Field]:
|
70
66
|
# fields parameter wants (name, type, Field)
|
71
67
|
return self.name, self.field_type, self.field
|
72
68
|
|
@@ -125,7 +121,7 @@ def get_default_factory_for_field(
|
|
125
121
|
|
126
122
|
|
127
123
|
def ensure_all_auto_fields_in_pydantic(
|
128
|
-
model:
|
124
|
+
model: type[BaseModel], auto_fields: set[str], cls_name: str
|
129
125
|
) -> None:
|
130
126
|
compat = PydanticCompat.from_model(model)
|
131
127
|
# Raise error if user defined a strawberry.auto field not present in the model
|
@@ -11,15 +11,15 @@ from dataclasses import ( # type: ignore
|
|
11
11
|
_field_init,
|
12
12
|
_init_param,
|
13
13
|
)
|
14
|
-
from typing import Any
|
14
|
+
from typing import Any
|
15
15
|
|
16
16
|
|
17
17
|
def dataclass_init_fn(
|
18
|
-
fields:
|
18
|
+
fields: list[Any],
|
19
19
|
frozen: bool,
|
20
20
|
has_post_init: bool,
|
21
21
|
self_name: str,
|
22
|
-
globals_:
|
22
|
+
globals_: dict[str, Any],
|
23
23
|
) -> Any:
|
24
24
|
"""Create an __init__ function for a dataclass.
|
25
25
|
|
strawberry/ext/mypy_plugin.py
CHANGED
@@ -8,10 +8,7 @@ from typing import (
|
|
8
8
|
TYPE_CHECKING,
|
9
9
|
Any,
|
10
10
|
Callable,
|
11
|
-
List,
|
12
11
|
Optional,
|
13
|
-
Set,
|
14
|
-
Tuple,
|
15
12
|
Union,
|
16
13
|
cast,
|
17
14
|
)
|
@@ -60,7 +57,7 @@ try:
|
|
60
57
|
except ImportError:
|
61
58
|
TypeVarDef = TypeVarType
|
62
59
|
|
63
|
-
PYDANTIC_VERSION: Optional[
|
60
|
+
PYDANTIC_VERSION: Optional[tuple[int, ...]] = None
|
64
61
|
|
65
62
|
# To be compatible with user who don't use pydantic
|
66
63
|
try:
|
@@ -326,7 +323,7 @@ def add_static_method_to_class(
|
|
326
323
|
api: Union[SemanticAnalyzerPluginInterface, CheckerPluginInterface],
|
327
324
|
cls: ClassDef,
|
328
325
|
name: str,
|
329
|
-
args:
|
326
|
+
args: list[Argument],
|
330
327
|
return_type: Type,
|
331
328
|
tvar_def: Optional[TypeVarType] = None,
|
332
329
|
) -> None:
|
@@ -410,7 +407,7 @@ def strawberry_pydantic_class_callback(ctx: ClassDefContext) -> None:
|
|
410
407
|
model_type = cast(Instance, _get_type_for_expr(model_expression, ctx.api))
|
411
408
|
|
412
409
|
# these are the fields that the user added to the strawberry type
|
413
|
-
new_strawberry_fields:
|
410
|
+
new_strawberry_fields: set[str] = set()
|
414
411
|
|
415
412
|
# TODO: think about inheritance for strawberry?
|
416
413
|
for stmt in ctx.cls.defs.body:
|
@@ -418,7 +415,7 @@ def strawberry_pydantic_class_callback(ctx: ClassDefContext) -> None:
|
|
418
415
|
lhs = cast(NameExpr, stmt.lvalues[0])
|
419
416
|
new_strawberry_fields.add(lhs.name)
|
420
417
|
|
421
|
-
pydantic_fields:
|
418
|
+
pydantic_fields: set[PydanticModelField] = set()
|
422
419
|
try:
|
423
420
|
fields = model_type.type.metadata[PYDANTIC_METADATA_KEY]["fields"]
|
424
421
|
for data in fields.items():
|
@@ -438,7 +435,7 @@ def strawberry_pydantic_class_callback(ctx: ClassDefContext) -> None:
|
|
438
435
|
ctx.reason,
|
439
436
|
)
|
440
437
|
|
441
|
-
potentially_missing_fields:
|
438
|
+
potentially_missing_fields: set[PydanticModelField] = {
|
442
439
|
f for f in pydantic_fields if f.name not in new_strawberry_fields
|
443
440
|
}
|
444
441
|
|
@@ -449,7 +446,7 @@ def strawberry_pydantic_class_callback(ctx: ClassDefContext) -> None:
|
|
449
446
|
This means that the user is using all_fields=True
|
450
447
|
"""
|
451
448
|
is_all_fields: bool = len(potentially_missing_fields) == len(pydantic_fields)
|
452
|
-
missing_pydantic_fields:
|
449
|
+
missing_pydantic_fields: set[PydanticModelField] = (
|
453
450
|
potentially_missing_fields if not is_all_fields else set()
|
454
451
|
)
|
455
452
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import warnings
|
2
|
-
from typing import Type
|
3
2
|
|
4
3
|
from .add_validation_rules import AddValidationRules
|
5
4
|
from .base_extension import LifecycleStep, SchemaExtension
|
@@ -13,7 +12,7 @@ from .query_depth_limiter import IgnoreContext, QueryDepthLimiter
|
|
13
12
|
from .validation_cache import ValidationCache
|
14
13
|
|
15
14
|
|
16
|
-
def __getattr__(name: str) ->
|
15
|
+
def __getattr__(name: str) -> type[SchemaExtension]:
|
17
16
|
if name == "Extension":
|
18
17
|
warnings.warn(
|
19
18
|
(
|
@@ -29,16 +28,16 @@ def __getattr__(name: str) -> Type[SchemaExtension]:
|
|
29
28
|
|
30
29
|
|
31
30
|
__all__ = [
|
32
|
-
"FieldExtension",
|
33
|
-
"SchemaExtension",
|
34
|
-
"LifecycleStep",
|
35
31
|
"AddValidationRules",
|
36
32
|
"DisableValidation",
|
37
|
-
"
|
38
|
-
"QueryDepthLimiter",
|
33
|
+
"FieldExtension",
|
39
34
|
"IgnoreContext",
|
40
|
-
"
|
35
|
+
"LifecycleStep",
|
41
36
|
"MaskErrors",
|
42
37
|
"MaxAliasesLimiter",
|
43
38
|
"MaxTokensLimiter",
|
39
|
+
"ParserCache",
|
40
|
+
"QueryDepthLimiter",
|
41
|
+
"SchemaExtension",
|
42
|
+
"ValidationCache",
|
44
43
|
]
|
@@ -1,10 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING
|
3
|
+
from typing import TYPE_CHECKING
|
4
4
|
|
5
5
|
from strawberry.extensions.base_extension import SchemaExtension
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
8
|
+
from collections.abc import Iterator
|
9
|
+
|
8
10
|
from graphql import ASTValidationRule
|
9
11
|
|
10
12
|
|
@@ -37,9 +39,9 @@ class AddValidationRules(SchemaExtension):
|
|
37
39
|
```
|
38
40
|
"""
|
39
41
|
|
40
|
-
validation_rules:
|
42
|
+
validation_rules: list[type[ASTValidationRule]]
|
41
43
|
|
42
|
-
def __init__(self, validation_rules:
|
44
|
+
def __init__(self, validation_rules: list[type[ASTValidationRule]]) -> None:
|
43
45
|
self.validation_rules = validation_rules
|
44
46
|
|
45
47
|
def on_operation(self) -> Iterator[None]:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from enum import Enum
|
4
|
-
from typing import TYPE_CHECKING, Any, Callable
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable
|
5
5
|
|
6
6
|
from strawberry.utils.await_maybe import AsyncIteratorOrIterator, AwaitableOrValue
|
7
7
|
|
@@ -60,7 +60,7 @@ class SchemaExtension:
|
|
60
60
|
) -> AwaitableOrValue[object]:
|
61
61
|
return _next(root, info, *args, **kwargs)
|
62
62
|
|
63
|
-
def get_results(self) -> AwaitableOrValue[
|
63
|
+
def get_results(self) -> AwaitableOrValue[dict[str, Any]]:
|
64
64
|
return {}
|
65
65
|
|
66
66
|
@classmethod
|
@@ -71,11 +71,11 @@ class SchemaExtension:
|
|
71
71
|
|
72
72
|
Hook = Callable[[SchemaExtension], AsyncIteratorOrIterator[None]]
|
73
73
|
|
74
|
-
HOOK_METHODS:
|
74
|
+
HOOK_METHODS: set[str] = {
|
75
75
|
SchemaExtension.on_operation.__name__,
|
76
76
|
SchemaExtension.on_validate.__name__,
|
77
77
|
SchemaExtension.on_parse.__name__,
|
78
78
|
SchemaExtension.on_execute.__name__,
|
79
79
|
}
|
80
80
|
|
81
|
-
__all__ = ["
|
81
|
+
__all__ = ["HOOK_METHODS", "Hook", "LifecycleStep", "SchemaExtension"]
|
strawberry/extensions/context.py
CHANGED
@@ -8,15 +8,9 @@ from asyncio import iscoroutinefunction
|
|
8
8
|
from typing import (
|
9
9
|
TYPE_CHECKING,
|
10
10
|
Any,
|
11
|
-
AsyncContextManager,
|
12
|
-
AsyncIterator,
|
13
11
|
Callable,
|
14
|
-
ContextManager,
|
15
|
-
Iterator,
|
16
|
-
List,
|
17
12
|
NamedTuple,
|
18
13
|
Optional,
|
19
|
-
Type,
|
20
14
|
Union,
|
21
15
|
)
|
22
16
|
|
@@ -24,6 +18,7 @@ from strawberry.extensions import SchemaExtension
|
|
24
18
|
from strawberry.utils.await_maybe import AwaitableOrValue, await_maybe
|
25
19
|
|
26
20
|
if TYPE_CHECKING:
|
21
|
+
from collections.abc import AsyncIterator, Iterator
|
27
22
|
from types import TracebackType
|
28
23
|
|
29
24
|
from strawberry.extensions.base_extension import Hook
|
@@ -31,17 +26,23 @@ if TYPE_CHECKING:
|
|
31
26
|
|
32
27
|
class WrappedHook(NamedTuple):
|
33
28
|
extension: SchemaExtension
|
34
|
-
hook: Callable[
|
29
|
+
hook: Callable[
|
30
|
+
...,
|
31
|
+
Union[
|
32
|
+
contextlib.AbstractAsyncContextManager[None],
|
33
|
+
contextlib.AbstractContextManager[None],
|
34
|
+
],
|
35
|
+
]
|
35
36
|
is_async: bool
|
36
37
|
|
37
38
|
|
38
39
|
class ExtensionContextManagerBase:
|
39
40
|
__slots__ = (
|
40
|
-
"hooks",
|
41
|
-
"deprecation_message",
|
42
|
-
"default_hook",
|
43
41
|
"async_exit_stack",
|
42
|
+
"default_hook",
|
43
|
+
"deprecation_message",
|
44
44
|
"exit_stack",
|
45
|
+
"hooks",
|
45
46
|
)
|
46
47
|
|
47
48
|
def __init_subclass__(cls) -> None:
|
@@ -56,8 +57,8 @@ class ExtensionContextManagerBase:
|
|
56
57
|
LEGACY_ENTER: str
|
57
58
|
LEGACY_EXIT: str
|
58
59
|
|
59
|
-
def __init__(self, extensions:
|
60
|
-
self.hooks:
|
60
|
+
def __init__(self, extensions: list[SchemaExtension]) -> None:
|
61
|
+
self.hooks: list[WrappedHook] = []
|
61
62
|
self.default_hook: Hook = getattr(SchemaExtension, self.HOOK_NAME)
|
62
63
|
for extension in extensions:
|
63
64
|
hook = self.get_hook(extension)
|
@@ -179,7 +180,7 @@ class ExtensionContextManagerBase:
|
|
179
180
|
|
180
181
|
def __exit__(
|
181
182
|
self,
|
182
|
-
exc_type: Optional[
|
183
|
+
exc_type: Optional[type[BaseException]],
|
183
184
|
exc_val: Optional[BaseException],
|
184
185
|
exc_tb: Optional[TracebackType],
|
185
186
|
) -> None:
|
@@ -198,7 +199,7 @@ class ExtensionContextManagerBase:
|
|
198
199
|
|
199
200
|
async def __aexit__(
|
200
201
|
self,
|
201
|
-
exc_type: Optional[
|
202
|
+
exc_type: Optional[type[BaseException]],
|
202
203
|
exc_val: Optional[BaseException],
|
203
204
|
exc_tb: Optional[TracebackType],
|
204
205
|
) -> None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Callable
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable
|
4
4
|
|
5
5
|
from strawberry.extensions import SchemaExtension
|
6
6
|
from strawberry.types.nodes import convert_arguments
|
@@ -62,7 +62,7 @@ def process_directive(
|
|
62
62
|
directive: DirectiveNode,
|
63
63
|
value: Any,
|
64
64
|
info: GraphQLResolveInfo,
|
65
|
-
) ->
|
65
|
+
) -> tuple[StrawberryDirective, dict[str, Any]]:
|
66
66
|
"""Get a `StrawberryDirective` from ``directive` and prepare its arguments."""
|
67
67
|
directive_name = directive.name.value
|
68
68
|
schema: Schema = info.schema._strawberry_schema # type: ignore
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import itertools
|
4
|
+
from collections.abc import Awaitable
|
4
5
|
from functools import cached_property
|
5
|
-
from typing import TYPE_CHECKING, Any,
|
6
|
+
from typing import TYPE_CHECKING, Any, Callable, Union
|
6
7
|
|
7
8
|
if TYPE_CHECKING:
|
8
9
|
from typing_extensions import TypeAlias
|
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Iterator
|
2
|
+
from typing import Callable
|
2
3
|
|
3
4
|
from graphql.error import GraphQLError
|
4
5
|
|
@@ -36,7 +37,7 @@ class MaskErrors(SchemaExtension):
|
|
36
37
|
yield
|
37
38
|
result = self.execution_context.result
|
38
39
|
if result and result.errors:
|
39
|
-
processed_errors:
|
40
|
+
processed_errors: list[GraphQLError] = []
|
40
41
|
for error in result.errors:
|
41
42
|
if self.should_mask_error(error):
|
42
43
|
processed_errors.append(self.anonymise_error(error))
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Union
|
2
2
|
|
3
3
|
from graphql import (
|
4
4
|
ExecutableDefinitionNode,
|
@@ -35,7 +35,7 @@ class MaxAliasesLimiter(AddValidationRules):
|
|
35
35
|
super().__init__([validator])
|
36
36
|
|
37
37
|
|
38
|
-
def create_validator(max_alias_count: int) ->
|
38
|
+
def create_validator(max_alias_count: int) -> type[ValidationRule]:
|
39
39
|
"""Create a validator that checks the number of aliases in a document.
|
40
40
|
|
41
41
|
Args:
|
@@ -1,12 +1,15 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import
|
4
|
+
from typing import TYPE_CHECKING
|
5
5
|
|
6
6
|
from pyinstrument import Profiler
|
7
7
|
|
8
8
|
from strawberry.extensions.base_extension import SchemaExtension
|
9
9
|
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from collections.abc import Iterator
|
12
|
+
|
10
13
|
|
11
14
|
class PyInstrument(SchemaExtension):
|
12
15
|
"""Extension to profile the execution time of resolvers using PyInstrument."""
|