strawberry-graphql 0.283.0__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.

Files changed (146) hide show
  1. strawberry/aiohttp/test/client.py +8 -15
  2. strawberry/aiohttp/views.py +12 -15
  3. strawberry/annotation.py +19 -23
  4. strawberry/asgi/__init__.py +18 -17
  5. strawberry/asgi/test/client.py +6 -6
  6. strawberry/chalice/views.py +6 -6
  7. strawberry/channels/handlers/base.py +7 -8
  8. strawberry/channels/handlers/http_handler.py +18 -20
  9. strawberry/channels/handlers/ws_handler.py +10 -12
  10. strawberry/channels/router.py +3 -4
  11. strawberry/channels/testing.py +7 -9
  12. strawberry/cli/commands/codegen.py +7 -7
  13. strawberry/cli/commands/schema_codegen.py +1 -2
  14. strawberry/cli/commands/upgrade/__init__.py +1 -3
  15. strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
  16. strawberry/codegen/plugins/print_operation.py +2 -2
  17. strawberry/codegen/plugins/python.py +2 -2
  18. strawberry/codegen/query_codegen.py +20 -30
  19. strawberry/codegen/types.py +32 -32
  20. strawberry/codemods/annotated_unions.py +2 -2
  21. strawberry/dataloader.py +28 -24
  22. strawberry/directive.py +6 -7
  23. strawberry/django/test/client.py +3 -3
  24. strawberry/django/views.py +16 -19
  25. strawberry/exceptions/__init__.py +4 -4
  26. strawberry/exceptions/conflicting_arguments.py +2 -2
  27. strawberry/exceptions/duplicated_type_name.py +4 -4
  28. strawberry/exceptions/exception.py +3 -3
  29. strawberry/exceptions/handler.py +8 -7
  30. strawberry/exceptions/invalid_argument_type.py +2 -2
  31. strawberry/exceptions/invalid_superclass_interface.py +2 -2
  32. strawberry/exceptions/invalid_union_type.py +4 -4
  33. strawberry/exceptions/missing_arguments_annotations.py +2 -2
  34. strawberry/exceptions/missing_dependencies.py +2 -4
  35. strawberry/exceptions/missing_field_annotation.py +2 -2
  36. strawberry/exceptions/missing_return_annotation.py +2 -2
  37. strawberry/exceptions/object_is_not_a_class.py +2 -2
  38. strawberry/exceptions/object_is_not_an_enum.py +2 -2
  39. strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
  40. strawberry/exceptions/private_strawberry_field.py +2 -2
  41. strawberry/exceptions/scalar_already_registered.py +2 -2
  42. strawberry/exceptions/syntax.py +3 -3
  43. strawberry/exceptions/unresolved_field_type.py +2 -2
  44. strawberry/exceptions/utils/source_finder.py +25 -25
  45. strawberry/experimental/pydantic/_compat.py +8 -7
  46. strawberry/experimental/pydantic/conversion.py +2 -2
  47. strawberry/experimental/pydantic/conversion_types.py +2 -2
  48. strawberry/experimental/pydantic/error_type.py +10 -12
  49. strawberry/experimental/pydantic/fields.py +9 -15
  50. strawberry/experimental/pydantic/object_type.py +15 -23
  51. strawberry/experimental/pydantic/utils.py +1 -2
  52. strawberry/ext/mypy_plugin.py +12 -14
  53. strawberry/extensions/base_extension.py +2 -1
  54. strawberry/extensions/context.py +13 -18
  55. strawberry/extensions/directives.py +3 -1
  56. strawberry/extensions/field_extension.py +4 -4
  57. strawberry/extensions/max_aliases.py +1 -3
  58. strawberry/extensions/parser_cache.py +1 -2
  59. strawberry/extensions/query_depth_limiter.py +18 -14
  60. strawberry/extensions/runner.py +2 -2
  61. strawberry/extensions/tracing/apollo.py +3 -3
  62. strawberry/extensions/tracing/datadog.py +3 -3
  63. strawberry/extensions/tracing/opentelemetry.py +6 -8
  64. strawberry/extensions/tracing/utils.py +3 -1
  65. strawberry/extensions/utils.py +2 -2
  66. strawberry/extensions/validation_cache.py +1 -2
  67. strawberry/fastapi/context.py +6 -6
  68. strawberry/fastapi/router.py +33 -36
  69. strawberry/federation/argument.py +4 -5
  70. strawberry/federation/enum.py +18 -21
  71. strawberry/federation/field.py +94 -97
  72. strawberry/federation/object_type.py +56 -58
  73. strawberry/federation/scalar.py +27 -35
  74. strawberry/federation/schema.py +15 -16
  75. strawberry/federation/schema_directive.py +7 -6
  76. strawberry/federation/schema_directives.py +11 -11
  77. strawberry/federation/union.py +4 -4
  78. strawberry/flask/views.py +10 -11
  79. strawberry/http/__init__.py +14 -14
  80. strawberry/http/async_base_view.py +23 -28
  81. strawberry/http/base.py +11 -12
  82. strawberry/http/ides.py +2 -3
  83. strawberry/http/sync_base_view.py +11 -13
  84. strawberry/http/types.py +3 -3
  85. strawberry/litestar/controller.py +40 -35
  86. strawberry/permission.py +4 -6
  87. strawberry/printer/ast_from_value.py +3 -5
  88. strawberry/printer/printer.py +8 -13
  89. strawberry/quart/views.py +12 -14
  90. strawberry/relay/exceptions.py +4 -4
  91. strawberry/relay/fields.py +33 -32
  92. strawberry/relay/types.py +31 -34
  93. strawberry/relay/utils.py +2 -2
  94. strawberry/resolvers.py +2 -1
  95. strawberry/sanic/context.py +1 -0
  96. strawberry/sanic/utils.py +3 -3
  97. strawberry/sanic/views.py +11 -14
  98. strawberry/scalars.py +2 -2
  99. strawberry/schema/_graphql_core.py +5 -5
  100. strawberry/schema/base.py +32 -33
  101. strawberry/schema/compat.py +9 -9
  102. strawberry/schema/config.py +5 -2
  103. strawberry/schema/exceptions.py +1 -3
  104. strawberry/schema/name_converter.py +6 -6
  105. strawberry/schema/schema.py +55 -60
  106. strawberry/schema/schema_converter.py +27 -22
  107. strawberry/schema/types/base_scalars.py +1 -1
  108. strawberry/schema/types/concrete_type.py +5 -5
  109. strawberry/schema_codegen/__init__.py +3 -3
  110. strawberry/schema_directive.py +7 -6
  111. strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -6
  112. strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
  113. strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -6
  114. strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
  115. strawberry/test/client.py +18 -18
  116. strawberry/tools/create_type.py +2 -3
  117. strawberry/types/arguments.py +25 -26
  118. strawberry/types/auto.py +3 -4
  119. strawberry/types/base.py +25 -27
  120. strawberry/types/enum.py +22 -25
  121. strawberry/types/execution.py +14 -15
  122. strawberry/types/field.py +108 -108
  123. strawberry/types/fields/resolver.py +19 -21
  124. strawberry/types/info.py +5 -11
  125. strawberry/types/lazy_type.py +2 -3
  126. strawberry/types/maybe.py +12 -3
  127. strawberry/types/mutation.py +115 -118
  128. strawberry/types/nodes.py +2 -2
  129. strawberry/types/object_type.py +43 -63
  130. strawberry/types/scalar.py +37 -43
  131. strawberry/types/union.py +12 -14
  132. strawberry/utils/aio.py +12 -9
  133. strawberry/utils/await_maybe.py +3 -3
  134. strawberry/utils/deprecations.py +2 -2
  135. strawberry/utils/importer.py +1 -2
  136. strawberry/utils/inspect.py +4 -6
  137. strawberry/utils/logging.py +2 -2
  138. strawberry/utils/operation.py +4 -4
  139. strawberry/utils/typing.py +18 -83
  140. {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +2 -2
  141. strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
  142. strawberry/utils/dataclasses.py +0 -37
  143. strawberry_graphql-0.283.0.dist-info/RECORD +0 -244
  144. {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +0 -0
  145. {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
  146. {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable
3
4
  from enum import Enum
4
- from typing import TYPE_CHECKING, Any, Callable
5
+ from typing import TYPE_CHECKING, Any
5
6
 
6
7
  from strawberry.utils.await_maybe import AsyncIteratorOrIterator, AwaitableOrValue
7
8
 
@@ -8,17 +8,14 @@ from asyncio import iscoroutinefunction
8
8
  from typing import (
9
9
  TYPE_CHECKING,
10
10
  Any,
11
- Callable,
12
11
  NamedTuple,
13
- Optional,
14
- Union,
15
12
  )
16
13
 
17
14
  from strawberry.extensions import SchemaExtension
18
15
  from strawberry.utils.await_maybe import AwaitableOrValue, await_maybe
19
16
 
20
17
  if TYPE_CHECKING:
21
- from collections.abc import AsyncIterator, Iterator
18
+ from collections.abc import AsyncIterator, Callable, Iterator
22
19
  from types import TracebackType
23
20
 
24
21
  from strawberry.extensions.base_extension import Hook
@@ -28,10 +25,8 @@ class WrappedHook(NamedTuple):
28
25
  extension: SchemaExtension
29
26
  hook: Callable[
30
27
  ...,
31
- Union[
32
- contextlib.AbstractAsyncContextManager[None],
33
- contextlib.AbstractContextManager[None],
34
- ],
28
+ contextlib.AbstractAsyncContextManager[None]
29
+ | contextlib.AbstractContextManager[None],
35
30
  ]
36
31
  is_async: bool
37
32
 
@@ -65,12 +60,12 @@ class ExtensionContextManagerBase:
65
60
  if hook:
66
61
  self.hooks.append(hook)
67
62
 
68
- def get_hook(self, extension: SchemaExtension) -> Optional[WrappedHook]:
63
+ def get_hook(self, extension: SchemaExtension) -> WrappedHook | None:
69
64
  on_start = getattr(extension, self.LEGACY_ENTER, None)
70
65
  on_end = getattr(extension, self.LEGACY_EXIT, None)
71
66
 
72
67
  is_legacy = on_start is not None or on_end is not None
73
- hook_fn: Optional[Hook] = getattr(type(extension), self.HOOK_NAME)
68
+ hook_fn: Hook | None = getattr(type(extension), self.HOOK_NAME)
74
69
  hook_fn = hook_fn if hook_fn is not self.default_hook else None
75
70
  if is_legacy and hook_fn is not None:
76
71
  raise ValueError(
@@ -111,8 +106,8 @@ class ExtensionContextManagerBase:
111
106
  @staticmethod
112
107
  def from_legacy(
113
108
  extension: SchemaExtension,
114
- on_start: Optional[Callable[[], None]] = None,
115
- on_end: Optional[Callable[[], None]] = None,
109
+ on_start: Callable[[], None] | None = None,
110
+ on_end: Callable[[], None] | None = None,
116
111
  ) -> WrappedHook:
117
112
  if iscoroutinefunction(on_start) or iscoroutinefunction(on_end):
118
113
 
@@ -176,9 +171,9 @@ class ExtensionContextManagerBase:
176
171
 
177
172
  def __exit__(
178
173
  self,
179
- exc_type: Optional[type[BaseException]],
180
- exc_val: Optional[BaseException],
181
- exc_tb: Optional[TracebackType],
174
+ exc_type: type[BaseException] | None,
175
+ exc_val: BaseException | None,
176
+ exc_tb: TracebackType | None,
182
177
  ) -> None:
183
178
  self.exit_stack.__exit__(exc_type, exc_val, exc_tb)
184
179
 
@@ -195,9 +190,9 @@ class ExtensionContextManagerBase:
195
190
 
196
191
  async def __aexit__(
197
192
  self,
198
- exc_type: Optional[type[BaseException]],
199
- exc_val: Optional[BaseException],
200
- exc_tb: Optional[TracebackType],
193
+ exc_type: type[BaseException] | None,
194
+ exc_val: BaseException | None,
195
+ exc_tb: TracebackType | None,
201
196
  ) -> None:
202
197
  await self.async_exit_stack.__aexit__(exc_type, exc_val, exc_tb)
203
198
 
@@ -1,12 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Callable
3
+ from typing import TYPE_CHECKING, Any
4
4
 
5
5
  from strawberry.extensions import SchemaExtension
6
6
  from strawberry.types.nodes import convert_arguments
7
7
  from strawberry.utils.await_maybe import await_maybe
8
8
 
9
9
  if TYPE_CHECKING:
10
+ from collections.abc import Callable
11
+
10
12
  from graphql import DirectiveNode, GraphQLResolveInfo
11
13
 
12
14
  from strawberry.directive import StrawberryDirective
@@ -1,12 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import itertools
4
- from collections.abc import Awaitable
4
+ from collections.abc import Awaitable, Callable
5
5
  from functools import cached_property
6
- from typing import TYPE_CHECKING, Any, Callable, Union
6
+ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  if TYPE_CHECKING:
9
- from typing_extensions import TypeAlias
9
+ from typing import TypeAlias
10
10
 
11
11
  from strawberry.types import Info
12
12
  from strawberry.types.field import StrawberryField
@@ -69,7 +69,7 @@ def _get_async_resolvers(
69
69
 
70
70
  def build_field_extension_resolvers(
71
71
  field: StrawberryField,
72
- ) -> list[Union[SyncExtensionResolver, AsyncExtensionResolver]]:
72
+ ) -> list[SyncExtensionResolver | AsyncExtensionResolver]:
73
73
  """Builds a list of resolvers for a field with extensions.
74
74
 
75
75
  Verifies that all of the field extensions for a given field support
@@ -1,5 +1,3 @@
1
- from typing import Union
2
-
3
1
  from graphql import (
4
2
  ExecutableDefinitionNode,
5
3
  FieldNode,
@@ -64,7 +62,7 @@ def create_validator(max_alias_count: int) -> type[ValidationRule]:
64
62
 
65
63
 
66
64
  def count_fields_with_alias(
67
- selection_set_owner: Union[ExecutableDefinitionNode, FieldNode, InlineFragmentNode],
65
+ selection_set_owner: ExecutableDefinitionNode | FieldNode | InlineFragmentNode,
68
66
  ) -> int:
69
67
  if selection_set_owner.selection_set is None:
70
68
  return 0
@@ -1,6 +1,5 @@
1
1
  from collections.abc import Iterator
2
2
  from functools import lru_cache
3
- from typing import Optional
4
3
 
5
4
  from graphql.language.parser import parse
6
5
 
@@ -25,7 +24,7 @@ class ParserCache(SchemaExtension):
25
24
  ```
26
25
  """
27
26
 
28
- def __init__(self, maxsize: Optional[int] = None) -> None:
27
+ def __init__(self, maxsize: int | None = None) -> None:
29
28
  """Initialize the ParserCache.
30
29
 
31
30
  Args:
@@ -28,12 +28,11 @@
28
28
  from __future__ import annotations
29
29
 
30
30
  import re
31
+ from collections.abc import Callable
31
32
  from dataclasses import dataclass
32
33
  from typing import (
33
34
  TYPE_CHECKING,
34
- Callable,
35
- Optional,
36
- Union,
35
+ TypeAlias,
37
36
  )
38
37
 
39
38
  from graphql import GraphQLError
@@ -61,12 +60,17 @@ from strawberry.extensions.utils import is_introspection_key
61
60
  if TYPE_CHECKING:
62
61
  from collections.abc import Iterable
63
62
 
64
- IgnoreType = Union[Callable[[str], bool], re.Pattern, str]
63
+ IgnoreType: TypeAlias = Callable[[str], bool] | re.Pattern | str
65
64
 
66
- FieldArgumentType = Union[
67
- bool, int, float, str, list["FieldArgumentType"], dict[str, "FieldArgumentType"]
68
- ]
69
- FieldArgumentsType = dict[str, FieldArgumentType]
65
+ FieldArgumentType: TypeAlias = (
66
+ bool
67
+ | int
68
+ | float
69
+ | str
70
+ | list["FieldArgumentType"]
71
+ | dict[str, "FieldArgumentType"]
72
+ )
73
+ FieldArgumentsType: TypeAlias = dict[str, FieldArgumentType]
70
74
 
71
75
 
72
76
  @dataclass
@@ -99,8 +103,8 @@ class QueryDepthLimiter(AddValidationRules):
99
103
  def __init__(
100
104
  self,
101
105
  max_depth: int,
102
- callback: Optional[Callable[[dict[str, int]], None]] = None,
103
- should_ignore: Optional[ShouldIgnoreType] = None,
106
+ callback: Callable[[dict[str, int]], None] | None = None,
107
+ should_ignore: ShouldIgnoreType | None = None,
104
108
  ) -> None:
105
109
  """Initialize the QueryDepthLimiter.
106
110
 
@@ -122,8 +126,8 @@ class QueryDepthLimiter(AddValidationRules):
122
126
 
123
127
  def create_validator(
124
128
  max_depth: int,
125
- should_ignore: Optional[ShouldIgnoreType],
126
- callback: Optional[Callable[[dict[str, int]], None]] = None,
129
+ should_ignore: ShouldIgnoreType | None,
130
+ callback: Callable[[dict[str, int]], None] | None = None,
127
131
  ) -> type[ValidationRule]:
128
132
  class DepthLimitValidator(ValidationRule):
129
133
  def __init__(self, validation_context: ValidationContext) -> None:
@@ -218,7 +222,7 @@ def determine_depth(
218
222
  max_depth: int,
219
223
  context: ValidationContext,
220
224
  operation_name: str,
221
- should_ignore: Optional[ShouldIgnoreType],
225
+ should_ignore: ShouldIgnoreType | None,
222
226
  ) -> int:
223
227
  if depth_so_far > max_depth:
224
228
  context.report_error(
@@ -288,7 +292,7 @@ def determine_depth(
288
292
  raise TypeError(f"Depth crawler cannot handle: {node.kind}") # pragma: no cover
289
293
 
290
294
 
291
- def is_ignored(node: FieldNode, ignore: Optional[list[IgnoreType]] = None) -> bool:
295
+ def is_ignored(node: FieldNode, ignore: list[IgnoreType] | None = None) -> bool:
292
296
  if ignore is None:
293
297
  return False
294
298
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import inspect
4
- from typing import TYPE_CHECKING, Any, Optional
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from strawberry.extensions.context import (
7
7
  ExecutingContextManager,
@@ -23,7 +23,7 @@ class SchemaExtensionsRunner:
23
23
  def __init__(
24
24
  self,
25
25
  execution_context: ExecutionContext,
26
- extensions: Optional[list[SchemaExtension]] = None,
26
+ extensions: list[SchemaExtension] | None = None,
27
27
  ) -> None:
28
28
  self.execution_context = execution_context
29
29
  self.extensions = extensions or []
@@ -4,7 +4,7 @@ import dataclasses
4
4
  import time
5
5
  from datetime import datetime, timezone
6
6
  from inspect import isawaitable
7
- from typing import TYPE_CHECKING, Any, Callable, Optional
7
+ from typing import TYPE_CHECKING, Any
8
8
 
9
9
  from strawberry.extensions import SchemaExtension
10
10
  from strawberry.extensions.utils import get_path_from_info
@@ -12,7 +12,7 @@ from strawberry.extensions.utils import get_path_from_info
12
12
  from .utils import should_skip_tracing
13
13
 
14
14
  if TYPE_CHECKING:
15
- from collections.abc import Generator
15
+ from collections.abc import Callable, Generator
16
16
 
17
17
  from graphql import GraphQLResolveInfo
18
18
 
@@ -38,7 +38,7 @@ class ApolloResolverStats:
38
38
  field_name: str
39
39
  return_type: Any
40
40
  start_offset: int
41
- duration: Optional[int] = None
41
+ duration: int | None = None
42
42
 
43
43
  def to_json(self) -> dict[str, Any]:
44
44
  return {
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import hashlib
4
4
  from functools import cached_property
5
5
  from inspect import isawaitable
6
- from typing import TYPE_CHECKING, Any, Callable, Optional
6
+ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  import ddtrace
9
9
  from packaging import version
@@ -19,7 +19,7 @@ else:
19
19
 
20
20
 
21
21
  if TYPE_CHECKING:
22
- from collections.abc import Generator, Iterator
22
+ from collections.abc import Callable, Generator, Iterator
23
23
 
24
24
  from graphql import GraphQLResolveInfo
25
25
 
@@ -30,7 +30,7 @@ class DatadogTracingExtension(SchemaExtension):
30
30
  def __init__(
31
31
  self,
32
32
  *,
33
- execution_context: Optional[ExecutionContext] = None,
33
+ execution_context: ExecutionContext | None = None,
34
34
  ) -> None:
35
35
  if execution_context:
36
36
  self.execution_context = execution_context
@@ -1,13 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable
3
4
  from copy import deepcopy
4
5
  from inspect import isawaitable
5
6
  from typing import (
6
7
  TYPE_CHECKING,
7
8
  Any,
8
- Callable,
9
- Optional,
10
- Union,
11
9
  )
12
10
 
13
11
  from opentelemetry import trace
@@ -33,16 +31,16 @@ ArgFilter = Callable[[dict[str, Any], "GraphQLResolveInfo"], dict[str, Any]]
33
31
 
34
32
 
35
33
  class OpenTelemetryExtension(SchemaExtension):
36
- _arg_filter: Optional[ArgFilter]
34
+ _arg_filter: ArgFilter | None
37
35
  _span_holder: dict[LifecycleStep, Span]
38
36
  _tracer: Tracer
39
37
 
40
38
  def __init__(
41
39
  self,
42
40
  *,
43
- execution_context: Optional[ExecutionContext] = None,
44
- arg_filter: Optional[ArgFilter] = None,
45
- tracer_provider: Optional[trace.TracerProvider] = None,
41
+ execution_context: ExecutionContext | None = None,
42
+ arg_filter: ArgFilter | None = None,
43
+ tracer_provider: trace.TracerProvider | None = None,
46
44
  ) -> None:
47
45
  self._arg_filter = arg_filter
48
46
  self._tracer = trace.get_tracer("strawberry", tracer_provider=tracer_provider)
@@ -129,7 +127,7 @@ class OpenTelemetryExtension(SchemaExtension):
129
127
  return bytes(value) # Convert bytearray and memoryview to bytes
130
128
  return str(value)
131
129
 
132
- def convert_set_to_allowed_types(self, value: Union[set, frozenset]) -> str:
130
+ def convert_set_to_allowed_types(self, value: set | frozenset) -> str:
133
131
  return (
134
132
  "{" + ", ".join(str(self.convert_to_allowed_types(x)) for x in value) + "}"
135
133
  )
@@ -1,11 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Callable
3
+ from typing import TYPE_CHECKING, Any
4
4
 
5
5
  from strawberry.extensions.utils import is_introspection_field
6
6
  from strawberry.resolvers import is_default_resolver
7
7
 
8
8
  if TYPE_CHECKING:
9
+ from collections.abc import Callable
10
+
9
11
  from graphql import GraphQLResolveInfo
10
12
 
11
13
 
@@ -1,12 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Union
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from graphql import GraphQLResolveInfo
7
7
 
8
8
 
9
- def is_introspection_key(key: Union[str, int]) -> bool:
9
+ def is_introspection_key(key: str | int) -> bool:
10
10
  # from: https://spec.graphql.org/June2018/#sec-Schema
11
11
  # > All types and directives defined within a schema must not have a name which
12
12
  # > begins with "__" (two underscores), as this is used exclusively
@@ -1,6 +1,5 @@
1
1
  from collections.abc import Iterator
2
2
  from functools import lru_cache
3
- from typing import Optional
4
3
 
5
4
  from strawberry.extensions.base_extension import SchemaExtension
6
5
 
@@ -22,7 +21,7 @@ class ValidationCache(SchemaExtension):
22
21
  ```
23
22
  """
24
23
 
25
- def __init__(self, maxsize: Optional[int] = None) -> None:
24
+ def __init__(self, maxsize: int | None = None) -> None:
26
25
  """Initialize the ValidationCache.
27
26
 
28
27
  Args:
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional, Union
1
+ from typing import Any, Union
2
2
 
3
3
  from starlette.background import BackgroundTasks
4
4
  from starlette.requests import Request
@@ -7,17 +7,17 @@ from starlette.websockets import WebSocket
7
7
 
8
8
  CustomContext = Union["BaseContext", dict[str, Any]]
9
9
  MergedContext = Union[
10
- "BaseContext", dict[str, Union[Any, BackgroundTasks, Request, Response, WebSocket]]
10
+ "BaseContext", dict[str, Any | BackgroundTasks | Request | Response | WebSocket]
11
11
  ]
12
12
 
13
13
 
14
14
  class BaseContext:
15
- connection_params: Optional[Any] = None
15
+ connection_params: Any | None = None
16
16
 
17
17
  def __init__(self) -> None:
18
- self.request: Optional[Union[Request, WebSocket]] = None
19
- self.background_tasks: Optional[BackgroundTasks] = None
20
- self.response: Optional[Response] = None
18
+ self.request: Request | WebSocket | None = None
19
+ self.background_tasks: BackgroundTasks | None = None
20
+ self.response: Response | None = None
21
21
 
22
22
 
23
23
  __all__ = ["BaseContext"]
@@ -6,13 +6,14 @@ from inspect import signature
6
6
  from typing import (
7
7
  TYPE_CHECKING,
8
8
  Any,
9
- Callable,
10
- Optional,
11
- Union,
9
+ TypeGuard,
12
10
  cast,
13
11
  )
14
- from typing_extensions import TypeGuard
15
12
 
13
+ from fastapi import APIRouter, Depends, params
14
+ from fastapi.datastructures import Default
15
+ from fastapi.routing import APIRoute
16
+ from fastapi.utils import generate_unique_id
16
17
  from lia import HTTPException, StarletteRequestAdapter
17
18
  from starlette import status
18
19
  from starlette.background import BackgroundTasks # noqa: TC002
@@ -26,10 +27,6 @@ from starlette.responses import (
26
27
  )
27
28
  from starlette.websockets import WebSocket
28
29
 
29
- from fastapi import APIRouter, Depends, params
30
- from fastapi.datastructures import Default
31
- from fastapi.routing import APIRoute
32
- from fastapi.utils import generate_unique_id
33
30
  from strawberry.asgi import ASGIWebSocketAdapter
34
31
  from strawberry.exceptions import InvalidCustomContext
35
32
  from strawberry.fastapi.context import BaseContext, CustomContext
@@ -41,6 +38,7 @@ if TYPE_CHECKING:
41
38
  from collections.abc import (
42
39
  AsyncIterator,
43
40
  Awaitable,
41
+ Callable,
44
42
  Sequence,
45
43
  )
46
44
  from enum import Enum
@@ -62,7 +60,7 @@ class GraphQLRouter(
62
60
  ):
63
61
  allow_queries_via_get = True
64
62
  request_adapter_class = StarletteRequestAdapter
65
- websocket_adapter_class = ASGIWebSocketAdapter
63
+ websocket_adapter_class = ASGIWebSocketAdapter # type: ignore
66
64
 
67
65
  @staticmethod
68
66
  async def __get_root_value() -> None:
@@ -71,16 +69,16 @@ class GraphQLRouter(
71
69
  @staticmethod
72
70
  def __get_context_getter(
73
71
  custom_getter: Callable[
74
- ..., Union[Optional[CustomContext], Awaitable[Optional[CustomContext]]]
72
+ ..., CustomContext | None | Awaitable[CustomContext | None]
75
73
  ],
76
74
  ) -> Callable[..., Awaitable[CustomContext]]:
77
75
  async def dependency(
78
- custom_context: Optional[CustomContext],
76
+ custom_context: CustomContext | None,
79
77
  background_tasks: BackgroundTasks,
80
78
  connection: HTTPConnection,
81
79
  response: Response = None, # type: ignore
82
80
  ) -> MergedContext:
83
- request = cast("Union[Request, WebSocket]", connection)
81
+ request = cast("Request | WebSocket", connection)
84
82
  if isinstance(custom_context, BaseContext):
85
83
  custom_context.request = request
86
84
  custom_context.background_tasks = background_tasks
@@ -122,35 +120,34 @@ class GraphQLRouter(
122
120
  self,
123
121
  schema: BaseSchema,
124
122
  path: str = "",
125
- graphiql: Optional[bool] = None,
126
- graphql_ide: Optional[GraphQL_IDE] = "graphiql",
123
+ graphiql: bool | None = None,
124
+ graphql_ide: GraphQL_IDE | None = "graphiql",
127
125
  allow_queries_via_get: bool = True,
128
126
  keep_alive: bool = False,
129
127
  keep_alive_interval: float = 1,
130
- root_value_getter: Optional[Callable[[], RootValue]] = None,
131
- context_getter: Optional[
132
- Callable[..., Union[Optional[Context], Awaitable[Optional[Context]]]]
133
- ] = None,
128
+ root_value_getter: Callable[[], RootValue] | None = None,
129
+ context_getter: Callable[..., Context | None | Awaitable[Context | None]]
130
+ | None = None,
134
131
  subscription_protocols: Sequence[str] = (
135
132
  GRAPHQL_TRANSPORT_WS_PROTOCOL,
136
133
  GRAPHQL_WS_PROTOCOL,
137
134
  ),
138
135
  connection_init_wait_timeout: timedelta = timedelta(minutes=1),
139
136
  prefix: str = "",
140
- tags: Optional[list[Union[str, Enum]]] = None,
141
- dependencies: Optional[Sequence[params.Depends]] = None,
137
+ tags: list[str | Enum] | None = None,
138
+ dependencies: Sequence[params.Depends] | None = None,
142
139
  default_response_class: type[Response] = Default(JSONResponse),
143
- responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
144
- callbacks: Optional[list[BaseRoute]] = None,
145
- routes: Optional[list[BaseRoute]] = None,
140
+ responses: dict[int | str, dict[str, Any]] | None = None,
141
+ callbacks: list[BaseRoute] | None = None,
142
+ routes: list[BaseRoute] | None = None,
146
143
  redirect_slashes: bool = True,
147
- default: Optional[ASGIApp] = None,
148
- dependency_overrides_provider: Optional[Any] = None,
144
+ default: ASGIApp | None = None,
145
+ dependency_overrides_provider: Any | None = None,
149
146
  route_class: type[APIRoute] = APIRoute,
150
- on_startup: Optional[Sequence[Callable[[], Any]]] = None,
151
- on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
152
- lifespan: Optional[Lifespan[Any]] = None,
153
- deprecated: Optional[bool] = None,
147
+ on_startup: Sequence[Callable[[], Any]] | None = None,
148
+ on_shutdown: Sequence[Callable[[], Any]] | None = None,
149
+ lifespan: Lifespan[Any] | None = None,
150
+ deprecated: bool | None = None,
154
151
  include_in_schema: bool = True,
155
152
  generate_unique_id_function: Callable[[APIRoute], str] = Default(
156
153
  generate_unique_id
@@ -265,13 +262,13 @@ class GraphQLRouter(
265
262
  return HTMLResponse(self.graphql_ide_html)
266
263
 
267
264
  async def get_context(
268
- self, request: Union[Request, WebSocket], response: Union[Response, WebSocket]
265
+ self, request: Request | WebSocket, response: Response | WebSocket
269
266
  ) -> Context: # pragma: no cover
270
267
  raise ValueError("`get_context` is not used by FastAPI GraphQL Router")
271
268
 
272
269
  async def get_root_value(
273
- self, request: Union[Request, WebSocket]
274
- ) -> Optional[RootValue]: # pragma: no cover
270
+ self, request: Request | WebSocket
271
+ ) -> RootValue | None: # pragma: no cover
275
272
  raise ValueError("`get_root_value` is not used by FastAPI GraphQL Router")
276
273
 
277
274
  async def get_sub_response(self, request: Request) -> Response:
@@ -279,7 +276,7 @@ class GraphQLRouter(
279
276
 
280
277
  def create_response(
281
278
  self,
282
- response_data: Union[GraphQLHTTPResponse, list[GraphQLHTTPResponse]],
279
+ response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
283
280
  sub_response: Response,
284
281
  ) -> Response:
285
282
  response = Response(
@@ -309,18 +306,18 @@ class GraphQLRouter(
309
306
  )
310
307
 
311
308
  def is_websocket_request(
312
- self, request: Union[Request, WebSocket]
309
+ self, request: Request | WebSocket
313
310
  ) -> TypeGuard[WebSocket]:
314
311
  return request.scope["type"] == "websocket"
315
312
 
316
- async def pick_websocket_subprotocol(self, request: WebSocket) -> Optional[str]:
313
+ async def pick_websocket_subprotocol(self, request: WebSocket) -> str | None:
317
314
  protocols = request["subprotocols"]
318
315
  intersection = set(protocols) & set(self.protocols)
319
316
  sorted_intersection = sorted(intersection, key=protocols.index)
320
317
  return next(iter(sorted_intersection), None)
321
318
 
322
319
  async def create_websocket_response(
323
- self, request: WebSocket, subprotocol: Optional[str]
320
+ self, request: WebSocket, subprotocol: str | None
324
321
  ) -> WebSocket:
325
322
  await request.accept(subprotocol=subprotocol)
326
323
  return request
@@ -1,16 +1,15 @@
1
1
  from collections.abc import Iterable
2
- from typing import Optional
3
2
 
4
3
  from strawberry.types.arguments import StrawberryArgumentAnnotation
5
4
 
6
5
 
7
6
  def argument(
8
- description: Optional[str] = None,
9
- name: Optional[str] = None,
10
- deprecation_reason: Optional[str] = None,
7
+ description: str | None = None,
8
+ name: str | None = None,
9
+ deprecation_reason: str | None = None,
11
10
  directives: Iterable[object] = (),
12
11
  inaccessible: bool = False,
13
- tags: Optional[Iterable[str]] = (),
12
+ tags: Iterable[str] | None = (),
14
13
  ) -> StrawberryArgumentAnnotation:
15
14
  from strawberry.federation.schema_directives import Inaccessible, Tag
16
15