strawberry-graphql 0.255.0__py3-none-any.whl → 0.256.1__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 +12 -15
- 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 +5 -2
- 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 +22 -24
- 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 +4 -3
- 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.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/METADATA +3 -6
- strawberry_graphql-0.256.1.dist-info/RECORD +236 -0
- strawberry_graphql-0.255.0.dist-info/RECORD +0 -236
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.255.0.dist-info → strawberry_graphql-0.256.1.dist-info}/entry_points.txt +0 -0
strawberry/http/ides.py
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
from email.message import Message
|
2
|
-
from typing import Dict, Tuple
|
3
2
|
|
4
3
|
|
5
|
-
def parse_content_type(content_type: str) ->
|
4
|
+
def parse_content_type(content_type: str) -> tuple[str, dict[str, str]]:
|
6
5
|
"""Parse a content type header into a mime-type and a dictionary of parameters."""
|
7
6
|
email = Message()
|
8
7
|
email["content-type"] = content_type
|
@@ -1,12 +1,10 @@
|
|
1
1
|
import abc
|
2
2
|
import json
|
3
|
+
from collections.abc import Mapping
|
3
4
|
from typing import (
|
4
5
|
Any,
|
5
6
|
Callable,
|
6
|
-
Dict,
|
7
7
|
Generic,
|
8
|
-
List,
|
9
|
-
Mapping,
|
10
8
|
Optional,
|
11
9
|
Union,
|
12
10
|
)
|
@@ -126,7 +124,7 @@ class SyncBaseHTTPView(
|
|
126
124
|
allowed_operation_types=allowed_operation_types,
|
127
125
|
)
|
128
126
|
|
129
|
-
def parse_multipart(self, request: SyncHTTPRequestAdapter) ->
|
127
|
+
def parse_multipart(self, request: SyncHTTPRequestAdapter) -> dict[str, str]:
|
130
128
|
operations = self.parse_json(request.post_data.get("operations", "{}"))
|
131
129
|
files_map = self.parse_json(request.post_data.get("map", "{}"))
|
132
130
|
|
@@ -159,7 +157,7 @@ class SyncBaseHTTPView(
|
|
159
157
|
)
|
160
158
|
|
161
159
|
def _handle_errors(
|
162
|
-
self, errors:
|
160
|
+
self, errors: list[GraphQLError], response_data: GraphQLHTTPResponse
|
163
161
|
) -> None:
|
164
162
|
"""Hook to allow custom handling of errors, used by the Sentry Integration."""
|
165
163
|
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from dataclasses import dataclass, field
|
2
|
-
from typing import Dict
|
3
2
|
|
4
3
|
|
5
4
|
@dataclass
|
6
5
|
class TemporalResponse:
|
7
6
|
status_code: int = 200
|
8
|
-
headers:
|
7
|
+
headers: dict[str, str] = field(default_factory=dict)
|
9
8
|
|
10
9
|
|
11
10
|
__all__ = ["TemporalResponse"]
|
strawberry/http/types.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Mapping
|
2
|
+
from typing import Any, Optional
|
2
3
|
from typing_extensions import Literal, TypedDict
|
3
4
|
|
4
5
|
HTTPMethod = Literal[
|
@@ -13,4 +14,4 @@ class FormData(TypedDict):
|
|
13
14
|
form: Mapping[str, Any]
|
14
15
|
|
15
16
|
|
16
|
-
__all__ = ["
|
17
|
+
__all__ = ["FormData", "HTTPMethod", "QueryParams"]
|
@@ -8,14 +8,8 @@ from datetime import timedelta
|
|
8
8
|
from typing import (
|
9
9
|
TYPE_CHECKING,
|
10
10
|
Any,
|
11
|
-
AsyncGenerator,
|
12
|
-
AsyncIterator,
|
13
11
|
Callable,
|
14
|
-
Dict,
|
15
|
-
FrozenSet,
|
16
12
|
Optional,
|
17
|
-
Tuple,
|
18
|
-
Type,
|
19
13
|
TypedDict,
|
20
14
|
Union,
|
21
15
|
cast,
|
@@ -60,7 +54,7 @@ from strawberry.http.typevars import Context, RootValue
|
|
60
54
|
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
|
61
55
|
|
62
56
|
if TYPE_CHECKING:
|
63
|
-
from collections.abc import Mapping
|
57
|
+
from collections.abc import AsyncGenerator, AsyncIterator, Mapping
|
64
58
|
|
65
59
|
from litestar.types import AnyCallable, Dependencies
|
66
60
|
from strawberry.http import GraphQLHTTPResponse
|
@@ -97,7 +91,7 @@ class WebSocketContextDict(TypedDict):
|
|
97
91
|
|
98
92
|
|
99
93
|
MergedContext = Union[
|
100
|
-
BaseContext, WebSocketContextDict, HTTPContextDict,
|
94
|
+
BaseContext, WebSocketContextDict, HTTPContextDict, dict[str, Any]
|
101
95
|
]
|
102
96
|
|
103
97
|
|
@@ -254,11 +248,11 @@ class GraphQLController(
|
|
254
248
|
websocket_adapter_class = LitestarWebSocketAdapter
|
255
249
|
|
256
250
|
allow_queries_via_get: bool = True
|
257
|
-
graphiql_allowed_accept:
|
251
|
+
graphiql_allowed_accept: frozenset[str] = frozenset({"text/html", "*/*"})
|
258
252
|
graphql_ide: Optional[GraphQL_IDE] = "graphiql"
|
259
253
|
debug: bool = False
|
260
254
|
connection_init_wait_timeout: timedelta = timedelta(minutes=1)
|
261
|
-
protocols:
|
255
|
+
protocols: tuple[str, ...] = (
|
262
256
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
263
257
|
GRAPHQL_WS_PROTOCOL,
|
264
258
|
)
|
@@ -329,7 +323,7 @@ class GraphQLController(
|
|
329
323
|
request: Request,
|
330
324
|
stream: Callable[[], AsyncIterator[str]],
|
331
325
|
sub_response: Response,
|
332
|
-
headers:
|
326
|
+
headers: dict[str, str],
|
333
327
|
) -> Response:
|
334
328
|
return Stream(
|
335
329
|
stream(),
|
@@ -416,13 +410,13 @@ def make_graphql_controller(
|
|
416
410
|
root_value_getter: Optional[AnyCallable] = None,
|
417
411
|
# TODO: context typevar
|
418
412
|
context_getter: Optional[AnyCallable] = None,
|
419
|
-
subscription_protocols:
|
413
|
+
subscription_protocols: tuple[str, ...] = (
|
420
414
|
GRAPHQL_TRANSPORT_WS_PROTOCOL,
|
421
415
|
GRAPHQL_WS_PROTOCOL,
|
422
416
|
),
|
423
417
|
connection_init_wait_timeout: timedelta = timedelta(minutes=1),
|
424
418
|
multipart_uploads_enabled: bool = False,
|
425
|
-
) ->
|
419
|
+
) -> type[GraphQLController]: # sourcery skip: move-assign
|
426
420
|
if context_getter is None:
|
427
421
|
custom_context_getter_ = _none_custom_context_getter
|
428
422
|
else:
|
@@ -474,6 +468,6 @@ def make_graphql_controller(
|
|
474
468
|
|
475
469
|
|
476
470
|
__all__ = [
|
477
|
-
"make_graphql_controller",
|
478
471
|
"GraphQLController",
|
472
|
+
"make_graphql_controller",
|
479
473
|
]
|
strawberry/parent.py
CHANGED
strawberry/permission.py
CHANGED
@@ -7,11 +7,7 @@ from inspect import iscoroutinefunction
|
|
7
7
|
from typing import (
|
8
8
|
TYPE_CHECKING,
|
9
9
|
Any,
|
10
|
-
Awaitable,
|
11
|
-
Dict,
|
12
|
-
List,
|
13
10
|
Optional,
|
14
|
-
Type,
|
15
11
|
Union,
|
16
12
|
)
|
17
13
|
|
@@ -25,6 +21,8 @@ from strawberry.types.base import StrawberryList, StrawberryOptional
|
|
25
21
|
from strawberry.utils.await_maybe import await_maybe
|
26
22
|
|
27
23
|
if TYPE_CHECKING:
|
24
|
+
from collections.abc import Awaitable
|
25
|
+
|
28
26
|
from graphql import GraphQLError, GraphQLErrorExtensions
|
29
27
|
|
30
28
|
from strawberry.extensions.field_extension import (
|
@@ -56,7 +54,7 @@ class BasePermission(abc.ABC):
|
|
56
54
|
|
57
55
|
error_extensions: Optional[GraphQLErrorExtensions] = None
|
58
56
|
|
59
|
-
error_class:
|
57
|
+
error_class: type[GraphQLError] = StrawberryGraphQLError
|
60
58
|
|
61
59
|
_schema_directive: Optional[object] = None
|
62
60
|
|
@@ -138,7 +136,7 @@ class PermissionExtension(FieldExtension):
|
|
138
136
|
|
139
137
|
def __init__(
|
140
138
|
self,
|
141
|
-
permissions:
|
139
|
+
permissions: list[BasePermission],
|
142
140
|
use_directives: bool = True,
|
143
141
|
fail_silently: bool = False,
|
144
142
|
) -> None:
|
@@ -189,7 +187,7 @@ class PermissionExtension(FieldExtension):
|
|
189
187
|
next_: SyncExtensionResolver,
|
190
188
|
source: Any,
|
191
189
|
info: Info,
|
192
|
-
**kwargs:
|
190
|
+
**kwargs: dict[str, Any],
|
193
191
|
) -> Any:
|
194
192
|
"""Checks if the permission should be accepted and raises an exception if not."""
|
195
193
|
for permission in self.permissions:
|
@@ -202,7 +200,7 @@ class PermissionExtension(FieldExtension):
|
|
202
200
|
next_: AsyncExtensionResolver,
|
203
201
|
source: Any,
|
204
202
|
info: Info,
|
205
|
-
**kwargs:
|
203
|
+
**kwargs: dict[str, Any],
|
206
204
|
) -> Any:
|
207
205
|
for permission in self.permissions:
|
208
206
|
has_permission = await await_maybe(
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import re
|
4
|
+
from collections.abc import Mapping
|
4
5
|
from math import isfinite
|
5
|
-
from typing import TYPE_CHECKING, Any,
|
6
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
6
7
|
|
7
8
|
from graphql.language import (
|
8
9
|
BooleanValueNode,
|
strawberry/printer/printer.py
CHANGED
@@ -5,19 +5,14 @@ from itertools import chain
|
|
5
5
|
from typing import (
|
6
6
|
TYPE_CHECKING,
|
7
7
|
Any,
|
8
|
-
Dict,
|
9
|
-
List,
|
10
8
|
Optional,
|
11
|
-
Set,
|
12
|
-
Tuple,
|
13
|
-
Type,
|
14
9
|
TypeVar,
|
15
10
|
Union,
|
16
11
|
cast,
|
17
12
|
overload,
|
18
13
|
)
|
19
14
|
|
20
|
-
from graphql import is_union_type
|
15
|
+
from graphql import GraphQLObjectType, GraphQLSchema, is_union_type
|
21
16
|
from graphql.language.printer import print_ast
|
22
17
|
from graphql.type import (
|
23
18
|
is_enum_type,
|
@@ -38,7 +33,11 @@ from graphql.utilities.print_schema import (
|
|
38
33
|
from graphql.utilities.print_schema import print_type as original_print_type
|
39
34
|
|
40
35
|
from strawberry.schema_directive import Location, StrawberrySchemaDirective
|
41
|
-
from strawberry.types.base import
|
36
|
+
from strawberry.types.base import (
|
37
|
+
StrawberryContainer,
|
38
|
+
StrawberryObjectDefinition,
|
39
|
+
has_object_definition,
|
40
|
+
)
|
42
41
|
from strawberry.types.enum import EnumDefinition
|
43
42
|
from strawberry.types.scalar import ScalarWrapper
|
44
43
|
from strawberry.types.unset import UNSET
|
@@ -64,18 +63,18 @@ _T = TypeVar("_T")
|
|
64
63
|
|
65
64
|
@dataclasses.dataclass
|
66
65
|
class PrintExtras:
|
67
|
-
directives:
|
68
|
-
types:
|
66
|
+
directives: set[str] = dataclasses.field(default_factory=set)
|
67
|
+
types: set[type] = dataclasses.field(default_factory=set)
|
69
68
|
|
70
69
|
|
71
70
|
@overload
|
72
|
-
def _serialize_dataclasses(value:
|
71
|
+
def _serialize_dataclasses(value: dict[_T, object]) -> dict[_T, object]: ...
|
73
72
|
|
74
73
|
|
75
74
|
@overload
|
76
75
|
def _serialize_dataclasses(
|
77
|
-
value: Union[
|
78
|
-
) ->
|
76
|
+
value: Union[list[object], tuple[object]],
|
77
|
+
) -> list[object]: ...
|
79
78
|
|
80
79
|
|
81
80
|
@overload
|
@@ -94,7 +93,7 @@ def _serialize_dataclasses(value):
|
|
94
93
|
|
95
94
|
|
96
95
|
def print_schema_directive_params(
|
97
|
-
directive: GraphQLDirective, values:
|
96
|
+
directive: GraphQLDirective, values: dict[str, Any]
|
98
97
|
) -> str:
|
99
98
|
params = []
|
100
99
|
for name, arg in directive.args.items():
|
@@ -189,7 +188,7 @@ def print_argument_directives(
|
|
189
188
|
|
190
189
|
|
191
190
|
def print_args(
|
192
|
-
args:
|
191
|
+
args: dict[str, GraphQLArgument],
|
193
192
|
indentation: str = "",
|
194
193
|
*,
|
195
194
|
schema: BaseSchema,
|
@@ -225,7 +224,12 @@ def print_args(
|
|
225
224
|
)
|
226
225
|
|
227
226
|
|
228
|
-
def print_fields(
|
227
|
+
def print_fields(
|
228
|
+
type_: GraphQLObjectType,
|
229
|
+
schema: BaseSchema,
|
230
|
+
*,
|
231
|
+
extras: PrintExtras,
|
232
|
+
) -> str:
|
229
233
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
230
234
|
|
231
235
|
fields = []
|
@@ -320,11 +324,13 @@ def print_enum(
|
|
320
324
|
)
|
321
325
|
|
322
326
|
|
323
|
-
def print_extends(type_:
|
327
|
+
def print_extends(type_: GraphQLObjectType, schema: BaseSchema) -> str:
|
324
328
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
325
329
|
|
326
|
-
strawberry_type =
|
327
|
-
|
330
|
+
strawberry_type = cast(
|
331
|
+
Optional[StrawberryObjectDefinition],
|
332
|
+
type_.extensions
|
333
|
+
and type_.extensions.get(GraphQLCoreConverter.DEFINITION_BACKREF),
|
328
334
|
)
|
329
335
|
|
330
336
|
if strawberry_type and strawberry_type.extend:
|
@@ -334,12 +340,14 @@ def print_extends(type_: Type, schema: BaseSchema) -> str:
|
|
334
340
|
|
335
341
|
|
336
342
|
def print_type_directives(
|
337
|
-
type_:
|
343
|
+
type_: GraphQLObjectType, schema: BaseSchema, *, extras: PrintExtras
|
338
344
|
) -> str:
|
339
345
|
from strawberry.schema.schema_converter import GraphQLCoreConverter
|
340
346
|
|
341
|
-
strawberry_type =
|
342
|
-
|
347
|
+
strawberry_type = cast(
|
348
|
+
Optional[StrawberryObjectDefinition],
|
349
|
+
type_.extensions
|
350
|
+
and type_.extensions.get(GraphQLCoreConverter.DEFINITION_BACKREF),
|
343
351
|
)
|
344
352
|
|
345
353
|
if not strawberry_type:
|
@@ -354,7 +362,7 @@ def print_type_directives(
|
|
354
362
|
for directive in strawberry_type.directives or []
|
355
363
|
if any(
|
356
364
|
location in allowed_locations
|
357
|
-
for location in directive.__strawberry_directive__.locations
|
365
|
+
for location in directive.__strawberry_directive__.locations # type: ignore[attr-defined]
|
358
366
|
)
|
359
367
|
)
|
360
368
|
|
@@ -550,21 +558,33 @@ def is_builtin_directive(directive: GraphQLDirective) -> bool:
|
|
550
558
|
|
551
559
|
|
552
560
|
def print_schema(schema: BaseSchema) -> str:
|
553
|
-
graphql_core_schema =
|
561
|
+
graphql_core_schema = cast(
|
562
|
+
GraphQLSchema,
|
563
|
+
schema._schema, # type: ignore
|
564
|
+
)
|
554
565
|
extras = PrintExtras()
|
555
566
|
|
556
|
-
|
557
|
-
|
558
|
-
|
567
|
+
filtered_directives = [
|
568
|
+
directive
|
569
|
+
for directive in graphql_core_schema.directives
|
570
|
+
if not is_builtin_directive(directive)
|
571
|
+
]
|
572
|
+
|
559
573
|
type_map = graphql_core_schema.type_map
|
560
|
-
types =
|
574
|
+
types = [
|
575
|
+
type_
|
576
|
+
for type_name in sorted(type_map)
|
577
|
+
if is_defined_type(type_ := type_map[type_name])
|
578
|
+
]
|
561
579
|
|
562
580
|
types_printed = [_print_type(type_, schema, extras=extras) for type_ in types]
|
563
581
|
schema_definition = print_schema_definition(schema, extras=extras)
|
564
582
|
|
565
|
-
directives =
|
566
|
-
|
567
|
-
|
583
|
+
directives = [
|
584
|
+
printed_directive
|
585
|
+
for directive in filtered_directives
|
586
|
+
if (printed_directive := print_directive(directive, schema=schema)) is not None
|
587
|
+
]
|
568
588
|
|
569
589
|
def _name_getter(type_: Any) -> str:
|
570
590
|
if hasattr(type_, "name"):
|
strawberry/quart/views.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import warnings
|
2
|
-
from collections.abc import Mapping
|
3
|
-
from typing import TYPE_CHECKING,
|
2
|
+
from collections.abc import AsyncGenerator, Mapping
|
3
|
+
from typing import TYPE_CHECKING, Callable, Optional, cast
|
4
4
|
from typing_extensions import TypeGuard
|
5
5
|
|
6
6
|
from quart import Request, Response, request
|
@@ -111,7 +111,7 @@ class GraphQLView(
|
|
111
111
|
request: Request,
|
112
112
|
stream: Callable[[], AsyncGenerator[str, None]],
|
113
113
|
sub_response: Response,
|
114
|
-
headers:
|
114
|
+
headers: dict[str, str],
|
115
115
|
) -> Response:
|
116
116
|
return (
|
117
117
|
stream(),
|
strawberry/relay/exceptions.py
CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from collections.abc import Callable
|
4
4
|
from functools import cached_property
|
5
|
-
from typing import TYPE_CHECKING, Optional,
|
5
|
+
from typing import TYPE_CHECKING, Optional, cast
|
6
6
|
|
7
7
|
from strawberry.exceptions.exception import StrawberryException
|
8
8
|
from strawberry.exceptions.utils.source_finder import SourceFinder
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
13
13
|
|
14
14
|
|
15
15
|
class NodeIDAnnotationError(StrawberryException):
|
16
|
-
def __init__(self, message: str, cls:
|
16
|
+
def __init__(self, message: str, cls: type) -> None:
|
17
17
|
self.cls = cls
|
18
18
|
|
19
19
|
self.message = message
|
@@ -41,7 +41,7 @@ class NodeIDAnnotationError(StrawberryException):
|
|
41
41
|
|
42
42
|
|
43
43
|
class RelayWrongAnnotationError(StrawberryException):
|
44
|
-
def __init__(self, field_name: str, cls:
|
44
|
+
def __init__(self, field_name: str, cls: type) -> None:
|
45
45
|
self.cls = cls
|
46
46
|
self.field_name = field_name
|
47
47
|
|
@@ -85,7 +85,7 @@ class RelayWrongResolverAnnotationError(StrawberryException):
|
|
85
85
|
)
|
86
86
|
self.suggestion = (
|
87
87
|
"To fix this error you can annootate your resolver to return "
|
88
|
-
"one of the following options: `
|
88
|
+
"one of the following options: `list[<NodeType>]`, "
|
89
89
|
"`Iterator[<NodeType>]`, `Iterable[<NodeType>]`, "
|
90
90
|
"`AsyncIterator[<NodeType>]`, `AsyncIterable[<NodeType>]`, "
|
91
91
|
"`Generator[<NodeType>, Any, Any]` and "
|
strawberry/relay/fields.py
CHANGED
@@ -4,28 +4,26 @@ import asyncio
|
|
4
4
|
import dataclasses
|
5
5
|
import inspect
|
6
6
|
from collections import defaultdict
|
7
|
-
from collections.abc import
|
8
|
-
|
9
|
-
TYPE_CHECKING,
|
10
|
-
Any,
|
7
|
+
from collections.abc import (
|
8
|
+
AsyncIterable,
|
11
9
|
AsyncIterator,
|
12
10
|
Awaitable,
|
13
|
-
Callable,
|
14
|
-
DefaultDict,
|
15
|
-
Dict,
|
16
|
-
ForwardRef,
|
17
11
|
Iterable,
|
18
12
|
Iterator,
|
19
|
-
List,
|
20
13
|
Mapping,
|
21
|
-
Optional,
|
22
14
|
Sequence,
|
23
|
-
|
24
|
-
|
15
|
+
)
|
16
|
+
from typing import (
|
17
|
+
TYPE_CHECKING,
|
18
|
+
Annotated,
|
19
|
+
Any,
|
20
|
+
Callable,
|
21
|
+
ForwardRef,
|
22
|
+
Optional,
|
25
23
|
Union,
|
26
24
|
cast,
|
27
25
|
)
|
28
|
-
from typing_extensions import
|
26
|
+
from typing_extensions import get_args, get_origin
|
29
27
|
|
30
28
|
from strawberry.annotation import StrawberryAnnotation
|
31
29
|
from strawberry.extensions.field_extension import (
|
@@ -100,7 +98,7 @@ class NodeExtension(FieldExtension):
|
|
100
98
|
|
101
99
|
def get_node_list_resolver(
|
102
100
|
self, field: StrawberryField
|
103
|
-
) -> Callable[[Info,
|
101
|
+
) -> Callable[[Info, list[GlobalID]], Union[list[Node], Awaitable[list[Node]]]]:
|
104
102
|
type_ = field.type
|
105
103
|
assert isinstance(type_, StrawberryList)
|
106
104
|
is_optional = isinstance(type_.of_type, StrawberryOptional)
|
@@ -108,14 +106,14 @@ class NodeExtension(FieldExtension):
|
|
108
106
|
def resolver(
|
109
107
|
info: Info,
|
110
108
|
ids: Annotated[
|
111
|
-
|
109
|
+
list[GlobalID], argument(description="The IDs of the objects.")
|
112
110
|
],
|
113
|
-
) -> Union[
|
114
|
-
nodes_map:
|
111
|
+
) -> Union[list[Node], Awaitable[list[Node]]]:
|
112
|
+
nodes_map: defaultdict[type[Node], list[str]] = defaultdict(list)
|
115
113
|
# Store the index of the node in the list of nodes of the same type
|
116
114
|
# so that we can return them in the same order while also supporting
|
117
115
|
# different types
|
118
|
-
index_map:
|
116
|
+
index_map: dict[GlobalID, tuple[type[Node], int]] = {}
|
119
117
|
for gid in ids:
|
120
118
|
node_t = gid.resolve_type(info)
|
121
119
|
nodes_map[node_t].append(gid.node_id)
|
@@ -143,7 +141,7 @@ class NodeExtension(FieldExtension):
|
|
143
141
|
|
144
142
|
if awaitable_nodes or asyncgen_nodes:
|
145
143
|
|
146
|
-
async def resolve(resolved: Any = resolved_nodes) ->
|
144
|
+
async def resolve(resolved: Any = resolved_nodes) -> list[Node]:
|
147
145
|
resolved.update(
|
148
146
|
zip(
|
149
147
|
[
|
@@ -182,7 +180,7 @@ class NodeExtension(FieldExtension):
|
|
182
180
|
|
183
181
|
|
184
182
|
class ConnectionExtension(FieldExtension):
|
185
|
-
connection_type:
|
183
|
+
connection_type: type[Connection[Node]]
|
186
184
|
|
187
185
|
def apply(self, field: StrawberryField) -> None:
|
188
186
|
field.arguments = [
|
@@ -268,7 +266,7 @@ class ConnectionExtension(FieldExtension):
|
|
268
266
|
):
|
269
267
|
raise RelayWrongResolverAnnotationError(field.name, field.base_resolver)
|
270
268
|
|
271
|
-
self.connection_type = cast(
|
269
|
+
self.connection_type = cast(type[Connection[Node]], f_type)
|
272
270
|
|
273
271
|
def resolve(
|
274
272
|
self,
|
@@ -352,13 +350,13 @@ def connection(
|
|
352
350
|
name: Optional[str] = None,
|
353
351
|
is_subscription: bool = False,
|
354
352
|
description: Optional[str] = None,
|
355
|
-
permission_classes: Optional[
|
353
|
+
permission_classes: Optional[list[type[BasePermission]]] = None,
|
356
354
|
deprecation_reason: Optional[str] = None,
|
357
355
|
default: Any = dataclasses.MISSING,
|
358
356
|
default_factory: Union[Callable[..., object], object] = dataclasses.MISSING,
|
359
357
|
metadata: Optional[Mapping[Any, Any]] = None,
|
360
358
|
directives: Optional[Sequence[object]] = (),
|
361
|
-
extensions:
|
359
|
+
extensions: list[FieldExtension] = (), # type: ignore
|
362
360
|
# This init parameter is used by pyright to determine whether this field
|
363
361
|
# is added in the constructor or not. It is not used to change
|
364
362
|
# any behaviour at the moment.
|
@@ -460,4 +458,4 @@ def connection(
|
|
460
458
|
return f
|
461
459
|
|
462
460
|
|
463
|
-
__all__ = ["
|
461
|
+
__all__ = ["connection", "node"]
|