strawberry-graphql 0.257.0.dev1735244504__py3-none-any.whl → 0.258.0__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.
Files changed (76) hide show
  1. strawberry/__init__.py +2 -0
  2. strawberry/aiohttp/test/client.py +1 -3
  3. strawberry/aiohttp/views.py +3 -3
  4. strawberry/annotation.py +5 -7
  5. strawberry/asgi/__init__.py +4 -4
  6. strawberry/channels/handlers/ws_handler.py +3 -3
  7. strawberry/channels/testing.py +3 -1
  8. strawberry/cli/__init__.py +7 -5
  9. strawberry/cli/commands/codegen.py +12 -14
  10. strawberry/cli/commands/server.py +2 -2
  11. strawberry/cli/commands/upgrade/_run_codemod.py +2 -3
  12. strawberry/cli/utils/__init__.py +1 -1
  13. strawberry/codegen/plugins/python.py +4 -5
  14. strawberry/codegen/plugins/typescript.py +3 -2
  15. strawberry/codegen/query_codegen.py +12 -11
  16. strawberry/codemods/annotated_unions.py +1 -1
  17. strawberry/codemods/update_imports.py +2 -4
  18. strawberry/dataloader.py +2 -2
  19. strawberry/django/__init__.py +2 -2
  20. strawberry/django/views.py +2 -3
  21. strawberry/exceptions/__init__.py +4 -2
  22. strawberry/exceptions/exception.py +1 -1
  23. strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -1
  24. strawberry/exceptions/utils/source_finder.py +1 -1
  25. strawberry/experimental/pydantic/_compat.py +4 -4
  26. strawberry/experimental/pydantic/conversion.py +4 -5
  27. strawberry/experimental/pydantic/fields.py +1 -2
  28. strawberry/experimental/pydantic/object_type.py +6 -2
  29. strawberry/experimental/pydantic/utils.py +3 -9
  30. strawberry/ext/mypy_plugin.py +7 -14
  31. strawberry/extensions/context.py +15 -19
  32. strawberry/extensions/field_extension.py +53 -54
  33. strawberry/extensions/query_depth_limiter.py +27 -33
  34. strawberry/extensions/tracing/datadog.py +1 -1
  35. strawberry/extensions/tracing/opentelemetry.py +9 -14
  36. strawberry/fastapi/router.py +2 -3
  37. strawberry/federation/schema.py +3 -3
  38. strawberry/flask/views.py +3 -2
  39. strawberry/http/async_base_view.py +2 -4
  40. strawberry/http/ides.py +1 -3
  41. strawberry/http/sync_base_view.py +1 -2
  42. strawberry/litestar/controller.py +6 -5
  43. strawberry/permission.py +1 -1
  44. strawberry/quart/views.py +2 -2
  45. strawberry/relay/fields.py +38 -4
  46. strawberry/relay/types.py +6 -1
  47. strawberry/relay/utils.py +6 -1
  48. strawberry/schema/base.py +0 -2
  49. strawberry/schema/execute.py +11 -11
  50. strawberry/schema/name_converter.py +4 -5
  51. strawberry/schema/schema.py +6 -4
  52. strawberry/schema/schema_converter.py +24 -19
  53. strawberry/schema/subscribe.py +4 -4
  54. strawberry/schema/types/base_scalars.py +4 -2
  55. strawberry/schema/types/scalar.py +1 -1
  56. strawberry/schema_codegen/__init__.py +5 -6
  57. strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +2 -2
  58. strawberry/subscriptions/protocols/graphql_ws/handlers.py +0 -3
  59. strawberry/test/client.py +1 -2
  60. strawberry/types/arguments.py +2 -2
  61. strawberry/types/auto.py +3 -3
  62. strawberry/types/base.py +12 -16
  63. strawberry/types/cast.py +35 -0
  64. strawberry/types/field.py +11 -7
  65. strawberry/types/fields/resolver.py +12 -19
  66. strawberry/types/union.py +1 -1
  67. strawberry/types/unset.py +1 -2
  68. strawberry/utils/debug.py +1 -1
  69. strawberry/utils/deprecations.py +1 -1
  70. strawberry/utils/graphql_lexer.py +6 -4
  71. strawberry/utils/typing.py +1 -2
  72. {strawberry_graphql-0.257.0.dev1735244504.dist-info → strawberry_graphql-0.258.0.dist-info}/METADATA +3 -3
  73. {strawberry_graphql-0.257.0.dev1735244504.dist-info → strawberry_graphql-0.258.0.dist-info}/RECORD +76 -75
  74. {strawberry_graphql-0.257.0.dev1735244504.dist-info → strawberry_graphql-0.258.0.dist-info}/WHEEL +1 -1
  75. {strawberry_graphql-0.257.0.dev1735244504.dist-info → strawberry_graphql-0.258.0.dist-info}/LICENSE +0 -0
  76. {strawberry_graphql-0.257.0.dev1735244504.dist-info → strawberry_graphql-0.258.0.dist-info}/entry_points.txt +0 -0
