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,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.__dict__.get("__annotations__", {})
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: Optional[str] = None,
119
+ name: str | None = None,
140
120
  is_input: bool = False,
141
121
  is_interface: bool = False,
142
- description: Optional[str] = None,
143
- directives: Optional[Sequence[object]] = (),
122
+ description: str | None = None,
123
+ directives: Sequence[object] | None = (),
144
124
  extend: bool = False,
145
- original_type_annotations: Optional[dict[str, Any]] = None,
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: Optional[str] = None,
191
+ name: str | None = None,
212
192
  is_input: bool = False,
213
193
  is_interface: bool = False,
214
- description: Optional[str] = None,
215
- directives: Optional[Sequence[object]] = (),
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: Optional[str] = None,
206
+ name: str | None = None,
227
207
  is_input: bool = False,
228
208
  is_interface: bool = False,
229
- description: Optional[str] = None,
230
- directives: Optional[Sequence[object]] = (),
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: Optional[T] = None,
216
+ cls: T | None = None,
237
217
  *,
238
- name: Optional[str] = None,
218
+ name: str | None = None,
239
219
  is_input: bool = False,
240
220
  is_interface: bool = False,
241
- description: Optional[str] = None,
242
- directives: Optional[Sequence[object]] = (),
221
+ description: str | None = None,
222
+ directives: Sequence[object] | None = (),
243
223
  extend: bool = False,
244
- ) -> Union[T, Callable[[T], T]]:
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: Optional[str] = None,
334
- one_of: Optional[bool] = None,
335
- description: Optional[str] = None,
336
- directives: Optional[Sequence[object]] = (),
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: Optional[str] = None,
347
- one_of: Optional[bool] = None,
348
- description: Optional[str] = None,
349
- directives: Optional[Sequence[object]] = (),
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: Optional[T] = None,
334
+ cls: T | None = None,
355
335
  *,
356
- name: Optional[str] = None,
357
- one_of: Optional[bool] = None,
358
- description: Optional[str] = None,
359
- directives: Optional[Sequence[object]] = (),
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: Optional[str] = None,
413
- description: Optional[str] = None,
414
- directives: Optional[Sequence[object]] = (),
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: Optional[str] = None,
425
- description: Optional[str] = None,
426
- directives: Optional[Sequence[object]] = (),
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: Optional[T] = None,
414
+ cls: T | None = None,
435
415
  *,
436
- name: Optional[str] = None,
437
- description: Optional[str] = None,
438
- directives: Optional[Sequence[object]] = (),
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
 
@@ -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
- # in python 3.10+ NewType is a class
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: Optional[str]
41
- specified_by_url: Optional[str]
42
- serialize: Optional[Callable]
43
- parse_value: Optional[Callable]
44
- parse_literal: Optional[Callable]
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: Optional[GraphQLScalarType | type] = None
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: Optional[GraphQLScalarType] = None
44
+ implementation: GraphQLScalarType | None = None
51
45
 
52
46
  # used for better error messages
53
- _source_file: Optional[str] = None
54
- _source_line: Optional[int] = None
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, Union[StrawberryType, type]]
58
- ) -> Union[StrawberryType, type]:
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: Union[StrawberryType, type]) -> StrawberryType:
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: Optional[str] = None,
90
- description: Optional[str] = None,
91
- specified_by_url: Optional[str] = None,
92
- serialize: Optional[Callable] = None,
93
- parse_value: Optional[Callable] = None,
94
- parse_literal: Optional[Callable] = None,
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: Optional[str] = None,
131
- description: Optional[str] = None,
132
- specified_by_url: Optional[str] = None,
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: Optional[Callable] = None,
135
- parse_literal: Optional[Callable] = None,
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: Optional[str] = None,
145
- description: Optional[str] = None,
146
- specified_by_url: Optional[str] = None,
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: Optional[Callable] = None,
149
- parse_literal: Optional[Callable] = None,
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: Optional[_T] = None,
152
+ cls: _T | None = None,
159
153
  *,
160
- name: Optional[str] = None,
161
- description: Optional[str] = None,
162
- specified_by_url: Optional[str] = None,
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: Optional[Callable] = None,
165
- parse_literal: Optional[Callable] = None,
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: Optional[str] = None
52
- _source_line: Optional[int] = None
49
+ _source_file: str | None = None
50
+ _source_line: int | None = None
53
51
 
54
52
  def __init__(
55
53
  self,
56
- name: Optional[str] = None,
54
+ name: str | None = None,
57
55
  type_annotations: tuple[StrawberryAnnotation, ...] = (),
58
- description: Optional[str] = None,
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: Optional[StrawberryUnion] = None
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: Union[StrawberryType, type]) -> StrawberryType:
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, Union[StrawberryType, type]]
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: Union[StrawberryType, 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: Optional[GraphQLType]
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: Optional[Collection[type[Any]]] = None,
243
+ types: Collection[type[Any]] | None = None,
246
244
  *,
247
- description: Optional[str] = None,
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 AsyncGenerator, AsyncIterable, AsyncIterator, Awaitable
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: Union[AsyncIterator[_T], AsyncIterable[_T]],
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: Union[AsyncIterator[_T], AsyncIterable[_T]],
44
- start: Optional[int] = None,
45
- stop: Optional[int] = None,
46
- step: Optional[int] = None,
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
@@ -1,11 +1,11 @@
1
1
  import inspect
2
2
  from collections.abc import AsyncIterator, Awaitable, Iterator
3
- from typing import TypeVar, Union
3
+ from typing import TypeAlias, TypeVar
4
4
 
5
5
  T = TypeVar("T")
6
6
 
7
- AwaitableOrValue = Union[Awaitable[T], T]
8
- AsyncIteratorOrIterator = Union[AsyncIterator[T], Iterator[T]]
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:
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import warnings
4
- from typing import Any, Optional
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: Optional[object], type: Optional[type] = None) -> Any:
22
+ def __get__(self, obj: object | None, type: type | None = None) -> Any:
23
23
  self.warn()
24
24
  return self.alias
25
25
 
@@ -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: Optional[str] = None
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)
@@ -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) -> Optional[dict[str, 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, Union[TypeVar, type]] = {}
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:
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import TYPE_CHECKING, Any, Optional
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: Optional[ExecutionContext] = None,
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:
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
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
- ) -> Optional[OperationDefinitionNode]:
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: Optional[str] = None
24
+ graphql_document: DocumentNode, operation_name: str | None = None
25
25
  ) -> OperationType:
26
- definition: Optional[OperationDefinitionNode] = None
26
+ definition: OperationDefinitionNode | None = None
27
27
 
28
28
  if operation_name is not None:
29
29
  for d in graphql_document.definitions: