strawberry-graphql 0.275.7__py3-none-any.whl → 0.284.3__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.
Potentially problematic release.
This version of strawberry-graphql might be problematic. Click here for more details.
- strawberry/__init__.py +2 -0
- strawberry/aiohttp/test/client.py +8 -15
- strawberry/aiohttp/views.py +15 -64
- strawberry/annotation.py +70 -25
- strawberry/asgi/__init__.py +22 -56
- strawberry/asgi/test/client.py +6 -6
- strawberry/chalice/views.py +13 -79
- strawberry/channels/handlers/base.py +7 -8
- strawberry/channels/handlers/http_handler.py +50 -32
- strawberry/channels/handlers/ws_handler.py +12 -14
- strawberry/channels/router.py +3 -4
- strawberry/channels/testing.py +7 -9
- strawberry/cli/__init__.py +7 -6
- strawberry/cli/commands/codegen.py +7 -7
- strawberry/cli/commands/dev.py +72 -0
- strawberry/cli/commands/schema_codegen.py +1 -2
- strawberry/cli/commands/server.py +3 -44
- strawberry/cli/commands/upgrade/__init__.py +3 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
- strawberry/cli/constants.py +1 -2
- strawberry/cli/{debug_server.py → dev_server.py} +3 -7
- strawberry/codegen/plugins/print_operation.py +2 -2
- strawberry/codegen/plugins/python.py +2 -2
- strawberry/codegen/query_codegen.py +20 -30
- strawberry/codegen/types.py +32 -32
- strawberry/codemods/__init__.py +9 -0
- strawberry/codemods/annotated_unions.py +2 -2
- strawberry/codemods/maybe_optional.py +118 -0
- strawberry/dataloader.py +28 -24
- strawberry/directive.py +6 -7
- strawberry/django/test/client.py +3 -3
- strawberry/django/views.py +21 -91
- strawberry/exceptions/__init__.py +4 -4
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +4 -4
- strawberry/exceptions/exception.py +3 -3
- strawberry/exceptions/handler.py +8 -7
- strawberry/exceptions/invalid_argument_type.py +2 -2
- strawberry/exceptions/invalid_superclass_interface.py +2 -2
- strawberry/exceptions/invalid_union_type.py +4 -4
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_dependencies.py +2 -4
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/missing_return_annotation.py +2 -2
- strawberry/exceptions/object_is_not_a_class.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/scalar_already_registered.py +2 -2
- strawberry/exceptions/syntax.py +3 -3
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +25 -25
- strawberry/experimental/pydantic/_compat.py +8 -7
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +2 -2
- strawberry/experimental/pydantic/error_type.py +10 -12
- strawberry/experimental/pydantic/fields.py +9 -15
- strawberry/experimental/pydantic/object_type.py +17 -25
- strawberry/experimental/pydantic/utils.py +1 -2
- strawberry/ext/mypy_plugin.py +12 -14
- strawberry/extensions/base_extension.py +2 -1
- strawberry/extensions/context.py +13 -18
- strawberry/extensions/directives.py +9 -3
- strawberry/extensions/field_extension.py +4 -4
- strawberry/extensions/mask_errors.py +24 -13
- strawberry/extensions/max_aliases.py +1 -3
- strawberry/extensions/parser_cache.py +1 -2
- strawberry/extensions/query_depth_limiter.py +18 -14
- strawberry/extensions/runner.py +2 -2
- strawberry/extensions/tracing/apollo.py +3 -3
- strawberry/extensions/tracing/datadog.py +3 -3
- strawberry/extensions/tracing/opentelemetry.py +6 -8
- strawberry/extensions/tracing/utils.py +3 -1
- strawberry/extensions/utils.py +2 -2
- strawberry/extensions/validation_cache.py +2 -3
- strawberry/fastapi/context.py +6 -6
- strawberry/fastapi/router.py +43 -42
- strawberry/federation/argument.py +4 -5
- strawberry/federation/enum.py +18 -21
- strawberry/federation/field.py +94 -97
- strawberry/federation/object_type.py +56 -58
- strawberry/federation/scalar.py +27 -35
- strawberry/federation/schema.py +15 -16
- strawberry/federation/schema_directive.py +7 -6
- strawberry/federation/schema_directives.py +11 -11
- strawberry/federation/union.py +4 -4
- strawberry/flask/views.py +16 -85
- strawberry/http/__init__.py +30 -20
- strawberry/http/async_base_view.py +208 -89
- strawberry/http/base.py +28 -11
- strawberry/http/exceptions.py +5 -7
- strawberry/http/ides.py +2 -3
- strawberry/http/sync_base_view.py +115 -69
- strawberry/http/types.py +3 -3
- strawberry/litestar/controller.py +43 -77
- strawberry/permission.py +4 -6
- strawberry/printer/ast_from_value.py +3 -5
- strawberry/printer/printer.py +18 -15
- strawberry/quart/views.py +16 -48
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +33 -32
- strawberry/relay/types.py +32 -35
- strawberry/relay/utils.py +11 -23
- strawberry/resolvers.py +2 -1
- strawberry/sanic/context.py +1 -0
- strawberry/sanic/utils.py +3 -3
- strawberry/sanic/views.py +15 -54
- strawberry/scalars.py +2 -2
- strawberry/schema/_graphql_core.py +55 -0
- strawberry/schema/base.py +32 -33
- strawberry/schema/compat.py +9 -9
- strawberry/schema/config.py +10 -1
- strawberry/schema/exceptions.py +1 -3
- strawberry/schema/name_converter.py +9 -8
- strawberry/schema/schema.py +133 -100
- strawberry/schema/schema_converter.py +96 -58
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +5 -5
- strawberry/schema/validation_rules/maybe_null.py +136 -0
- strawberry/schema_codegen/__init__.py +3 -3
- strawberry/schema_directive.py +7 -6
- strawberry/static/graphiql.html +5 -5
- strawberry/streamable.py +35 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -16
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -12
- strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
- strawberry/test/client.py +18 -18
- strawberry/tools/create_type.py +2 -3
- strawberry/types/arguments.py +41 -28
- strawberry/types/auto.py +3 -4
- strawberry/types/base.py +25 -27
- strawberry/types/enum.py +22 -25
- strawberry/types/execution.py +21 -16
- strawberry/types/field.py +109 -130
- strawberry/types/fields/resolver.py +19 -21
- strawberry/types/info.py +5 -11
- strawberry/types/lazy_type.py +2 -3
- strawberry/types/maybe.py +12 -3
- strawberry/types/mutation.py +115 -118
- strawberry/types/nodes.py +2 -2
- strawberry/types/object_type.py +43 -63
- strawberry/types/scalar.py +37 -43
- strawberry/types/union.py +12 -14
- strawberry/utils/aio.py +12 -9
- strawberry/utils/await_maybe.py +3 -3
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/importer.py +1 -2
- strawberry/utils/inspect.py +4 -6
- strawberry/utils/logging.py +2 -2
- strawberry/utils/operation.py +4 -4
- strawberry/utils/typing.py +18 -83
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +14 -8
- strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +1 -1
- strawberry/utils/dataclasses.py +0 -37
- strawberry/utils/debug.py +0 -46
- strawberry/utils/graphql_lexer.py +0 -35
- strawberry_graphql-0.275.7.dist-info/RECORD +0 -241
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info/licenses}/LICENSE +0 -0
strawberry/types/object_type.py
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import builtins
|
|
2
2
|
import dataclasses
|
|
3
3
|
import inspect
|
|
4
|
-
import sys
|
|
5
4
|
import types
|
|
6
|
-
from collections.abc import Sequence
|
|
5
|
+
from collections.abc import Callable, Sequence
|
|
7
6
|
from typing import (
|
|
8
7
|
Any,
|
|
9
|
-
Callable,
|
|
10
|
-
Optional,
|
|
11
8
|
TypeVar,
|
|
12
|
-
Union,
|
|
13
9
|
overload,
|
|
14
10
|
)
|
|
15
|
-
from typing_extensions import dataclass_transform
|
|
11
|
+
from typing_extensions import dataclass_transform, get_annotations
|
|
16
12
|
|
|
17
13
|
from strawberry.exceptions import (
|
|
18
14
|
InvalidSuperclassInterfaceError,
|
|
@@ -51,7 +47,8 @@ def _check_field_annotations(cls: builtins.type[Any]) -> None:
|
|
|
51
47
|
|
|
52
48
|
https://github.com/python/cpython/blob/6fed3c85402c5ca704eb3f3189ca3f5c67a08d19/Lib/dataclasses.py#L881-L884
|
|
53
49
|
"""
|
|
54
|
-
cls_annotations = cls
|
|
50
|
+
cls_annotations = get_annotations(cls)
|
|
51
|
+
# TODO: do we need this?
|
|
55
52
|
cls.__annotations__ = cls_annotations
|
|
56
53
|
|
|
57
54
|
for field_name, field_ in cls.__dict__.items():
|
|
@@ -104,24 +101,7 @@ def _wrap_dataclass(cls: builtins.type[T]) -> builtins.type[T]:
|
|
|
104
101
|
"""Wrap a strawberry.type class with a dataclass and check for any issues before doing so."""
|
|
105
102
|
# Ensure all Fields have been properly type-annotated
|
|
106
103
|
_check_field_annotations(cls)
|
|
107
|
-
|
|
108
|
-
dclass_kwargs: dict[str, bool] = {}
|
|
109
|
-
|
|
110
|
-
# Python 3.10 introduces the kw_only param. If we're on an older version
|
|
111
|
-
# then generate our own custom init function
|
|
112
|
-
if sys.version_info >= (3, 10):
|
|
113
|
-
dclass_kwargs["kw_only"] = True
|
|
114
|
-
else:
|
|
115
|
-
dclass_kwargs["init"] = False
|
|
116
|
-
|
|
117
|
-
dclass = dataclasses.dataclass(cls, **dclass_kwargs)
|
|
118
|
-
|
|
119
|
-
if sys.version_info < (3, 10):
|
|
120
|
-
from strawberry.utils.dataclasses import add_custom_init_fn
|
|
121
|
-
|
|
122
|
-
add_custom_init_fn(dclass)
|
|
123
|
-
|
|
124
|
-
return dclass
|
|
104
|
+
return dataclasses.dataclass(kw_only=True)(cls)
|
|
125
105
|
|
|
126
106
|
|
|
127
107
|
def _inject_default_for_maybe_annotations(
|
|
@@ -136,13 +116,13 @@ def _inject_default_for_maybe_annotations(
|
|
|
136
116
|
def _process_type(
|
|
137
117
|
cls: T,
|
|
138
118
|
*,
|
|
139
|
-
name:
|
|
119
|
+
name: str | None = None,
|
|
140
120
|
is_input: bool = False,
|
|
141
121
|
is_interface: bool = False,
|
|
142
|
-
description:
|
|
143
|
-
directives:
|
|
122
|
+
description: str | None = None,
|
|
123
|
+
directives: Sequence[object] | None = (),
|
|
144
124
|
extend: bool = False,
|
|
145
|
-
original_type_annotations:
|
|
125
|
+
original_type_annotations: dict[str, Any] | None = None,
|
|
146
126
|
) -> T:
|
|
147
127
|
name = name or to_camel_case(cls.__name__)
|
|
148
128
|
original_type_annotations = original_type_annotations or {}
|
|
@@ -208,11 +188,11 @@ def _process_type(
|
|
|
208
188
|
def type(
|
|
209
189
|
cls: T,
|
|
210
190
|
*,
|
|
211
|
-
name:
|
|
191
|
+
name: str | None = None,
|
|
212
192
|
is_input: bool = False,
|
|
213
193
|
is_interface: bool = False,
|
|
214
|
-
description:
|
|
215
|
-
directives:
|
|
194
|
+
description: str | None = None,
|
|
195
|
+
directives: Sequence[object] | None = (),
|
|
216
196
|
extend: bool = False,
|
|
217
197
|
) -> T: ...
|
|
218
198
|
|
|
@@ -223,25 +203,25 @@ def type(
|
|
|
223
203
|
)
|
|
224
204
|
def type(
|
|
225
205
|
*,
|
|
226
|
-
name:
|
|
206
|
+
name: str | None = None,
|
|
227
207
|
is_input: bool = False,
|
|
228
208
|
is_interface: bool = False,
|
|
229
|
-
description:
|
|
230
|
-
directives:
|
|
209
|
+
description: str | None = None,
|
|
210
|
+
directives: Sequence[object] | None = (),
|
|
231
211
|
extend: bool = False,
|
|
232
212
|
) -> Callable[[T], T]: ...
|
|
233
213
|
|
|
234
214
|
|
|
235
215
|
def type(
|
|
236
|
-
cls:
|
|
216
|
+
cls: T | None = None,
|
|
237
217
|
*,
|
|
238
|
-
name:
|
|
218
|
+
name: str | None = None,
|
|
239
219
|
is_input: bool = False,
|
|
240
220
|
is_interface: bool = False,
|
|
241
|
-
description:
|
|
242
|
-
directives:
|
|
221
|
+
description: str | None = None,
|
|
222
|
+
directives: Sequence[object] | None = (),
|
|
243
223
|
extend: bool = False,
|
|
244
|
-
) ->
|
|
224
|
+
) -> T | Callable[[T], T]:
|
|
245
225
|
"""Annotates a class as a GraphQL type.
|
|
246
226
|
|
|
247
227
|
Similar to `dataclasses.dataclass`, but with additional functionality for
|
|
@@ -330,10 +310,10 @@ def type(
|
|
|
330
310
|
def input(
|
|
331
311
|
cls: T,
|
|
332
312
|
*,
|
|
333
|
-
name:
|
|
334
|
-
one_of:
|
|
335
|
-
description:
|
|
336
|
-
directives:
|
|
313
|
+
name: str | None = None,
|
|
314
|
+
one_of: bool | None = None,
|
|
315
|
+
description: str | None = None,
|
|
316
|
+
directives: Sequence[object] | None = (),
|
|
337
317
|
) -> T: ...
|
|
338
318
|
|
|
339
319
|
|
|
@@ -343,20 +323,20 @@ def input(
|
|
|
343
323
|
)
|
|
344
324
|
def input(
|
|
345
325
|
*,
|
|
346
|
-
name:
|
|
347
|
-
one_of:
|
|
348
|
-
description:
|
|
349
|
-
directives:
|
|
326
|
+
name: str | None = None,
|
|
327
|
+
one_of: bool | None = None,
|
|
328
|
+
description: str | None = None,
|
|
329
|
+
directives: Sequence[object] | None = (),
|
|
350
330
|
) -> Callable[[T], T]: ...
|
|
351
331
|
|
|
352
332
|
|
|
353
333
|
def input(
|
|
354
|
-
cls:
|
|
334
|
+
cls: T | None = None,
|
|
355
335
|
*,
|
|
356
|
-
name:
|
|
357
|
-
one_of:
|
|
358
|
-
description:
|
|
359
|
-
directives:
|
|
336
|
+
name: str | None = None,
|
|
337
|
+
one_of: bool | None = None,
|
|
338
|
+
description: str | None = None,
|
|
339
|
+
directives: Sequence[object] | None = (),
|
|
360
340
|
):
|
|
361
341
|
"""Annotates a class as a GraphQL Input type.
|
|
362
342
|
|
|
@@ -409,9 +389,9 @@ def input(
|
|
|
409
389
|
def interface(
|
|
410
390
|
cls: T,
|
|
411
391
|
*,
|
|
412
|
-
name:
|
|
413
|
-
description:
|
|
414
|
-
directives:
|
|
392
|
+
name: str | None = None,
|
|
393
|
+
description: str | None = None,
|
|
394
|
+
directives: Sequence[object] | None = (),
|
|
415
395
|
) -> T: ...
|
|
416
396
|
|
|
417
397
|
|
|
@@ -421,9 +401,9 @@ def interface(
|
|
|
421
401
|
)
|
|
422
402
|
def interface(
|
|
423
403
|
*,
|
|
424
|
-
name:
|
|
425
|
-
description:
|
|
426
|
-
directives:
|
|
404
|
+
name: str | None = None,
|
|
405
|
+
description: str | None = None,
|
|
406
|
+
directives: Sequence[object] | None = (),
|
|
427
407
|
) -> Callable[[T], T]: ...
|
|
428
408
|
|
|
429
409
|
|
|
@@ -431,11 +411,11 @@ def interface(
|
|
|
431
411
|
order_default=True, kw_only_default=True, field_specifiers=(field, StrawberryField)
|
|
432
412
|
)
|
|
433
413
|
def interface(
|
|
434
|
-
cls:
|
|
414
|
+
cls: T | None = None,
|
|
435
415
|
*,
|
|
436
|
-
name:
|
|
437
|
-
description:
|
|
438
|
-
directives:
|
|
416
|
+
name: str | None = None,
|
|
417
|
+
description: str | None = None,
|
|
418
|
+
directives: Sequence[object] | None = (),
|
|
439
419
|
):
|
|
440
420
|
"""Annotates a class as a GraphQL Interface.
|
|
441
421
|
|
strawberry/types/scalar.py
CHANGED
|
@@ -5,11 +5,9 @@ from dataclasses import dataclass
|
|
|
5
5
|
from typing import (
|
|
6
6
|
TYPE_CHECKING,
|
|
7
7
|
Any,
|
|
8
|
-
Callable,
|
|
9
8
|
NewType,
|
|
10
9
|
Optional,
|
|
11
10
|
TypeVar,
|
|
12
|
-
Union,
|
|
13
11
|
overload,
|
|
14
12
|
)
|
|
15
13
|
|
|
@@ -18,16 +16,12 @@ from strawberry.types.base import StrawberryType
|
|
|
18
16
|
from strawberry.utils.str_converters import to_camel_case
|
|
19
17
|
|
|
20
18
|
if TYPE_CHECKING:
|
|
21
|
-
from collections.abc import Iterable, Mapping
|
|
19
|
+
from collections.abc import Callable, Iterable, Mapping
|
|
22
20
|
|
|
23
21
|
from graphql import GraphQLScalarType
|
|
24
22
|
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
if sys.version_info >= (3, 10):
|
|
28
|
-
_T = TypeVar("_T", bound=Union[type, NewType])
|
|
29
|
-
else:
|
|
30
|
-
_T = TypeVar("_T", bound=type)
|
|
24
|
+
_T = TypeVar("_T", bound=type | NewType)
|
|
31
25
|
|
|
32
26
|
|
|
33
27
|
def identity(x: _T) -> _T:
|
|
@@ -37,25 +31,25 @@ def identity(x: _T) -> _T:
|
|
|
37
31
|
@dataclass
|
|
38
32
|
class ScalarDefinition(StrawberryType):
|
|
39
33
|
name: str
|
|
40
|
-
description:
|
|
41
|
-
specified_by_url:
|
|
42
|
-
serialize:
|
|
43
|
-
parse_value:
|
|
44
|
-
parse_literal:
|
|
34
|
+
description: str | None
|
|
35
|
+
specified_by_url: str | None
|
|
36
|
+
serialize: Callable | None
|
|
37
|
+
parse_value: Callable | None
|
|
38
|
+
parse_literal: Callable | None
|
|
45
39
|
directives: Iterable[object] = ()
|
|
46
|
-
origin:
|
|
40
|
+
origin: GraphQLScalarType | type | None = None
|
|
47
41
|
|
|
48
42
|
# Optionally store the GraphQLScalarType instance so that we don't get
|
|
49
43
|
# duplicates
|
|
50
|
-
implementation:
|
|
44
|
+
implementation: GraphQLScalarType | None = None
|
|
51
45
|
|
|
52
46
|
# used for better error messages
|
|
53
|
-
_source_file:
|
|
54
|
-
_source_line:
|
|
47
|
+
_source_file: str | None = None
|
|
48
|
+
_source_line: int | None = None
|
|
55
49
|
|
|
56
50
|
def copy_with(
|
|
57
|
-
self, type_var_map: Mapping[str,
|
|
58
|
-
) ->
|
|
51
|
+
self, type_var_map: Mapping[str, StrawberryType | type]
|
|
52
|
+
) -> StrawberryType | type:
|
|
59
53
|
return super().copy_with(type_var_map) # type: ignore[safe-super]
|
|
60
54
|
|
|
61
55
|
@property
|
|
@@ -72,10 +66,10 @@ class ScalarWrapper:
|
|
|
72
66
|
def __call__(self, *args: str, **kwargs: Any) -> Any:
|
|
73
67
|
return self.wrap(*args, **kwargs)
|
|
74
68
|
|
|
75
|
-
def __or__(self, other:
|
|
69
|
+
def __or__(self, other: StrawberryType | type) -> StrawberryType:
|
|
76
70
|
if other is None:
|
|
77
71
|
# Return the correct notation when using `StrawberryUnion | None`.
|
|
78
|
-
return Optional[self]
|
|
72
|
+
return Optional[self] # noqa: UP045
|
|
79
73
|
|
|
80
74
|
# Raise an error in any other case.
|
|
81
75
|
# There is Work in progress to deal with more merging cases, see:
|
|
@@ -86,12 +80,12 @@ class ScalarWrapper:
|
|
|
86
80
|
def _process_scalar(
|
|
87
81
|
cls: _T,
|
|
88
82
|
*,
|
|
89
|
-
name:
|
|
90
|
-
description:
|
|
91
|
-
specified_by_url:
|
|
92
|
-
serialize:
|
|
93
|
-
parse_value:
|
|
94
|
-
parse_literal:
|
|
83
|
+
name: str | None = None,
|
|
84
|
+
description: str | None = None,
|
|
85
|
+
specified_by_url: str | None = None,
|
|
86
|
+
serialize: Callable | None = None,
|
|
87
|
+
parse_value: Callable | None = None,
|
|
88
|
+
parse_literal: Callable | None = None,
|
|
95
89
|
directives: Iterable[object] = (),
|
|
96
90
|
) -> ScalarWrapper:
|
|
97
91
|
from strawberry.exceptions.handler import should_use_rich_exceptions
|
|
@@ -127,12 +121,12 @@ def _process_scalar(
|
|
|
127
121
|
@overload
|
|
128
122
|
def scalar(
|
|
129
123
|
*,
|
|
130
|
-
name:
|
|
131
|
-
description:
|
|
132
|
-
specified_by_url:
|
|
124
|
+
name: str | None = None,
|
|
125
|
+
description: str | None = None,
|
|
126
|
+
specified_by_url: str | None = None,
|
|
133
127
|
serialize: Callable = identity,
|
|
134
|
-
parse_value:
|
|
135
|
-
parse_literal:
|
|
128
|
+
parse_value: Callable | None = None,
|
|
129
|
+
parse_literal: Callable | None = None,
|
|
136
130
|
directives: Iterable[object] = (),
|
|
137
131
|
) -> Callable[[_T], _T]: ...
|
|
138
132
|
|
|
@@ -141,12 +135,12 @@ def scalar(
|
|
|
141
135
|
def scalar(
|
|
142
136
|
cls: _T,
|
|
143
137
|
*,
|
|
144
|
-
name:
|
|
145
|
-
description:
|
|
146
|
-
specified_by_url:
|
|
138
|
+
name: str | None = None,
|
|
139
|
+
description: str | None = None,
|
|
140
|
+
specified_by_url: str | None = None,
|
|
147
141
|
serialize: Callable = identity,
|
|
148
|
-
parse_value:
|
|
149
|
-
parse_literal:
|
|
142
|
+
parse_value: Callable | None = None,
|
|
143
|
+
parse_literal: Callable | None = None,
|
|
150
144
|
directives: Iterable[object] = (),
|
|
151
145
|
) -> _T: ...
|
|
152
146
|
|
|
@@ -155,14 +149,14 @@ def scalar(
|
|
|
155
149
|
# here or else it won't let us use any custom scalar to annotate attributes in
|
|
156
150
|
# dataclasses/types. This should be properly solved when implementing StrawberryScalar
|
|
157
151
|
def scalar(
|
|
158
|
-
cls:
|
|
152
|
+
cls: _T | None = None,
|
|
159
153
|
*,
|
|
160
|
-
name:
|
|
161
|
-
description:
|
|
162
|
-
specified_by_url:
|
|
154
|
+
name: str | None = None,
|
|
155
|
+
description: str | None = None,
|
|
156
|
+
specified_by_url: str | None = None,
|
|
163
157
|
serialize: Callable = identity,
|
|
164
|
-
parse_value:
|
|
165
|
-
parse_literal:
|
|
158
|
+
parse_value: Callable | None = None,
|
|
159
|
+
parse_literal: Callable | None = None,
|
|
166
160
|
directives: Iterable[object] = (),
|
|
167
161
|
) -> Any:
|
|
168
162
|
"""Annotates a class or type as a GraphQL custom scalar.
|
strawberry/types/union.py
CHANGED
|
@@ -9,12 +9,10 @@ from typing import (
|
|
|
9
9
|
Annotated,
|
|
10
10
|
Any,
|
|
11
11
|
NoReturn,
|
|
12
|
-
Optional,
|
|
13
12
|
TypeVar,
|
|
14
|
-
Union,
|
|
15
13
|
cast,
|
|
14
|
+
get_origin,
|
|
16
15
|
)
|
|
17
|
-
from typing_extensions import get_origin
|
|
18
16
|
|
|
19
17
|
from graphql import GraphQLNamedType, GraphQLUnionType
|
|
20
18
|
|
|
@@ -48,14 +46,14 @@ if TYPE_CHECKING:
|
|
|
48
46
|
|
|
49
47
|
class StrawberryUnion(StrawberryType):
|
|
50
48
|
# used for better error messages
|
|
51
|
-
_source_file:
|
|
52
|
-
_source_line:
|
|
49
|
+
_source_file: str | None = None
|
|
50
|
+
_source_line: int | None = None
|
|
53
51
|
|
|
54
52
|
def __init__(
|
|
55
53
|
self,
|
|
56
|
-
name:
|
|
54
|
+
name: str | None = None,
|
|
57
55
|
type_annotations: tuple[StrawberryAnnotation, ...] = (),
|
|
58
|
-
description:
|
|
56
|
+
description: str | None = None,
|
|
59
57
|
directives: Iterable[object] = (),
|
|
60
58
|
) -> None:
|
|
61
59
|
self.graphql_name = name
|
|
@@ -64,7 +62,7 @@ class StrawberryUnion(StrawberryType):
|
|
|
64
62
|
self.directives = directives
|
|
65
63
|
self._source_file = None
|
|
66
64
|
self._source_line = None
|
|
67
|
-
self.concrete_of:
|
|
65
|
+
self.concrete_of: StrawberryUnion | None = None
|
|
68
66
|
|
|
69
67
|
def __eq__(self, other: object) -> bool:
|
|
70
68
|
if isinstance(other, StrawberryType):
|
|
@@ -81,7 +79,7 @@ class StrawberryUnion(StrawberryType):
|
|
|
81
79
|
def __hash__(self) -> int:
|
|
82
80
|
return hash((self.graphql_name, self.type_annotations, self.description))
|
|
83
81
|
|
|
84
|
-
def __or__(self, other:
|
|
82
|
+
def __or__(self, other: StrawberryType | type) -> StrawberryType:
|
|
85
83
|
# TODO: this will be removed in future versions, you should
|
|
86
84
|
# use Annotated[Union[...], strawberry.union(...)] instead
|
|
87
85
|
|
|
@@ -131,7 +129,7 @@ class StrawberryUnion(StrawberryType):
|
|
|
131
129
|
return any(map(_is_generic, self.types))
|
|
132
130
|
|
|
133
131
|
def copy_with(
|
|
134
|
-
self, type_var_map: Mapping[str,
|
|
132
|
+
self, type_var_map: Mapping[str, StrawberryType | type]
|
|
135
133
|
) -> StrawberryType:
|
|
136
134
|
if not self.is_graphql_generic:
|
|
137
135
|
return self
|
|
@@ -139,7 +137,7 @@ class StrawberryUnion(StrawberryType):
|
|
|
139
137
|
new_types = []
|
|
140
138
|
|
|
141
139
|
for type_ in self.types:
|
|
142
|
-
new_type:
|
|
140
|
+
new_type: StrawberryType | type
|
|
143
141
|
|
|
144
142
|
if has_object_definition(type_):
|
|
145
143
|
type_definition = type_.__strawberry_definition__
|
|
@@ -189,7 +187,7 @@ class StrawberryUnion(StrawberryType):
|
|
|
189
187
|
# Couldn't resolve using `is_type_of`
|
|
190
188
|
raise WrongReturnTypeForUnion(info.field_name, str(type(root)))
|
|
191
189
|
|
|
192
|
-
return_type:
|
|
190
|
+
return_type: GraphQLType | None
|
|
193
191
|
|
|
194
192
|
# Iterate over all of our known types and find the first concrete
|
|
195
193
|
# type that implements the type. We prioritise checking types named in the
|
|
@@ -242,9 +240,9 @@ class StrawberryUnion(StrawberryType):
|
|
|
242
240
|
|
|
243
241
|
def union(
|
|
244
242
|
name: str,
|
|
245
|
-
types:
|
|
243
|
+
types: Collection[type[Any]] | None = None,
|
|
246
244
|
*,
|
|
247
|
-
description:
|
|
245
|
+
description: str | None = None,
|
|
248
246
|
directives: Iterable[object] = (),
|
|
249
247
|
) -> StrawberryUnion:
|
|
250
248
|
"""Creates a new named Union type.
|
strawberry/utils/aio.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import sys
|
|
2
|
-
from collections.abc import
|
|
2
|
+
from collections.abc import (
|
|
3
|
+
AsyncGenerator,
|
|
4
|
+
AsyncIterable,
|
|
5
|
+
AsyncIterator,
|
|
6
|
+
Awaitable,
|
|
7
|
+
Callable,
|
|
8
|
+
)
|
|
3
9
|
from contextlib import asynccontextmanager, suppress
|
|
4
10
|
from typing import (
|
|
5
11
|
Any,
|
|
6
|
-
Callable,
|
|
7
|
-
Optional,
|
|
8
12
|
TypeVar,
|
|
9
|
-
Union,
|
|
10
13
|
cast,
|
|
11
14
|
)
|
|
12
15
|
|
|
@@ -30,7 +33,7 @@ async def aclosing(thing: _T) -> AsyncGenerator[_T, None]:
|
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
async def aenumerate(
|
|
33
|
-
iterable:
|
|
36
|
+
iterable: AsyncIterator[_T] | AsyncIterable[_T],
|
|
34
37
|
) -> AsyncIterator[tuple[int, _T]]:
|
|
35
38
|
"""Async version of enumerate."""
|
|
36
39
|
i = 0
|
|
@@ -40,10 +43,10 @@ async def aenumerate(
|
|
|
40
43
|
|
|
41
44
|
|
|
42
45
|
async def aislice(
|
|
43
|
-
aiterable:
|
|
44
|
-
start:
|
|
45
|
-
stop:
|
|
46
|
-
step:
|
|
46
|
+
aiterable: AsyncIterator[_T] | AsyncIterable[_T],
|
|
47
|
+
start: int | None = None,
|
|
48
|
+
stop: int | None = None,
|
|
49
|
+
step: int | None = None,
|
|
47
50
|
) -> AsyncIterator[_T]:
|
|
48
51
|
"""Async version of itertools.islice."""
|
|
49
52
|
# This is based on
|
strawberry/utils/await_maybe.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
from collections.abc import AsyncIterator, Awaitable, Iterator
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import TypeAlias, TypeVar
|
|
4
4
|
|
|
5
5
|
T = TypeVar("T")
|
|
6
6
|
|
|
7
|
-
AwaitableOrValue =
|
|
8
|
-
AsyncIteratorOrIterator =
|
|
7
|
+
AwaitableOrValue: TypeAlias = Awaitable[T] | T
|
|
8
|
+
AsyncIteratorOrIterator: TypeAlias = AsyncIterator[T] | Iterator[T]
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
async def await_maybe(value: AwaitableOrValue[T]) -> T:
|
strawberry/utils/deprecations.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class DEPRECATION_MESSAGES: # noqa: N801
|
|
@@ -19,7 +19,7 @@ class DeprecatedDescriptor:
|
|
|
19
19
|
def warn(self) -> None:
|
|
20
20
|
warnings.warn(self.msg, stacklevel=2)
|
|
21
21
|
|
|
22
|
-
def __get__(self, obj:
|
|
22
|
+
def __get__(self, obj: object | None, type: type | None = None) -> Any:
|
|
23
23
|
self.warn()
|
|
24
24
|
return self.alias
|
|
25
25
|
|
strawberry/utils/importer.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import importlib
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
def import_module_symbol(
|
|
6
|
-
selector: str, default_symbol_name:
|
|
5
|
+
selector: str, default_symbol_name: str | None = None
|
|
7
6
|
) -> object:
|
|
8
7
|
if ":" in selector:
|
|
9
8
|
module_name, symbol_name = selector.split(":", 1)
|
strawberry/utils/inspect.py
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import inspect
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
from functools import lru_cache
|
|
4
5
|
from typing import (
|
|
5
6
|
Any,
|
|
6
|
-
Callable,
|
|
7
7
|
Generic,
|
|
8
|
-
Optional,
|
|
9
8
|
Protocol,
|
|
10
9
|
TypeVar,
|
|
11
|
-
Union,
|
|
12
10
|
get_args,
|
|
13
11
|
get_origin,
|
|
14
12
|
)
|
|
@@ -39,7 +37,7 @@ def get_func_args(func: Callable[[Any], Any]) -> list[str]:
|
|
|
39
37
|
]
|
|
40
38
|
|
|
41
39
|
|
|
42
|
-
def get_specialized_type_var_map(cls: type) ->
|
|
40
|
+
def get_specialized_type_var_map(cls: type) -> dict[str, type] | None:
|
|
43
41
|
"""Get a type var map for specialized types.
|
|
44
42
|
|
|
45
43
|
Consider the following:
|
|
@@ -84,7 +82,7 @@ def get_specialized_type_var_map(cls: type) -> Optional[dict[str, type]]:
|
|
|
84
82
|
"""
|
|
85
83
|
from strawberry.types.base import has_object_definition
|
|
86
84
|
|
|
87
|
-
param_args: dict[TypeVar,
|
|
85
|
+
param_args: dict[TypeVar, TypeVar | type] = {}
|
|
88
86
|
|
|
89
87
|
types: list[type] = [cls]
|
|
90
88
|
while types:
|
|
@@ -99,7 +97,7 @@ def get_specialized_type_var_map(cls: type) -> Optional[dict[str, type]]:
|
|
|
99
97
|
if (type_params := getattr(origin, "__parameters__", None)) is not None:
|
|
100
98
|
args = get_args(tp)
|
|
101
99
|
if args:
|
|
102
|
-
for type_param, arg in zip(type_params, args):
|
|
100
|
+
for type_param, arg in zip(type_params, args, strict=True):
|
|
103
101
|
if type_param not in param_args:
|
|
104
102
|
param_args[type_param] = arg
|
|
105
103
|
else:
|
strawberry/utils/logging.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from typing import Final
|
|
@@ -18,7 +18,7 @@ class StrawberryLogger:
|
|
|
18
18
|
def error(
|
|
19
19
|
cls,
|
|
20
20
|
error: GraphQLError,
|
|
21
|
-
execution_context:
|
|
21
|
+
execution_context: ExecutionContext | None = None,
|
|
22
22
|
# https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values
|
|
23
23
|
**logger_kwargs: Any,
|
|
24
24
|
) -> None:
|
strawberry/utils/operation.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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 graphql.language import OperationDefinitionNode
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|
|
12
12
|
|
|
13
13
|
def get_first_operation(
|
|
14
14
|
graphql_document: DocumentNode,
|
|
15
|
-
) ->
|
|
15
|
+
) -> OperationDefinitionNode | None:
|
|
16
16
|
for definition in graphql_document.definitions:
|
|
17
17
|
if isinstance(definition, OperationDefinitionNode):
|
|
18
18
|
return definition
|
|
@@ -21,9 +21,9 @@ def get_first_operation(
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def get_operation_type(
|
|
24
|
-
graphql_document: DocumentNode, operation_name:
|
|
24
|
+
graphql_document: DocumentNode, operation_name: str | None = None
|
|
25
25
|
) -> OperationType:
|
|
26
|
-
definition:
|
|
26
|
+
definition: OperationDefinitionNode | None = None
|
|
27
27
|
|
|
28
28
|
if operation_name is not None:
|
|
29
29
|
for d in graphql_document.definitions:
|