@@ -37,6 +37,7 @@ from strawberry.relay.exceptions import (
37
37
  )
38
38
  from strawberry.types.arguments import StrawberryArgument, argument
39
39
  from strawberry.types.base import StrawberryList, StrawberryOptional
40
+ from strawberry.types.cast import cast as strawberry_cast
40
41
  from strawberry.types.field import _RESOLVER_TYPE, StrawberryField, field
41
42
  from strawberry.types.fields.resolver import StrawberryResolver
42
43
  from strawberry.types.lazy_type import LazyType
@@ -88,12 +89,27 @@ class NodeExtension(FieldExtension):
88
89
  info: Info,
89
90
  id: Annotated[GlobalID, argument(description="The ID of the object.")],
90
91
  ) -> Union[Node, None, Awaitable[Union[Node, None]]]:
91
- return id.resolve_type(info).resolve_node(
92
+ node_type = id.resolve_type(info)
93
+ resolved_node = node_type.resolve_node(
92
94
  id.node_id,
93
95
  info=info,
94
96
  required=not is_optional,
95
97
  )
96
98
 
99
+ # We are using `strawberry_cast` here to cast the resolved node to make
100
+ # sure `is_type_of` will not try to find its type again. Very important
101
+ # when returning a non type (e.g. Django/SQLAlchemy/Pydantic model), as
102
+ # we could end up resolving to a different type in case more than one
103
+ # are registered.
104
+ if inspect.isawaitable(resolved_node):
105
+
106
+ async def resolve() -> Any:
107
+ return strawberry_cast(node_type, await resolved_node)
108
+
109
+ return resolve()
110
+
111
+ return cast(Node, strawberry_cast(node_type, resolved_node))
112
+
97
113
  return resolver
98
114
 
99
115
  def get_node_list_resolver(
@@ -139,6 +155,14 @@ class NodeExtension(FieldExtension):
139
155
  if inspect.isasyncgen(nodes)
140
156
  }
141
157
 
158
+ # We are using `strawberry_cast` here to cast the resolved node to make
159
+ # sure `is_type_of` will not try to find its type again. Very important
160
+ # when returning a non type (e.g. Django/SQLAlchemy/Pydantic model), as
161
+ # we could end up resolving to a different type in case more than one
162
+ # are registered
163
+ def cast_nodes(node_t: type[Node], nodes: Iterable[Any]) -> list[Node]:
164
+ return [cast(Node, strawberry_cast(node_t, node)) for node in nodes]
165
+
142
166
  if awaitable_nodes or asyncgen_nodes:
143
167
 
144
168
  async def resolve(resolved: Any = resolved_nodes) -> list[Node]:
@@ -161,7 +185,8 @@ class NodeExtension(FieldExtension):
161
185
 
162
186
  # Resolve any generator to lists
163
187
  resolved = {
164
- node_t: list(nodes) for node_t, nodes in resolved.items()
188
+ node_t: cast_nodes(node_t, nodes)
189
+ for node_t, nodes in resolved.items()
165
190
  }
166
191
  return [
167
192
  resolved[index_map[gid][0]][index_map[gid][1]] for gid in ids
@@ -171,7 +196,7 @@ class NodeExtension(FieldExtension):
171
196
 
172
197
  # Resolve any generator to lists
173
198
  resolved = {
174
- node_t: list(cast(Iterator[Node], nodes))
199
+ node_t: cast_nodes(node_t, cast(Iterable[Node], nodes))
175
200
  for node_t, nodes in resolved_nodes.items()
176
201
  }
177
202
  return [resolved[index_map[gid][0]][index_map[gid][1]] for gid in ids]
@@ -182,6 +207,9 @@ class NodeExtension(FieldExtension):
182
207
  class ConnectionExtension(FieldExtension):
183
208
  connection_type: type[Connection[Node]]
184
209
 
210
+ def __init__(self, max_results: Optional[int] = None) -> None:
211
+ self.max_results = max_results
212
+
185
213
  def apply(self, field: StrawberryField) -> None:
186
214
  field.arguments = [
187
215
  *field.arguments,
@@ -288,6 +316,7 @@ class ConnectionExtension(FieldExtension):
288
316
  after=after,
289
317
  first=first,
290
318
  last=last,
319
+ max_results=self.max_results,
291
320
  )
292
321
 
293
322
  async def resolve_async(
@@ -316,6 +345,7 @@ class ConnectionExtension(FieldExtension):
316
345
  after=after,
317
346
  first=first,
318
347
  last=last,
348
+ max_results=self.max_results,
319
349
  )
320
350
 
321
351
  # If nodes was an AsyncIterable/AsyncIterator, resolve_connection
@@ -357,6 +387,7 @@ def connection(
357
387
  metadata: Optional[Mapping[Any, Any]] = None,
358
388
  directives: Optional[Sequence[object]] = (),
359
389
  extensions: list[FieldExtension] = (), # type: ignore
390
+ max_results: Optional[int] = None,
360
391
  # This init parameter is used by pyright to determine whether this field
361
392
  # is added in the constructor or not. It is not used to change
362
393
  # any behaviour at the moment.
@@ -389,6 +420,9 @@ def connection(
389
420
  metadata: The metadata of the field.
390
421
  directives: The directives to apply to the field.
391
422
  extensions: The extensions to apply to the field.
423
+ max_results: The maximum number of results this connection can return.
424
+ Can be set to override the default value of 100 defined in the
425
+ schema configuration.
392
426
  init: Used only for type checking purposes.
393
427
 
394
428
  Examples:
@@ -451,7 +485,7 @@ def connection(
451
485
  default_factory=default_factory,
452
486
  metadata=metadata,
453
487
  directives=directives or (),
454
- extensions=[*extensions, ConnectionExtension()],
488
+ extensions=[*extensions, ConnectionExtension(max_results=max_results)],
455
489
  )
456
490
  if resolver is not None:
457
491
  f = f(resolver)
strawberry/relay/types.py CHANGED
@@ -717,6 +717,7 @@ class Connection(Generic[NodeType]):
717
717
  after: Optional[str] = None,
718
718
  first: Optional[int] = None,
719
719
  last: Optional[int] = None,
720
+ max_results: Optional[int] = None,
720
721
  **kwargs: Any,
721
722
  ) -> AwaitableOrValue[Self]:
722
723
  """Resolve a connection from nodes.
@@ -731,6 +732,7 @@ class Connection(Generic[NodeType]):
731
732
  after: Returns the items in the list that come after the specified cursor.
732
733
  first: Returns the first n items from the list.
733
734
  last: Returns the items in the list that come after the specified cursor.
735
+ max_results: The maximum number of results to resolve.
734
736
  kwargs: Additional arguments passed to the resolver.
735
737
 
736
738
  Returns:
@@ -758,7 +760,7 @@ class ListConnection(Connection[NodeType]):
758
760
  )
759
761
 
760
762
  @classmethod
761
- def resolve_connection(
763
+ def resolve_connection( # noqa: PLR0915
762
764
  cls,
763
765
  nodes: NodeIterableType[NodeType],
764
766
  *,
@@ -767,6 +769,7 @@ class ListConnection(Connection[NodeType]):
767
769
  after: Optional[str] = None,
768
770
  first: Optional[int] = None,
769
771
  last: Optional[int] = None,
772
+ max_results: Optional[int] = None,
770
773
  **kwargs: Any,
771
774
  ) -> AwaitableOrValue[Self]:
772
775
  """Resolve a connection from the list of nodes.
@@ -780,6 +783,7 @@ class ListConnection(Connection[NodeType]):
780
783
  after: Returns the items in the list that come after the specified cursor.
781
784
  first: Returns the first n items from the list.
782
785
  last: Returns the items in the list that come after the specified cursor.
786
+ max_results: The maximum number of results to resolve.
783
787
  kwargs: Additional arguments passed to the resolver.
784
788
 
785
789
  Returns:
@@ -794,6 +798,7 @@ class ListConnection(Connection[NodeType]):
794
798
  after=after,
795
799
  first=first,
796
800
  last=last,
801
+ max_results=max_results,
797
802
  )
798
803
 
799
804
  type_def = get_object_definition(cls)
strawberry/relay/utils.py CHANGED
@@ -131,11 +131,16 @@ class SliceMetadata:
131
131
  after: str | None = None,
132
132
  first: int | None = None,
133
133
  last: int | None = None,
134
+ max_results: int | None = None,
134
135
  ) -> Self:
135
136
  """Get the slice metadata to use on ListConnection."""
136
137
  from strawberry.relay.types import PREFIX
137
138
 
138
- max_results = info.schema.config.relay_max_results
139
+ max_results = (
140
+ max_results
141
+ if max_results is not None
142
+ else info.schema.config.relay_max_results
143
+ )
139
144
  start = 0
140
145
  end: int | None = None
141
146
 
strawberry/schema/base.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from abc import abstractmethod
4
- from functools import lru_cache
5
4
  from typing import TYPE_CHECKING, Any, Optional, Union
6
5
  from typing_extensions import Protocol
7
6
 
@@ -88,7 +87,6 @@ class BaseSchema(Protocol):
88
87
  raise NotImplementedError
89
88
 
90
89
  @abstractmethod
91
- @lru_cache
92
90
  def get_directive_by_name(self, graphql_name: str) -> Optional[StrawberryDirective]:
93
91
  raise NotImplementedError
94
92
 
@@ -85,7 +85,7 @@ async def _parse_and_validate_async(
85
85
  context: ExecutionContext, extensions_runner: SchemaExtensionsRunner
86
86
  ) -> Optional[PreExecutionError]:
87
87
  if not context.query:
88
- raise MissingQueryError()
88
+ raise MissingQueryError
89
89
 
90
90
  async with extensions_runner.parsing():
91
91
  try:
@@ -96,7 +96,7 @@ async def _parse_and_validate_async(
96
96
  context.errors = [error]
97
97
  return PreExecutionError(data=None, errors=[error])
98
98
 
99
- except Exception as error:
99
+ except Exception as error: # noqa: BLE001
100
100
  error = GraphQLError(str(error), original_error=error)
101
101
  context.errors = [error]
102
102
  return PreExecutionError(data=None, errors=[error])
@@ -189,9 +189,9 @@ async def execute(
189
189
  # only return a sanitised version to the client.
190
190
  process_errors(result.errors, execution_context)
191
191
 
192
- except (MissingQueryError, InvalidOperationTypeError) as e:
193
- raise e
194
- except Exception as exc:
192
+ except (MissingQueryError, InvalidOperationTypeError):
193
+ raise
194
+ except Exception as exc: # noqa: BLE001
195
195
  return await _handle_execution_result(
196
196
  execution_context,
197
197
  PreExecutionError(data=None, errors=[_coerce_error(exc)]),
@@ -219,7 +219,7 @@ def execute_sync(
219
219
  # Note: In graphql-core the schema would be validated here but in
220
220
  # Strawberry we are validating it at initialisation time instead
221
221
  if not execution_context.query:
222
- raise MissingQueryError()
222
+ raise MissingQueryError # noqa: TRY301
223
223
 
224
224
  with extensions_runner.parsing():
225
225
  try:
@@ -238,7 +238,7 @@ def execute_sync(
238
238
  )
239
239
 
240
240
  if execution_context.operation_type not in allowed_operation_types:
241
- raise InvalidOperationTypeError(execution_context.operation_type)
241
+ raise InvalidOperationTypeError(execution_context.operation_type) # noqa: TRY301
242
242
 
243
243
  with extensions_runner.validation():
244
244
  _run_validation(execution_context)
@@ -266,7 +266,7 @@ def execute_sync(
266
266
  if isawaitable(result):
267
267
  result = cast(Awaitable[GraphQLExecutionResult], result) # type: ignore[redundant-cast]
268
268
  ensure_future(result).cancel()
269
- raise RuntimeError(
269
+ raise RuntimeError( # noqa: TRY301
270
270
  "GraphQL execution failed to complete synchronously."
271
271
  )
272
272
 
@@ -282,9 +282,9 @@ def execute_sync(
282
282
  # extension). That way we can log the original errors but
283
283
  # only return a sanitised version to the client.
284
284
  process_errors(result.errors, execution_context)
285
- except (MissingQueryError, InvalidOperationTypeError) as e:
286
- raise e
287
- except Exception as exc:
285
+ except (MissingQueryError, InvalidOperationTypeError):
286
+ raise
287
+ except Exception as exc: # noqa: BLE001
288
288
  errors = [_coerce_error(exc)]
289
289
  execution_context.errors = errors
290
290
  process_errors(errors, execution_context)
@@ -47,18 +47,17 @@ class NameConverter:
47
47
  return self.from_directive(type_)
48
48
  if isinstance(type_, EnumDefinition): # TODO: Replace with StrawberryEnum
49
49
  return self.from_enum(type_)
50
- elif isinstance(type_, StrawberryObjectDefinition):
50
+ if isinstance(type_, StrawberryObjectDefinition):
51
51
  if type_.is_input:
52
52
  return self.from_input_object(type_)
53
53
  if type_.is_interface:
54
54
  return self.from_interface(type_)
55
55
  return self.from_object(type_)
56
- elif isinstance(type_, StrawberryUnion):
56
+ if isinstance(type_, StrawberryUnion):
57
57
  return self.from_union(type_)
58
- elif isinstance(type_, ScalarDefinition): # TODO: Replace with StrawberryScalar
58
+ if isinstance(type_, ScalarDefinition): # TODO: Replace with StrawberryScalar
59
59
  return self.from_scalar(type_)
60
- else:
61
- return str(type_)
60
+ return str(type_)
62
61
 
63
62
  def from_argument(self, argument: StrawberryArgument) -> str:
64
63
  return self.get_graphql_name(argument)
@@ -30,6 +30,7 @@ from strawberry.extensions.directives import (
30
30
  DirectivesExtensionSync,
31
31
  )
32
32
  from strawberry.extensions.runner import SchemaExtensionsRunner
33
+ from strawberry.printer import print_schema
33
34
  from strawberry.schema.schema_converter import GraphQLCoreConverter
34
35
  from strawberry.schema.types.scalar import DEFAULT_SCALAR_REGISTRY
35
36
  from strawberry.types import ExecutionContext
@@ -40,7 +41,6 @@ from strawberry.types.base import (
40
41
  )
41
42
  from strawberry.types.graphql import OperationType
42
43
 
43
- from ..printer import print_schema
44
44
  from . import compat
45
45
  from .base import BaseSchema
46
46
  from .config import StrawberryConfig
@@ -177,9 +177,11 @@ class Schema(BaseSchema):
177
177
  self.schema_converter.from_schema_directive(type_)
178
178
  )
179
179
  else:
180
- if has_object_definition(type_):
181
- if type_.__strawberry_definition__.is_graphql_generic:
182
- type_ = StrawberryAnnotation(type_).resolve() # noqa: PLW2901
180
+ if (
181
+ has_object_definition(type_)
182
+ and type_.__strawberry_definition__.is_graphql_generic
183
+ ):
184
+ type_ = StrawberryAnnotation(type_).resolve() # noqa: PLW2901
183
185
  graphql_type = self.schema_converter.from_maybe_optional(type_)
184
186
  if isinstance(graphql_type, GraphQLNonNull):
185
187
  graphql_type = graphql_type.of_type
@@ -47,6 +47,7 @@ from strawberry.exceptions import (
47
47
  ScalarAlreadyRegisteredError,
48
48
  UnresolvedFieldTypeError,
49
49
  )
50
+ from strawberry.extensions.field_extension import build_field_extension_resolvers
50
51
  from strawberry.schema.types.scalar import _make_scalar_type
51
52
  from strawberry.types.arguments import StrawberryArgument, convert_arguments
52
53
  from strawberry.types.base import (
@@ -57,6 +58,7 @@ from strawberry.types.base import (
57
58
  get_object_definition,
58
59
  has_object_definition,
59
60
  )
61
+ from strawberry.types.cast import get_strawberry_type_cast
60
62
  from strawberry.types.enum import EnumDefinition
61
63
  from strawberry.types.field import UNRESOLVED
62
64
  from strawberry.types.lazy_type import LazyType
@@ -66,7 +68,6 @@ from strawberry.types.union import StrawberryUnion
66
68
  from strawberry.types.unset import UNSET
67
69
  from strawberry.utils.await_maybe import await_maybe
68
70
 
69
- from ..extensions.field_extension import build_field_extension_resolvers
70
71
  from . import compat
71
72
  from .types.concrete_type import ConcreteType
72
73
 
@@ -91,7 +92,9 @@ if TYPE_CHECKING:
91
92
 
92
93
 
93
94
  FieldType = TypeVar(
94
- "FieldType", bound=Union[GraphQLField, GraphQLInputField], covariant=True
95
+ "FieldType",
96
+ bound=Union[GraphQLField, GraphQLInputField],
97
+ covariant=True,
95
98
  )
96
99
 
97
100
 
@@ -374,8 +377,6 @@ class GraphQLCoreConverter:
374
377
  # self.from_resolver needs to be called before accessing field.type because
375
378
  # in there a field extension might want to change the type during its apply
376
379
  resolver = self.from_resolver(field)
377
- # TODO: think more about this
378
- field._resolver = resolver # type: ignore
379
380
  field_type = cast(
380
381
  "GraphQLOutputType",
381
382
  self.from_maybe_optional(
@@ -619,6 +620,9 @@ class GraphQLCoreConverter:
619
620
  )
620
621
 
621
622
  def is_type_of(obj: Any, _info: GraphQLResolveInfo) -> bool:
623
+ if (type_cast := get_strawberry_type_cast(obj)) is not None:
624
+ return type_cast in possible_types
625
+
622
626
  if object_type.concrete_of and (
623
627
  has_object_definition(obj)
624
628
  and obj.__strawberry_definition__.origin
@@ -758,9 +762,8 @@ class GraphQLCoreConverter:
758
762
  if field.is_async:
759
763
  _async_resolver._is_default = not field.base_resolver # type: ignore
760
764
  return _async_resolver
761
- else:
762
- _resolver._is_default = not field.base_resolver # type: ignore
763
- return _resolver
765
+ _resolver._is_default = not field.base_resolver # type: ignore
766
+ return _resolver
764
767
 
765
768
  def from_scalar(self, scalar: type) -> GraphQLScalarType:
766
769
  scalar_definition: ScalarDefinition
@@ -810,10 +813,9 @@ class GraphQLCoreConverter:
810
813
  NoneType = type(None)
811
814
  if type_ is None or type_ is NoneType:
812
815
  return self.from_type(type_)
813
- elif isinstance(type_, StrawberryOptional):
816
+ if isinstance(type_, StrawberryOptional):
814
817
  return self.from_type(type_.of_type)
815
- else:
816
- return GraphQLNonNull(self.from_type(type_))
818
+ return GraphQLNonNull(self.from_type(type_))
817
819
 
818
820
  def from_type(self, type_: Union[StrawberryType, type]) -> GraphQLNullableType:
819
821
  if compat.is_graphql_generic(type_):
@@ -821,27 +823,27 @@ class GraphQLCoreConverter:
821
823
 
822
824
  if isinstance(type_, EnumDefinition): # TODO: Replace with StrawberryEnum
823
825
  return self.from_enum(type_)
824
- elif compat.is_input_type(type_): # TODO: Replace with StrawberryInputObject
826
+ if compat.is_input_type(type_): # TODO: Replace with StrawberryInputObject
825
827
  return self.from_input_object(type_)
826
- elif isinstance(type_, StrawberryList):
828
+ if isinstance(type_, StrawberryList):
827
829
  return self.from_list(type_)
828
- elif compat.is_interface_type(type_): # TODO: Replace with StrawberryInterface
830
+ if compat.is_interface_type(type_): # TODO: Replace with StrawberryInterface
829
831
  type_definition: StrawberryObjectDefinition = (
830
832
  type_.__strawberry_definition__ # type: ignore
831
833
  )
832
834
  return self.from_interface(type_definition)
833
- elif has_object_definition(type_):
835
+ if has_object_definition(type_):
834
836
  return self.from_object(type_.__strawberry_definition__)
835
- elif compat.is_enum(type_): # TODO: Replace with StrawberryEnum
837
+ if compat.is_enum(type_): # TODO: Replace with StrawberryEnum
836
838
  enum_definition: EnumDefinition = type_._enum_definition # type: ignore
837
839
  return self.from_enum(enum_definition)
838
- elif isinstance(type_, StrawberryObjectDefinition):
840
+ if isinstance(type_, StrawberryObjectDefinition):
839
841
  return self.from_object(type_)
840
- elif isinstance(type_, StrawberryUnion):
842
+ if isinstance(type_, StrawberryUnion):
841
843
  return self.from_union(type_)
842
- elif isinstance(type_, LazyType):
844
+ if isinstance(type_, LazyType):
843
845
  return self.from_type(type_.resolve_type())
844
- elif compat.is_scalar(
846
+ if compat.is_scalar(
845
847
  type_, self.scalar_registry
846
848
  ): # TODO: Replace with StrawberryScalar
847
849
  return self.from_scalar(type_)
@@ -900,6 +902,9 @@ class GraphQLCoreConverter:
900
902
  if object_type.interfaces:
901
903
 
902
904
  def is_type_of(obj: Any, _info: GraphQLResolveInfo) -> bool:
905
+ if (type_cast := get_strawberry_type_cast(obj)) is not None:
906
+ return type_cast is object_type.origin
907
+
903
908
  if object_type.concrete_of and (
904
909
  has_object_definition(obj)
905
910
  and obj.__strawberry_definition__.origin
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
27
27
  from graphql.execution.middleware import MiddlewareManager
28
28
  from graphql.type.schema import GraphQLSchema
29
29
 
30
- from ..extensions.runner import SchemaExtensionsRunner
30
+ from strawberry.extensions.runner import SchemaExtensionsRunner
31
31
 
32
32
  SubscriptionResult: TypeAlias = Union[
33
33
  PreExecutionError, AsyncGenerator[ExecutionResult, None]
@@ -80,7 +80,7 @@ async def _subscribe(
80
80
  )
81
81
  # graphql-core 3.2 doesn't handle some of the pre-execution errors.
82
82
  # see `test_subscription_immediate_error`
83
- except Exception as exc:
83
+ except Exception as exc: # noqa: BLE001
84
84
  aiter_or_result = OriginalExecutionResult(
85
85
  data=None, errors=[_coerce_error(exc)]
86
86
  )
@@ -103,7 +103,7 @@ async def _subscribe(
103
103
  process_errors,
104
104
  )
105
105
  # graphql-core doesn't handle exceptions raised while executing.
106
- except Exception as exc:
106
+ except Exception as exc: # noqa: BLE001
107
107
  yield await _handle_execution_result(
108
108
  execution_context,
109
109
  OriginalExecutionResult(data=None, errors=[_coerce_error(exc)]),
@@ -111,7 +111,7 @@ async def _subscribe(
111
111
  process_errors,
112
112
  )
113
113
  # catch exceptions raised in `on_execute` hook.
114
- except Exception as exc:
114
+ except Exception as exc: # noqa: BLE001
115
115
  origin_result = OriginalExecutionResult(
116
116
  data=None, errors=[_coerce_error(exc)]
117
117
  )
@@ -15,7 +15,9 @@ def wrap_parser(parser: Callable, type_: str) -> Callable:
15
15
  try:
16
16
  return parser(value)
17
17
  except ValueError as e:
18
- raise GraphQLError(f'Value cannot represent a {type_}: "{value}". {e}')
18
+ raise GraphQLError( # noqa: B904
19
+ f'Value cannot represent a {type_}: "{value}". {e}'
20
+ )
19
21
 
20
22
  return inner
21
23
 
@@ -24,7 +26,7 @@ def parse_decimal(value: object) -> decimal.Decimal:
24
26
  try:
25
27
  return decimal.Decimal(str(value))
26
28
  except decimal.DecimalException:
27
- raise GraphQLError(f'Value cannot represent a Decimal: "{value}".')
29
+ raise GraphQLError(f'Value cannot represent a Decimal: "{value}".') # noqa: B904
28
30
 
29
31
 
30
32
  isoformat = methodcaller("isoformat")
@@ -62,7 +62,7 @@ DEFAULT_SCALAR_REGISTRY: dict[object, ScalarDefinition] = {
62
62
  datetime.datetime: _get_scalar_definition(base_scalars.DateTime),
63
63
  datetime.time: _get_scalar_definition(base_scalars.Time),
64
64
  decimal.Decimal: _get_scalar_definition(base_scalars.Decimal),
65
- # We can't wrap GLobalID with @scalar because it has custom attributes/methods
65
+ # We can't wrap GlobalID with @scalar because it has custom attributes/methods
66
66
  GlobalID: _get_scalar_definition(
67
67
  scalar(
68
68
  GlobalID,
@@ -115,7 +115,7 @@ def _get_field_type(
115
115
 
116
116
  if isinstance(field_type, NonNullTypeNode):
117
117
  return _get_field_type(field_type.type, was_non_nullable=True)
118
- elif isinstance(field_type, ListTypeNode):
118
+ if isinstance(field_type, ListTypeNode):
119
119
  expr = cst.Subscript(
120
120
  value=cst.Name("list"),
121
121
  slice=[
@@ -262,14 +262,13 @@ ArgumentValue: TypeAlias = Union[str, bool, list["ArgumentValue"]]
262
262
  def _get_argument_value(argument_value: ConstValueNode) -> ArgumentValue:
263
263
  if isinstance(argument_value, StringValueNode):
264
264
  return argument_value.value
265
- elif isinstance(argument_value, EnumValueDefinitionNode):
265
+ if isinstance(argument_value, EnumValueDefinitionNode):
266
266
  return argument_value.name.value
267
- elif isinstance(argument_value, ListValueNode):
267
+ if isinstance(argument_value, ListValueNode):
268
268
  return [_get_argument_value(arg) for arg in argument_value.values]
269
- elif isinstance(argument_value, BooleanValueNode):
269
+ if isinstance(argument_value, BooleanValueNode):
270
270
  return argument_value.value
271
- else:
272
- raise NotImplementedError(f"Unknown argument value {argument_value}")
271
+ raise NotImplementedError(f"Unknown argument value {argument_value}")
273
272
 
274
273
 
275
274
  def _get_directives(
@@ -122,7 +122,7 @@ class BaseGraphQLTransportWSHandler(Generic[Context, RootValue]):
122
122
  self.connection_timed_out = True
123
123
  reason = "Connection initialisation timeout"
124
124
  await self.websocket.close(code=4408, reason=reason)
125
- except Exception as error:
125
+ except Exception as error: # noqa: BLE001
126
126
  await self.handle_task_exception(error) # pragma: no cover
127
127
  finally:
128
128
  # do not clear self.connection_init_timeout_task
@@ -298,7 +298,7 @@ class BaseGraphQLTransportWSHandler(Generic[Context, RootValue]):
298
298
  {"id": operation.id, "type": "complete"}
299
299
  )
300
300
 
301
- except BaseException as e: # pragma: no cover
301
+ except BaseException: # pragma: no cover
302
302
  self.operations.pop(operation.id, None)
303
303
  raise
304
304
  finally:
@@ -34,9 +34,6 @@ if TYPE_CHECKING:
34
34
 
35
35
 
36
36
  class BaseGraphQLWSHandler(Generic[Context, RootValue]):
37
- context: Context
38
- root_value: RootValue
39
-
40
37
  def __init__(
41
38
  self,
42
39
  view: AsyncBaseHTTPView[Any, Any, Any, Any, Any, Context, RootValue],
strawberry/test/client.py CHANGED
@@ -188,8 +188,7 @@ class BaseGraphQLTestClient(ABC):
188
188
  # Variables can be mixed files and other data, we don't want to map non-files
189
189
  # vars so we need to remove them, we can't remove them before
190
190
  # because they can be part of a list of files or folder
191
- map_without_vars = {k: v for k, v in map.items() if k in files}
192
- return map_without_vars
191
+ return {k: v for k, v in map.items() if k in files}
193
192
 
194
193
  def _decode(self, response: Any, type: Literal["multipart", "json"]) -> Any:
195
194
  if type == "multipart":
@@ -23,8 +23,8 @@ from strawberry.types.base import (
23
23
  )
24
24
  from strawberry.types.enum import EnumDefinition
25
25
  from strawberry.types.lazy_type import LazyType, StrawberryLazyReference
26
- from strawberry.types.unset import UNSET as _deprecated_UNSET
27
- from strawberry.types.unset import _deprecated_is_unset # noqa # type: ignore
26
+ from strawberry.types.unset import UNSET as _deprecated_UNSET # noqa: N811
27
+ from strawberry.types.unset import _deprecated_is_unset # noqa: F401
28
28
 
29
29
  if TYPE_CHECKING:
30
30
  from strawberry.schema.config import StrawberryConfig
strawberry/types/auto.py CHANGED
@@ -23,8 +23,8 @@ class StrawberryAutoMeta(type):
23
23
 
24
24
  """
25
25
 
26
- def __init__(self, *args: str, **kwargs: Any) -> None:
27
- self._instance: Optional[StrawberryAuto] = None
26
+ def __init__(cls, *args: str, **kwargs: Any) -> None:
27
+ cls._instance: Optional[StrawberryAuto] = None
28
28
  super().__init__(*args, **kwargs)
29
29
 
30
30
  def __call__(cls, *args: str, **kwargs: Any) -> Any:
@@ -34,7 +34,7 @@ class StrawberryAutoMeta(type):
34
34
  return cls._instance
35
35
 
36
36
  def __instancecheck__(
37
- self,
37
+ cls,
38
38
  instance: Union[StrawberryAuto, StrawberryAnnotation, StrawberryType, type],
39
39
  ) -> bool:
40
40
  if isinstance(instance, StrawberryAnnotation):