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,6 +1,6 @@
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
  from strawberry.scalars import is_scalar as is_strawberry_scalar
6
6
  from strawberry.types.base import StrawberryType, has_object_definition
@@ -11,40 +11,40 @@ from strawberry.types.base import StrawberryType, has_object_definition
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from collections.abc import Mapping
14
- from typing_extensions import TypeGuard
14
+ from typing import TypeGuard
15
15
 
16
16
  from strawberry.types.scalar import ScalarDefinition, ScalarWrapper
17
17
 
18
18
 
19
- def is_input_type(type_: Union[StrawberryType, type]) -> TypeGuard[type]:
19
+ def is_input_type(type_: StrawberryType | type) -> TypeGuard[type]:
20
20
  if not has_object_definition(type_):
21
21
  return False
22
22
  return type_.__strawberry_definition__.is_input
23
23
 
24
24
 
25
- def is_interface_type(type_: Union[StrawberryType, type]) -> TypeGuard[type]:
25
+ def is_interface_type(type_: StrawberryType | type) -> TypeGuard[type]:
26
26
  if not has_object_definition(type_):
27
27
  return False
28
28
  return type_.__strawberry_definition__.is_interface
29
29
 
30
30
 
31
31
  def is_scalar(
32
- type_: Union[StrawberryType, type],
33
- scalar_registry: Mapping[object, Union[ScalarWrapper, ScalarDefinition]],
32
+ type_: StrawberryType | type,
33
+ scalar_registry: Mapping[object, ScalarWrapper | ScalarDefinition],
34
34
  ) -> TypeGuard[type]:
35
35
  return is_strawberry_scalar(type_, scalar_registry)
36
36
 
37
37
 
38
- def is_enum(type_: Union[StrawberryType, type]) -> TypeGuard[type]:
38
+ def is_enum(type_: StrawberryType | type) -> TypeGuard[type]:
39
39
  return hasattr(type_, "_enum_definition")
40
40
 
41
41
 
42
- def is_schema_directive(type_: Union[StrawberryType, type]) -> TypeGuard[type]:
42
+ def is_schema_directive(type_: StrawberryType | type) -> TypeGuard[type]:
43
43
  return hasattr(type_, "__strawberry_directive__")
44
44
 
45
45
 
46
46
  # TODO: do we still need this?
47
- def is_graphql_generic(type_: Union[StrawberryType, type]) -> bool:
47
+ def is_graphql_generic(type_: StrawberryType | type) -> bool:
48
48
  if has_object_definition(type_):
49
49
  return type_.__strawberry_definition__.is_graphql_generic
50
50
 
@@ -1,12 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import InitVar, dataclass, field
4
- from typing import Any, Callable, Optional, TypedDict
4
+ from typing import TYPE_CHECKING, Any, TypedDict
5
5
 
6
6
  from strawberry.types.info import Info
7
7
 
8
8
  from .name_converter import NameConverter
9
9
 
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Callable
12
+
10
13
 
11
14
  class BatchingConfig(TypedDict):
12
15
  max_operations: int
@@ -23,7 +26,7 @@ class StrawberryConfig:
23
26
  info_class: type[Info] = Info
24
27
  enable_experimental_incremental_execution: bool = False
25
28
  _unsafe_disable_same_type_validation: bool = False
26
- batching_config: Optional[BatchingConfig] = None
29
+ batching_config: BatchingConfig | None = None
27
30
 
28
31
  def __post_init__(
29
32
  self,
@@ -1,12 +1,10 @@
1
- from typing import Optional
2
-
3
1
  from strawberry.types.graphql import OperationType
4
2
 
5
3
 
6
4
  class CannotGetOperationTypeError(Exception):
7
5
  """Internal error raised when we cannot get the operation type from a GraphQL document."""
8
6
 
9
- def __init__(self, operation_name: Optional[str]) -> None:
7
+ def __init__(self, operation_name: str | None) -> None:
10
8
  self.operation_name = operation_name
11
9
 
12
10
  def as_http_error_reason(self) -> str:
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional, Union, cast
3
+ from typing import TYPE_CHECKING, cast
4
4
  from typing_extensions import Protocol
5
5
 
6
6
  from strawberry.directive import StrawberryDirective
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
26
26
 
27
27
  class HasGraphQLName(Protocol):
28
28
  python_name: str
29
- graphql_name: Optional[str]
29
+ graphql_name: str | None
30
30
 
31
31
 
32
32
  class NameConverter:
@@ -41,7 +41,7 @@ class NameConverter:
41
41
 
42
42
  def from_type(
43
43
  self,
44
- type_: Union[StrawberryType, StrawberryDirective],
44
+ type_: StrawberryType | StrawberryDirective,
45
45
  ) -> str:
46
46
  if isinstance(type_, (StrawberryDirective, StrawberrySchemaDirective)):
47
47
  return self.from_directive(type_)
@@ -85,7 +85,7 @@ class NameConverter:
85
85
  return enum_value.name
86
86
 
87
87
  def from_directive(
88
- self, directive: Union[StrawberryDirective, StrawberrySchemaDirective]
88
+ self, directive: StrawberryDirective | StrawberrySchemaDirective
89
89
  ) -> str:
90
90
  name = self.get_graphql_name(directive)
91
91
 
@@ -134,7 +134,7 @@ class NameConverter:
134
134
  def from_generic(
135
135
  self,
136
136
  generic_type: StrawberryObjectDefinition,
137
- types: list[Union[StrawberryType, type]],
137
+ types: list[StrawberryType | type],
138
138
  ) -> str:
139
139
  generic_type_name = generic_type.name
140
140
 
@@ -146,7 +146,7 @@ class NameConverter:
146
146
 
147
147
  return "".join(names) + generic_type_name
148
148
 
149
- def get_name_from_type(self, type_: Union[StrawberryType, type]) -> str:
149
+ def get_name_from_type(self, type_: StrawberryType | type) -> str:
150
150
  type_ = eval_type(type_)
151
151
 
152
152
  if isinstance(type_, LazyType):
@@ -2,16 +2,13 @@ from __future__ import annotations
2
2
 
3
3
  import warnings
4
4
  from asyncio import ensure_future
5
- from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Iterable
5
+ from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable, Iterable
6
6
  from functools import cached_property, lru_cache
7
7
  from inspect import isawaitable
8
8
  from typing import (
9
9
  TYPE_CHECKING,
10
10
  Any,
11
- Callable,
12
11
  NamedTuple,
13
- Optional,
14
- Union,
15
12
  cast,
16
13
  )
17
14
 
@@ -83,7 +80,7 @@ from .exceptions import CannotGetOperationTypeError, InvalidOperationTypeError
83
80
 
84
81
  if TYPE_CHECKING:
85
82
  from collections.abc import Iterable, Mapping
86
- from typing_extensions import TypeAlias
83
+ from typing import TypeAlias
87
84
 
88
85
  from graphql.language import DocumentNode
89
86
  from graphql.pyutils import Path
@@ -98,13 +95,12 @@ if TYPE_CHECKING:
98
95
  from strawberry.types.union import StrawberryUnion
99
96
 
100
97
  SubscriptionResult: TypeAlias = AsyncGenerator[
101
- Union[PreExecutionError, ExecutionResult], None
98
+ PreExecutionError | ExecutionResult, None
102
99
  ]
103
100
 
104
- OriginSubscriptionResult = Union[
105
- OriginalExecutionResult,
106
- AsyncIterator[OriginalExecutionResult],
107
- ]
101
+ OriginSubscriptionResult: TypeAlias = (
102
+ OriginalExecutionResult | AsyncIterator[OriginalExecutionResult]
103
+ )
108
104
 
109
105
 
110
106
  DEFAULT_ALLOWED_OPERATION_TYPES = {
@@ -113,7 +109,7 @@ DEFAULT_ALLOWED_OPERATION_TYPES = {
113
109
  OperationType.SUBSCRIPTION,
114
110
  }
115
111
  ProcessErrors: TypeAlias = (
116
- "Callable[[list[GraphQLError], Optional[ExecutionContext]], None]"
112
+ "Callable[[list[GraphQLError], ExecutionContext | None], None]"
117
113
  )
118
114
 
119
115
 
@@ -150,7 +146,7 @@ def _run_validation(execution_context: ExecutionContext) -> None:
150
146
  )
151
147
 
152
148
 
153
- def _coerce_error(error: Union[GraphQLError, Exception]) -> GraphQLError:
149
+ def _coerce_error(error: GraphQLError | Exception) -> GraphQLError:
154
150
  if isinstance(error, GraphQLError):
155
151
  return error
156
152
  return GraphQLError(str(error), original_error=error)
@@ -212,16 +208,16 @@ class Schema(BaseSchema):
212
208
  # TODO: can we make sure we only allow to pass
213
209
  # something that has been decorated?
214
210
  query: type,
215
- mutation: Optional[type] = None,
216
- subscription: Optional[type] = None,
211
+ mutation: type | None = None,
212
+ subscription: type | None = None,
217
213
  directives: Iterable[StrawberryDirective] = (),
218
- types: Iterable[Union[type, StrawberryType]] = (),
219
- extensions: Iterable[Union[type[SchemaExtension], SchemaExtension]] = (),
220
- execution_context_class: Optional[type[GraphQLExecutionContext]] = None,
221
- config: Optional[StrawberryConfig] = None,
222
- scalar_overrides: Optional[
223
- Mapping[object, Union[type, ScalarWrapper, ScalarDefinition]],
224
- ] = None,
214
+ types: Iterable[type | StrawberryType] = (),
215
+ extensions: Iterable[type[SchemaExtension] | SchemaExtension] = (),
216
+ execution_context_class: type[GraphQLExecutionContext] | None = None,
217
+ config: StrawberryConfig | None = None,
218
+ scalar_overrides: (
219
+ Mapping[object, type | ScalarWrapper | ScalarDefinition] | None
220
+ ) = None,
225
221
  schema_directives: Iterable[object] = (),
226
222
  ) -> None:
227
223
  """Default Schema to be used in a Strawberry application.
@@ -398,7 +394,7 @@ class Schema(BaseSchema):
398
394
  )
399
395
 
400
396
  def _get_custom_context_kwargs(
401
- self, operation_extensions: Optional[dict[str, Any]] = None
397
+ self, operation_extensions: dict[str, Any] | None = None
402
398
  ) -> dict[str, Any]:
403
399
  if not IS_GQL_33:
404
400
  return {}
@@ -417,13 +413,13 @@ class Schema(BaseSchema):
417
413
 
418
414
  def _create_execution_context(
419
415
  self,
420
- query: Optional[str],
416
+ query: str | None,
421
417
  allowed_operation_types: Iterable[OperationType],
422
- variable_values: Optional[dict[str, Any]] = None,
423
- context_value: Optional[Any] = None,
424
- root_value: Optional[Any] = None,
425
- operation_name: Optional[str] = None,
426
- operation_extensions: Optional[dict[str, Any]] = None,
418
+ variable_values: dict[str, Any] | None = None,
419
+ context_value: Any | None = None,
420
+ root_value: Any | None = None,
421
+ operation_name: str | None = None,
422
+ operation_extensions: dict[str, Any] | None = None,
427
423
  ) -> ExecutionContext:
428
424
  return ExecutionContext(
429
425
  query=query,
@@ -439,14 +435,13 @@ class Schema(BaseSchema):
439
435
  @lru_cache
440
436
  def get_type_by_name(
441
437
  self, name: str
442
- ) -> Optional[
443
- Union[
444
- StrawberryObjectDefinition,
445
- ScalarDefinition,
446
- EnumDefinition,
447
- StrawberryUnion,
448
- ]
449
- ]:
438
+ ) -> (
439
+ StrawberryObjectDefinition
440
+ | ScalarDefinition
441
+ | EnumDefinition
442
+ | StrawberryUnion
443
+ | None
444
+ ):
450
445
  # TODO: respect auto_camel_case
451
446
  if name in self.schema_converter.type_map:
452
447
  return self.schema_converter.type_map[name].definition
@@ -455,7 +450,7 @@ class Schema(BaseSchema):
455
450
 
456
451
  def get_field_for_type(
457
452
  self, field_name: str, type_name: str
458
- ) -> Optional[StrawberryField]:
453
+ ) -> StrawberryField | None:
459
454
  type_ = self.get_type_by_name(type_name)
460
455
 
461
456
  if not type_:
@@ -473,7 +468,7 @@ class Schema(BaseSchema):
473
468
  )
474
469
 
475
470
  @lru_cache
476
- def get_directive_by_name(self, graphql_name: str) -> Optional[StrawberryDirective]:
471
+ def get_directive_by_name(self, graphql_name: str) -> StrawberryDirective | None:
477
472
  return next(
478
473
  (
479
474
  directive
@@ -490,7 +485,7 @@ class Schema(BaseSchema):
490
485
 
491
486
  async def _parse_and_validate_async(
492
487
  self, context: ExecutionContext, extensions_runner: SchemaExtensionsRunner
493
- ) -> Optional[PreExecutionError]:
488
+ ) -> PreExecutionError | None:
494
489
  if not context.query:
495
490
  raise MissingQueryError
496
491
 
@@ -553,13 +548,13 @@ class Schema(BaseSchema):
553
548
 
554
549
  async def execute(
555
550
  self,
556
- query: Optional[str],
557
- variable_values: Optional[dict[str, Any]] = None,
558
- context_value: Optional[Any] = None,
559
- root_value: Optional[Any] = None,
560
- operation_name: Optional[str] = None,
561
- allowed_operation_types: Optional[Iterable[OperationType]] = None,
562
- operation_extensions: Optional[dict[str, Any]] = None,
551
+ query: str | None,
552
+ variable_values: dict[str, Any] | None = None,
553
+ context_value: Any | None = None,
554
+ root_value: Any | None = None,
555
+ operation_name: str | None = None,
556
+ allowed_operation_types: Iterable[OperationType] | None = None,
557
+ operation_extensions: dict[str, Any] | None = None,
563
558
  ) -> ExecutionResult:
564
559
  if allowed_operation_types is None:
565
560
  allowed_operation_types = DEFAULT_ALLOWED_OPERATION_TYPES
@@ -659,13 +654,13 @@ class Schema(BaseSchema):
659
654
 
660
655
  def execute_sync(
661
656
  self,
662
- query: Optional[str],
663
- variable_values: Optional[dict[str, Any]] = None,
664
- context_value: Optional[Any] = None,
665
- root_value: Optional[Any] = None,
666
- operation_name: Optional[str] = None,
667
- allowed_operation_types: Optional[Iterable[OperationType]] = None,
668
- operation_extensions: Optional[dict[str, Any]] = None,
657
+ query: str | None,
658
+ variable_values: dict[str, Any] | None = None,
659
+ context_value: Any | None = None,
660
+ root_value: Any | None = None,
661
+ operation_name: str | None = None,
662
+ allowed_operation_types: Iterable[OperationType] | None = None,
663
+ operation_extensions: dict[str, Any] | None = None,
669
664
  ) -> ExecutionResult:
670
665
  if allowed_operation_types is None:
671
666
  allowed_operation_types = DEFAULT_ALLOWED_OPERATION_TYPES
@@ -805,7 +800,7 @@ class Schema(BaseSchema):
805
800
  extensions_runner: SchemaExtensionsRunner,
806
801
  middleware_manager: MiddlewareManager,
807
802
  execution_context_class: type[GraphQLExecutionContext] | None = None,
808
- operation_extensions: Optional[dict[str, Any]] = None,
803
+ operation_extensions: dict[str, Any] | None = None,
809
804
  ) -> AsyncGenerator[ExecutionResult, None]:
810
805
  async with extensions_runner.operation():
811
806
  if initial_error := await self._parse_and_validate_async(
@@ -884,12 +879,12 @@ class Schema(BaseSchema):
884
879
 
885
880
  async def subscribe(
886
881
  self,
887
- query: Optional[str],
888
- variable_values: Optional[dict[str, Any]] = None,
889
- context_value: Optional[Any] = None,
890
- root_value: Optional[Any] = None,
891
- operation_name: Optional[str] = None,
892
- operation_extensions: Optional[dict[str, Any]] = None,
882
+ query: str | None,
883
+ variable_values: dict[str, Any] | None = None,
884
+ context_value: Any | None = None,
885
+ root_value: Any | None = None,
886
+ operation_name: str | None = None,
887
+ operation_extensions: dict[str, Any] | None = None,
893
888
  ) -> SubscriptionResult:
894
889
  execution_context = self._create_execution_context(
895
890
  query=query,
@@ -2,15 +2,14 @@ from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
4
  import sys
5
+ import typing
5
6
  from functools import partial, reduce
6
7
  from typing import (
7
8
  TYPE_CHECKING,
9
+ Annotated,
8
10
  Any,
9
- Callable,
10
11
  Generic,
11
- Optional,
12
12
  TypeVar,
13
- Union,
14
13
  cast,
15
14
  )
16
15
  from typing_extensions import Protocol
@@ -80,7 +79,7 @@ from . import compat
80
79
  from .types.concrete_type import ConcreteType
81
80
 
82
81
  if TYPE_CHECKING:
83
- from collections.abc import Awaitable, Mapping
82
+ from collections.abc import Awaitable, Callable, Mapping
84
83
 
85
84
  from graphql import (
86
85
  GraphQLInputType,
@@ -100,17 +99,17 @@ if TYPE_CHECKING:
100
99
 
101
100
  FieldType = TypeVar(
102
101
  "FieldType",
103
- bound=Union[GraphQLField, GraphQLInputField],
102
+ bound=GraphQLField | GraphQLInputField,
104
103
  covariant=True,
105
104
  )
106
105
 
107
106
 
108
- class FieldConverterProtocol(Generic[FieldType], Protocol):
107
+ class FieldConverterProtocol(Protocol, Generic[FieldType]):
109
108
  def __call__( # pragma: no cover
110
109
  self,
111
110
  field: StrawberryField,
112
111
  *,
113
- type_definition: Optional[StrawberryObjectDefinition] = None,
112
+ type_definition: StrawberryObjectDefinition | None = None,
114
113
  ) -> FieldType: ...
115
114
 
116
115
 
@@ -180,7 +179,7 @@ class CustomGraphQLEnumType(GraphQLEnumType):
180
179
  return self.wrapped_cls(super().parse_value(input_value))
181
180
 
182
181
  def parse_literal(
183
- self, value_node: ValueNode, _variables: Optional[dict[str, Any]] = None
182
+ self, value_node: ValueNode, _variables: dict[str, Any] | None = None
184
183
  ) -> Any:
185
184
  return self.wrapped_cls(super().parse_literal(value_node, _variables))
186
185
 
@@ -192,7 +191,7 @@ def get_arguments(
192
191
  info: Info,
193
192
  kwargs: Any,
194
193
  config: StrawberryConfig,
195
- scalar_registry: Mapping[object, Union[ScalarWrapper, ScalarDefinition]],
194
+ scalar_registry: Mapping[object, ScalarWrapper | ScalarDefinition],
196
195
  ) -> tuple[list[Any], dict[str, Any]]:
197
196
  # TODO: An extension might have changed the resolver arguments,
198
197
  # but we need them here since we are calling it.
@@ -249,7 +248,7 @@ class GraphQLCoreConverter:
249
248
  def __init__(
250
249
  self,
251
250
  config: StrawberryConfig,
252
- scalar_overrides: Mapping[object, Union[ScalarWrapper, ScalarDefinition]],
251
+ scalar_overrides: Mapping[object, ScalarWrapper | ScalarDefinition],
253
252
  get_fields: Callable[[StrawberryObjectDefinition], list[StrawberryField]],
254
253
  ) -> None:
255
254
  self.type_map: dict[str, ConcreteType] = {}
@@ -259,8 +258,8 @@ class GraphQLCoreConverter:
259
258
 
260
259
  def _get_scalar_registry(
261
260
  self,
262
- scalar_overrides: Mapping[object, Union[ScalarWrapper, ScalarDefinition]],
263
- ) -> Mapping[object, Union[ScalarWrapper, ScalarDefinition]]:
261
+ scalar_overrides: Mapping[object, ScalarWrapper | ScalarDefinition],
262
+ ) -> Mapping[object, ScalarWrapper | ScalarDefinition]:
264
263
  scalar_registry = {**DEFAULT_SCALAR_REGISTRY}
265
264
 
266
265
  global_id_name = "GlobalID" if self.config.relay_use_legacy_global_id else "ID"
@@ -407,7 +406,7 @@ class GraphQLCoreConverter:
407
406
  self,
408
407
  field: StrawberryField,
409
408
  *,
410
- type_definition: Optional[StrawberryObjectDefinition] = None,
409
+ type_definition: StrawberryObjectDefinition | None = None,
411
410
  ) -> GraphQLField:
412
411
  # self.from_resolver needs to be called before accessing field.type because
413
412
  # in there a field extension might want to change the type during its apply
@@ -445,7 +444,7 @@ class GraphQLCoreConverter:
445
444
  self,
446
445
  field: StrawberryField,
447
446
  *,
448
- type_definition: Optional[StrawberryObjectDefinition] = None,
447
+ type_definition: StrawberryObjectDefinition | None = None,
449
448
  ) -> GraphQLInputField:
450
449
  field_type = cast(
451
450
  "GraphQLInputType",
@@ -556,14 +555,14 @@ class GraphQLCoreConverter:
556
555
 
557
556
  def _get_resolve_type() -> Callable[
558
557
  [Any, GraphQLResolveInfo, GraphQLAbstractType],
559
- Union[Awaitable[Optional[str]], str, None],
558
+ Awaitable[str | None] | str | None,
560
559
  ]:
561
560
  if interface.resolve_type:
562
561
  return interface.resolve_type
563
562
 
564
563
  def resolve_type(
565
564
  obj: Any, info: GraphQLResolveInfo, abstract_type: GraphQLAbstractType
566
- ) -> Union[Awaitable[Optional[str]], str, None]:
565
+ ) -> Awaitable[str | None] | str | None:
567
566
  if isinstance(obj, interface.origin):
568
567
  type_definition = get_object_definition(obj, strict=True)
569
568
 
@@ -578,7 +577,7 @@ class GraphQLCoreConverter:
578
577
  # all the types in the schema, but we should probably
579
578
  # optimize this
580
579
 
581
- return_type: Optional[GraphQLType] = None
580
+ return_type: GraphQLType | None = None
582
581
 
583
582
  for possible_concrete_type in self.type_map.values():
584
583
  possible_type = possible_concrete_type.definition
@@ -639,7 +638,7 @@ class GraphQLCoreConverter:
639
638
  assert isinstance(graphql_object_type, GraphQLObjectType) # For mypy
640
639
  return graphql_object_type
641
640
 
642
- def _get_is_type_of() -> Optional[Callable[[Any, GraphQLResolveInfo], bool]]:
641
+ def _get_is_type_of() -> Callable[[Any, GraphQLResolveInfo], bool] | None:
643
642
  if object_type.is_type_of:
644
643
  return object_type.is_type_of
645
644
 
@@ -849,8 +848,8 @@ class GraphQLCoreConverter:
849
848
  return implementation
850
849
 
851
850
  def from_maybe_optional(
852
- self, type_: Union[StrawberryType, type]
853
- ) -> Union[GraphQLNullableType, GraphQLNonNull]:
851
+ self, type_: StrawberryType | type
852
+ ) -> GraphQLNullableType | GraphQLNonNull:
854
853
  NoneType = type(None)
855
854
  if type_ is None or type_ is NoneType:
856
855
  return self.from_type(type_)
@@ -865,10 +864,16 @@ class GraphQLCoreConverter:
865
864
  return self.from_type(type_.of_type)
866
865
  return GraphQLNonNull(self.from_type(type_))
867
866
 
868
- def from_type(self, type_: Union[StrawberryType, type]) -> GraphQLNullableType:
867
+ def from_type(self, type_: StrawberryType | type) -> GraphQLNullableType:
869
868
  if compat.is_graphql_generic(type_):
870
869
  raise MissingTypesForGenericError(type_)
871
870
 
871
+ # to handle lazy unions
872
+ if typing.get_origin(type_) is Annotated:
873
+ args = typing.get_args(type_)
874
+ if len(args) >= 2 and isinstance(args[1], StrawberryUnion):
875
+ type_ = args[1]
876
+
872
877
  if isinstance(type_, EnumDefinition): # TODO: Replace with StrawberryEnum
873
878
  return self.from_enum(type_)
874
879
  if compat.is_input_type(type_): # TODO: Replace with StrawberryInputObject
@@ -952,7 +957,7 @@ class GraphQLCoreConverter:
952
957
  def _get_is_type_of(
953
958
  self,
954
959
  object_type: StrawberryObjectDefinition,
955
- ) -> Optional[Callable[[Any, GraphQLResolveInfo], bool]]:
960
+ ) -> Callable[[Any, GraphQLResolveInfo], bool] | None:
956
961
  if object_type.is_type_of:
957
962
  return object_type.is_type_of
958
963
 
@@ -1,8 +1,8 @@
1
1
  import datetime
2
2
  import decimal
3
3
  import uuid
4
+ from collections.abc import Callable
4
5
  from operator import methodcaller
5
- from typing import Callable
6
6
 
7
7
  import dateutil.parser
8
8
  from graphql import GraphQLError
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
- from typing import TYPE_CHECKING, Union
4
+ from typing import TYPE_CHECKING, TypeAlias
5
5
 
6
6
  from graphql import GraphQLField, GraphQLInputField, GraphQLType
7
7
 
@@ -11,14 +11,14 @@ if TYPE_CHECKING:
11
11
  from strawberry.types.scalar import ScalarDefinition
12
12
  from strawberry.types.union import StrawberryUnion
13
13
 
14
- Field = Union[GraphQLInputField, GraphQLField]
14
+ Field: TypeAlias = GraphQLInputField | GraphQLField
15
15
 
16
16
 
17
17
  @dataclasses.dataclass
18
18
  class ConcreteType:
19
- definition: Union[
20
- StrawberryObjectDefinition, EnumDefinition, ScalarDefinition, StrawberryUnion
21
- ]
19
+ definition: (
20
+ StrawberryObjectDefinition | EnumDefinition | ScalarDefinition | StrawberryUnion
21
+ )
22
22
  implementation: GraphQLType
23
23
 
24
24
 
@@ -4,8 +4,8 @@ import dataclasses
4
4
  import keyword
5
5
  from collections import defaultdict
6
6
  from graphlib import TopologicalSorter
7
- from typing import TYPE_CHECKING, Union
8
- from typing_extensions import Protocol, TypeAlias
7
+ from typing import TYPE_CHECKING, TypeAlias
8
+ from typing_extensions import Protocol
9
9
 
10
10
  import libcst as cst
11
11
  from graphql import (
@@ -256,7 +256,7 @@ def _get_field(
256
256
  )
257
257
 
258
258
 
259
- ArgumentValue: TypeAlias = Union[str, bool, list["ArgumentValue"]]
259
+ ArgumentValue: TypeAlias = str | bool | list["ArgumentValue"]
260
260
 
261
261
 
262
262
  def _get_argument_value(argument_value: ConstValueNode) -> ArgumentValue:
@@ -1,6 +1,7 @@
1
1
  import dataclasses
2
+ from collections.abc import Callable
2
3
  from enum import Enum
3
- from typing import Callable, Optional, TypeVar
4
+ from typing import TypeVar
4
5
  from typing_extensions import dataclass_transform
5
6
 
6
7
  from strawberry.types.field import StrawberryField, field
@@ -27,13 +28,13 @@ class Location(Enum):
27
28
  @dataclasses.dataclass
28
29
  class StrawberrySchemaDirective:
29
30
  python_name: str
30
- graphql_name: Optional[str]
31
+ graphql_name: str | None
31
32
  locations: list[Location]
32
33
  fields: list["StrawberryField"]
33
- description: Optional[str] = None
34
+ description: str | None = None
34
35
  repeatable: bool = False
35
36
  print_definition: bool = True
36
- origin: Optional[type] = None
37
+ origin: type | None = None
37
38
 
38
39
 
39
40
  T = TypeVar("T", bound=type)
@@ -47,8 +48,8 @@ T = TypeVar("T", bound=type)
47
48
  def schema_directive(
48
49
  *,
49
50
  locations: list[Location],
50
- description: Optional[str] = None,
51
- name: Optional[str] = None,
51
+ description: str | None = None,
52
+ name: str | None = None,
52
53
  repeatable: bool = False,
53
54
  print_definition: bool = True,
54
55
  ) -> Callable[[T], T]: