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.
- strawberry/aiohttp/test/client.py +8 -15
- strawberry/aiohttp/views.py +12 -15
- strawberry/annotation.py +19 -23
- strawberry/asgi/__init__.py +18 -17
- strawberry/asgi/test/client.py +6 -6
- strawberry/chalice/views.py +6 -6
- strawberry/channels/handlers/base.py +7 -8
- strawberry/channels/handlers/http_handler.py +18 -20
- strawberry/channels/handlers/ws_handler.py +10 -12
- strawberry/channels/router.py +3 -4
- strawberry/channels/testing.py +7 -9
- strawberry/cli/commands/codegen.py +7 -7
- strawberry/cli/commands/schema_codegen.py +1 -2
- strawberry/cli/commands/upgrade/__init__.py +1 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
- strawberry/codegen/plugins/print_operation.py +2 -2
- strawberry/codegen/plugins/python.py +2 -2
- strawberry/codegen/query_codegen.py +20 -30
- strawberry/codegen/types.py +32 -32
- strawberry/codemods/annotated_unions.py +2 -2
- strawberry/dataloader.py +28 -24
- strawberry/directive.py +6 -7
- strawberry/django/test/client.py +3 -3
- strawberry/django/views.py +16 -19
- strawberry/exceptions/__init__.py +4 -4
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +4 -4
- strawberry/exceptions/exception.py +3 -3
- strawberry/exceptions/handler.py +8 -7
- strawberry/exceptions/invalid_argument_type.py +2 -2
- strawberry/exceptions/invalid_superclass_interface.py +2 -2
- strawberry/exceptions/invalid_union_type.py +4 -4
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_dependencies.py +2 -4
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/missing_return_annotation.py +2 -2
- strawberry/exceptions/object_is_not_a_class.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/scalar_already_registered.py +2 -2
- strawberry/exceptions/syntax.py +3 -3
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +25 -25
- strawberry/experimental/pydantic/_compat.py +8 -7
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +2 -2
- strawberry/experimental/pydantic/error_type.py +10 -12
- strawberry/experimental/pydantic/fields.py +9 -15
- strawberry/experimental/pydantic/object_type.py +15 -23
- strawberry/experimental/pydantic/utils.py +1 -2
- strawberry/ext/mypy_plugin.py +12 -14
- strawberry/extensions/base_extension.py +2 -1
- strawberry/extensions/context.py +13 -18
- strawberry/extensions/directives.py +3 -1
- strawberry/extensions/field_extension.py +4 -4
- strawberry/extensions/max_aliases.py +1 -3
- strawberry/extensions/parser_cache.py +1 -2
- strawberry/extensions/query_depth_limiter.py +18 -14
- strawberry/extensions/runner.py +2 -2
- strawberry/extensions/tracing/apollo.py +3 -3
- strawberry/extensions/tracing/datadog.py +3 -3
- strawberry/extensions/tracing/opentelemetry.py +6 -8
- strawberry/extensions/tracing/utils.py +3 -1
- strawberry/extensions/utils.py +2 -2
- strawberry/extensions/validation_cache.py +1 -2
- strawberry/fastapi/context.py +6 -6
- strawberry/fastapi/router.py +33 -36
- strawberry/federation/argument.py +4 -5
- strawberry/federation/enum.py +18 -21
- strawberry/federation/field.py +94 -97
- strawberry/federation/object_type.py +56 -58
- strawberry/federation/scalar.py +27 -35
- strawberry/federation/schema.py +15 -16
- strawberry/federation/schema_directive.py +7 -6
- strawberry/federation/schema_directives.py +11 -11
- strawberry/federation/union.py +4 -4
- strawberry/flask/views.py +10 -11
- strawberry/http/__init__.py +14 -14
- strawberry/http/async_base_view.py +23 -28
- strawberry/http/base.py +11 -12
- strawberry/http/ides.py +2 -3
- strawberry/http/sync_base_view.py +11 -13
- strawberry/http/types.py +3 -3
- strawberry/litestar/controller.py +40 -35
- strawberry/permission.py +4 -6
- strawberry/printer/ast_from_value.py +3 -5
- strawberry/printer/printer.py +8 -13
- strawberry/quart/views.py +12 -14
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +33 -32
- strawberry/relay/types.py +31 -34
- strawberry/relay/utils.py +2 -2
- strawberry/resolvers.py +2 -1
- strawberry/sanic/context.py +1 -0
- strawberry/sanic/utils.py +3 -3
- strawberry/sanic/views.py +11 -14
- strawberry/scalars.py +2 -2
- strawberry/schema/_graphql_core.py +5 -5
- strawberry/schema/base.py +32 -33
- strawberry/schema/compat.py +9 -9
- strawberry/schema/config.py +5 -2
- strawberry/schema/exceptions.py +1 -3
- strawberry/schema/name_converter.py +6 -6
- strawberry/schema/schema.py +55 -60
- strawberry/schema/schema_converter.py +27 -22
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +5 -5
- strawberry/schema_codegen/__init__.py +3 -3
- strawberry/schema_directive.py +7 -6
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -6
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -6
- strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
- strawberry/test/client.py +18 -18
- strawberry/tools/create_type.py +2 -3
- strawberry/types/arguments.py +25 -26
- strawberry/types/auto.py +3 -4
- strawberry/types/base.py +25 -27
- strawberry/types/enum.py +22 -25
- strawberry/types/execution.py +14 -15
- strawberry/types/field.py +108 -108
- strawberry/types/fields/resolver.py +19 -21
- strawberry/types/info.py +5 -11
- strawberry/types/lazy_type.py +2 -3
- strawberry/types/maybe.py +12 -3
- strawberry/types/mutation.py +115 -118
- strawberry/types/nodes.py +2 -2
- strawberry/types/object_type.py +43 -63
- strawberry/types/scalar.py +37 -43
- strawberry/types/union.py +12 -14
- strawberry/utils/aio.py +12 -9
- strawberry/utils/await_maybe.py +3 -3
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/importer.py +1 -2
- strawberry/utils/inspect.py +4 -6
- strawberry/utils/logging.py +2 -2
- strawberry/utils/operation.py +4 -4
- strawberry/utils/typing.py +18 -83
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +2 -2
- strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
- strawberry/utils/dataclasses.py +0 -37
- strawberry_graphql-0.283.0.dist-info/RECORD +0 -244
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
- {strawberry_graphql-0.283.0.dist-info → strawberry_graphql-0.284.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import cached_property
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from .exception import StrawberryException
|
|
7
7
|
from .utils.source_finder import SourceFinder
|
|
@@ -32,7 +32,7 @@ class PrivateStrawberryFieldError(StrawberryException):
|
|
|
32
32
|
super().__init__(self.message)
|
|
33
33
|
|
|
34
34
|
@cached_property
|
|
35
|
-
def exception_source(self) ->
|
|
35
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
36
36
|
if self.cls is None:
|
|
37
37
|
return None # pragma: no cover
|
|
38
38
|
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from functools import cached_property
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from strawberry.exceptions.utils.source_finder import SourceFinder
|
|
8
8
|
|
|
@@ -45,7 +45,7 @@ class ScalarAlreadyRegisteredError(StrawberryException):
|
|
|
45
45
|
super().__init__(self.message)
|
|
46
46
|
|
|
47
47
|
@cached_property
|
|
48
|
-
def exception_source(self) ->
|
|
48
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
49
49
|
if not all(
|
|
50
50
|
(self.scalar_definition._source_file, self.scalar_definition._source_line)
|
|
51
51
|
):
|
strawberry/exceptions/syntax.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from pygments.lexers import PythonLexer
|
|
6
6
|
from rich.segment import Segment
|
|
@@ -15,9 +15,9 @@ class Syntax(RichSyntax):
|
|
|
15
15
|
self,
|
|
16
16
|
code: str,
|
|
17
17
|
line_range: tuple[int, int],
|
|
18
|
-
highlight_lines:
|
|
18
|
+
highlight_lines: set[int] | None = None,
|
|
19
19
|
line_offset: int = 0,
|
|
20
|
-
line_annotations:
|
|
20
|
+
line_annotations: dict[int, str] | None = None,
|
|
21
21
|
) -> None:
|
|
22
22
|
self.line_offset = line_offset
|
|
23
23
|
self.line_annotations = line_annotations or {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import cached_property
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from strawberry.exceptions.utils.source_finder import SourceFinder
|
|
7
7
|
|
|
@@ -40,7 +40,7 @@ class UnresolvedFieldTypeError(StrawberryException):
|
|
|
40
40
|
super().__init__(self.message)
|
|
41
41
|
|
|
42
42
|
@cached_property
|
|
43
|
-
def exception_source(self) ->
|
|
43
|
+
def exception_source(self) -> ExceptionSource | None:
|
|
44
44
|
source_finder = SourceFinder()
|
|
45
45
|
|
|
46
46
|
# field could be attached to the class or not
|
|
@@ -6,12 +6,12 @@ import sys
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from functools import cached_property
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import TYPE_CHECKING, Any,
|
|
9
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
10
10
|
|
|
11
11
|
from strawberry.exceptions.exception_source import ExceptionSource
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
|
-
from collections.abc import Sequence
|
|
14
|
+
from collections.abc import Callable, Sequence
|
|
15
15
|
from inspect import Traceback
|
|
16
16
|
|
|
17
17
|
from libcst import BinaryOperation, Call, CSTNode, FunctionDef
|
|
@@ -30,7 +30,7 @@ class LibCSTSourceFinder:
|
|
|
30
30
|
def __init__(self) -> None:
|
|
31
31
|
self.cst = importlib.import_module("libcst")
|
|
32
32
|
|
|
33
|
-
def find_source(self, module: str) ->
|
|
33
|
+
def find_source(self, module: str) -> SourcePath | None:
|
|
34
34
|
# TODO: support for pyodide
|
|
35
35
|
|
|
36
36
|
source_module = sys.modules.get(module)
|
|
@@ -73,11 +73,11 @@ class LibCSTSourceFinder:
|
|
|
73
73
|
|
|
74
74
|
def _find_definition_by_qualname(
|
|
75
75
|
self, qualname: str, nodes: Sequence[CSTNode]
|
|
76
|
-
) ->
|
|
76
|
+
) -> CSTNode | None:
|
|
77
77
|
from libcst import ClassDef, FunctionDef
|
|
78
78
|
|
|
79
79
|
for definition in nodes:
|
|
80
|
-
parent:
|
|
80
|
+
parent: CSTNode | None = definition
|
|
81
81
|
stack = []
|
|
82
82
|
|
|
83
83
|
while parent:
|
|
@@ -101,7 +101,7 @@ class LibCSTSourceFinder:
|
|
|
101
101
|
|
|
102
102
|
def _find_function_definition(
|
|
103
103
|
self, source: SourcePath, function: Callable[..., Any]
|
|
104
|
-
) ->
|
|
104
|
+
) -> FunctionDef | None:
|
|
105
105
|
import libcst.matchers as m
|
|
106
106
|
|
|
107
107
|
matcher = m.FunctionDef(name=m.Name(value=function.__name__))
|
|
@@ -115,7 +115,7 @@ class LibCSTSourceFinder:
|
|
|
115
115
|
|
|
116
116
|
def _find_class_definition(
|
|
117
117
|
self, source: SourcePath, cls: type[Any]
|
|
118
|
-
) ->
|
|
118
|
+
) -> CSTNode | None:
|
|
119
119
|
import libcst.matchers as m
|
|
120
120
|
|
|
121
121
|
matcher = m.ClassDef(name=m.Name(value=cls.__name__))
|
|
@@ -123,7 +123,7 @@ class LibCSTSourceFinder:
|
|
|
123
123
|
class_defs = self._find(source.code, matcher)
|
|
124
124
|
return self._find_definition_by_qualname(cls.__qualname__, class_defs)
|
|
125
125
|
|
|
126
|
-
def find_class(self, cls: type[Any]) ->
|
|
126
|
+
def find_class(self, cls: type[Any]) -> ExceptionSource | None:
|
|
127
127
|
source = self.find_source(cls.__module__)
|
|
128
128
|
|
|
129
129
|
if source is None:
|
|
@@ -149,7 +149,7 @@ class LibCSTSourceFinder:
|
|
|
149
149
|
|
|
150
150
|
def find_class_attribute(
|
|
151
151
|
self, cls: type[Any], attribute_name: str
|
|
152
|
-
) ->
|
|
152
|
+
) -> ExceptionSource | None:
|
|
153
153
|
source = self.find_source(cls.__module__)
|
|
154
154
|
|
|
155
155
|
if source is None:
|
|
@@ -191,7 +191,7 @@ class LibCSTSourceFinder:
|
|
|
191
191
|
error_column_end=attribute_position.end.column,
|
|
192
192
|
)
|
|
193
193
|
|
|
194
|
-
def find_function(self, function: Callable[..., Any]) ->
|
|
194
|
+
def find_function(self, function: Callable[..., Any]) -> ExceptionSource | None:
|
|
195
195
|
source = self.find_source(function.__module__)
|
|
196
196
|
|
|
197
197
|
if source is None:
|
|
@@ -225,7 +225,7 @@ class LibCSTSourceFinder:
|
|
|
225
225
|
|
|
226
226
|
def find_argument(
|
|
227
227
|
self, function: Callable[..., Any], argument_name: str
|
|
228
|
-
) ->
|
|
228
|
+
) -> ExceptionSource | None:
|
|
229
229
|
source = self.find_source(function.__module__)
|
|
230
230
|
|
|
231
231
|
if source is None:
|
|
@@ -263,7 +263,7 @@ class LibCSTSourceFinder:
|
|
|
263
263
|
|
|
264
264
|
def find_union_call(
|
|
265
265
|
self, path: Path, union_name: str, invalid_type: object
|
|
266
|
-
) ->
|
|
266
|
+
) -> ExceptionSource | None:
|
|
267
267
|
import libcst.matchers as m
|
|
268
268
|
|
|
269
269
|
source = path.read_text()
|
|
@@ -339,7 +339,7 @@ class LibCSTSourceFinder:
|
|
|
339
339
|
|
|
340
340
|
def find_union_merge(
|
|
341
341
|
self, union: StrawberryUnion, other: object, frame: Traceback
|
|
342
|
-
) ->
|
|
342
|
+
) -> ExceptionSource | None:
|
|
343
343
|
import libcst.matchers as m
|
|
344
344
|
|
|
345
345
|
path = Path(frame.filename)
|
|
@@ -375,7 +375,7 @@ class LibCSTSourceFinder:
|
|
|
375
375
|
|
|
376
376
|
def find_annotated_union(
|
|
377
377
|
self, union_definition: StrawberryUnion, invalid_type: object
|
|
378
|
-
) ->
|
|
378
|
+
) -> ExceptionSource | None:
|
|
379
379
|
if union_definition._source_file is None:
|
|
380
380
|
return None
|
|
381
381
|
|
|
@@ -503,7 +503,7 @@ class LibCSTSourceFinder:
|
|
|
503
503
|
|
|
504
504
|
def find_scalar_call(
|
|
505
505
|
self, scalar_definition: ScalarDefinition
|
|
506
|
-
) ->
|
|
506
|
+
) -> ExceptionSource | None:
|
|
507
507
|
if scalar_definition._source_file is None:
|
|
508
508
|
return None # pragma: no cover
|
|
509
509
|
|
|
@@ -571,7 +571,7 @@ class LibCSTSourceFinder:
|
|
|
571
571
|
call_node: Any,
|
|
572
572
|
scalar_definition: ScalarDefinition,
|
|
573
573
|
is_newtype: bool,
|
|
574
|
-
) ->
|
|
574
|
+
) -> ExceptionSource | None:
|
|
575
575
|
"""Helper method to create ExceptionSource for scalar calls."""
|
|
576
576
|
import libcst.matchers as m
|
|
577
577
|
|
|
@@ -615,33 +615,33 @@ class LibCSTSourceFinder:
|
|
|
615
615
|
|
|
616
616
|
class SourceFinder:
|
|
617
617
|
@cached_property
|
|
618
|
-
def cst(self) ->
|
|
618
|
+
def cst(self) -> LibCSTSourceFinder | None:
|
|
619
619
|
try:
|
|
620
620
|
return LibCSTSourceFinder()
|
|
621
621
|
except ImportError:
|
|
622
622
|
return None # pragma: no cover
|
|
623
623
|
|
|
624
|
-
def find_class_from_object(self, cls: type[Any]) ->
|
|
624
|
+
def find_class_from_object(self, cls: type[Any]) -> ExceptionSource | None:
|
|
625
625
|
return self.cst.find_class(cls) if self.cst else None
|
|
626
626
|
|
|
627
627
|
def find_class_attribute_from_object(
|
|
628
628
|
self, cls: type[Any], attribute_name: str
|
|
629
|
-
) ->
|
|
629
|
+
) -> ExceptionSource | None:
|
|
630
630
|
return self.cst.find_class_attribute(cls, attribute_name) if self.cst else None
|
|
631
631
|
|
|
632
632
|
def find_function_from_object(
|
|
633
633
|
self, function: Callable[..., Any]
|
|
634
|
-
) ->
|
|
634
|
+
) -> ExceptionSource | None:
|
|
635
635
|
return self.cst.find_function(function) if self.cst else None
|
|
636
636
|
|
|
637
637
|
def find_argument_from_object(
|
|
638
638
|
self, function: Callable[..., Any], argument_name: str
|
|
639
|
-
) ->
|
|
639
|
+
) -> ExceptionSource | None:
|
|
640
640
|
return self.cst.find_argument(function, argument_name) if self.cst else None
|
|
641
641
|
|
|
642
642
|
def find_union_call(
|
|
643
643
|
self, path: Path, union_name: str, invalid_type: object
|
|
644
|
-
) ->
|
|
644
|
+
) -> ExceptionSource | None:
|
|
645
645
|
return (
|
|
646
646
|
self.cst.find_union_call(path, union_name, invalid_type)
|
|
647
647
|
if self.cst
|
|
@@ -650,17 +650,17 @@ class SourceFinder:
|
|
|
650
650
|
|
|
651
651
|
def find_union_merge(
|
|
652
652
|
self, union: StrawberryUnion, other: object, frame: Traceback
|
|
653
|
-
) ->
|
|
653
|
+
) -> ExceptionSource | None:
|
|
654
654
|
return self.cst.find_union_merge(union, other, frame) if self.cst else None
|
|
655
655
|
|
|
656
656
|
def find_scalar_call(
|
|
657
657
|
self, scalar_definition: ScalarDefinition
|
|
658
|
-
) ->
|
|
658
|
+
) -> ExceptionSource | None:
|
|
659
659
|
return self.cst.find_scalar_call(scalar_definition) if self.cst else None
|
|
660
660
|
|
|
661
661
|
def find_annotated_union(
|
|
662
662
|
self, union_definition: StrawberryUnion, invalid_type: object
|
|
663
|
-
) ->
|
|
663
|
+
) -> ExceptionSource | None:
|
|
664
664
|
return (
|
|
665
665
|
self.cst.find_annotated_union(union_definition, invalid_type)
|
|
666
666
|
if self.cst
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from decimal import Decimal
|
|
4
5
|
from functools import cached_property
|
|
5
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
6
7
|
from uuid import UUID
|
|
7
8
|
|
|
8
9
|
import pydantic
|
|
@@ -24,12 +25,12 @@ class CompatModelField:
|
|
|
24
25
|
type_: Any
|
|
25
26
|
outer_type_: Any
|
|
26
27
|
default: Any
|
|
27
|
-
default_factory:
|
|
28
|
+
default_factory: Callable[[], Any] | None
|
|
28
29
|
required: bool
|
|
29
|
-
alias:
|
|
30
|
+
alias: str | None
|
|
30
31
|
allow_none: bool
|
|
31
32
|
has_alias: bool
|
|
32
|
-
description:
|
|
33
|
+
description: str | None
|
|
33
34
|
_missing_type: Any
|
|
34
35
|
is_v1: bool
|
|
35
36
|
|
|
@@ -43,8 +44,8 @@ class CompatModelField:
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
ATTR_TO_TYPE_MAP = {
|
|
46
|
-
"NoneStr": Optional[str],
|
|
47
|
-
"NoneBytes": Optional[bytes],
|
|
47
|
+
"NoneStr": Optional[str], # noqa: UP045
|
|
48
|
+
"NoneBytes": Optional[bytes], # noqa: UP045
|
|
48
49
|
"StrBytes": None,
|
|
49
50
|
"NoneStrBytes": None,
|
|
50
51
|
"StrictStr": str,
|
|
@@ -296,7 +297,7 @@ class PydanticCompat:
|
|
|
296
297
|
|
|
297
298
|
|
|
298
299
|
if IS_PYDANTIC_V2:
|
|
299
|
-
from
|
|
300
|
+
from typing import get_args, get_origin
|
|
300
301
|
|
|
301
302
|
from pydantic.v1.typing import is_new_type
|
|
302
303
|
from pydantic.v1.utils import lenient_issubclass, smart_deepcopy
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import dataclasses
|
|
5
|
-
from typing import TYPE_CHECKING, Any,
|
|
5
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
6
6
|
|
|
7
7
|
from strawberry.types.base import (
|
|
8
8
|
StrawberryList,
|
|
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def _convert_from_pydantic_to_strawberry_type(
|
|
21
|
-
type_:
|
|
21
|
+
type_: StrawberryType | type,
|
|
22
22
|
data_from_model=None, # noqa: ANN001
|
|
23
23
|
extra=None, # noqa: ANN001
|
|
24
24
|
) -> Any:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
4
4
|
from typing_extensions import Protocol
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel
|
|
@@ -22,7 +22,7 @@ class StrawberryTypeFromPydantic(Protocol[PydanticModel]):
|
|
|
22
22
|
|
|
23
23
|
@staticmethod
|
|
24
24
|
def from_pydantic(
|
|
25
|
-
instance: PydanticModel, extra:
|
|
25
|
+
instance: PydanticModel, extra: dict[str, Any] | None = None
|
|
26
26
|
) -> StrawberryTypeFromPydantic[PydanticModel]: ...
|
|
27
27
|
|
|
28
28
|
def to_pydantic(self, **kwargs: Any) -> PydanticModel: ...
|
|
@@ -5,9 +5,7 @@ import warnings
|
|
|
5
5
|
from typing import (
|
|
6
6
|
TYPE_CHECKING,
|
|
7
7
|
Any,
|
|
8
|
-
Callable,
|
|
9
8
|
Optional,
|
|
10
|
-
Union,
|
|
11
9
|
cast,
|
|
12
10
|
)
|
|
13
11
|
|
|
@@ -31,18 +29,18 @@ from strawberry.utils.typing import get_list_annotation, is_list
|
|
|
31
29
|
from .exceptions import MissingFieldsListError
|
|
32
30
|
|
|
33
31
|
if TYPE_CHECKING:
|
|
34
|
-
from collections.abc import Sequence
|
|
32
|
+
from collections.abc import Callable, Sequence
|
|
35
33
|
|
|
36
34
|
from strawberry.types.base import WithStrawberryObjectDefinition
|
|
37
35
|
|
|
38
36
|
|
|
39
|
-
def get_type_for_field(field: CompatModelField) ->
|
|
37
|
+
def get_type_for_field(field: CompatModelField) -> type[None | list] | Any:
|
|
40
38
|
type_ = field.outer_type_
|
|
41
39
|
type_ = normalize_type(type_)
|
|
42
40
|
return field_type_to_type(type_)
|
|
43
41
|
|
|
44
42
|
|
|
45
|
-
def field_type_to_type(type_: type) ->
|
|
43
|
+
def field_type_to_type(type_: type) -> Any | list[Any] | None:
|
|
46
44
|
error_class: Any = str
|
|
47
45
|
strawberry_type: Any = error_class
|
|
48
46
|
|
|
@@ -56,21 +54,21 @@ def field_type_to_type(type_: type) -> Union[Any, list[Any], None]:
|
|
|
56
54
|
else:
|
|
57
55
|
strawberry_type = list[error_class]
|
|
58
56
|
|
|
59
|
-
strawberry_type = Optional[strawberry_type]
|
|
57
|
+
strawberry_type = Optional[strawberry_type] # noqa: UP045
|
|
60
58
|
elif lenient_issubclass(type_, BaseModel):
|
|
61
59
|
strawberry_type = get_strawberry_type_from_model(type_)
|
|
62
|
-
return Optional[strawberry_type]
|
|
60
|
+
return Optional[strawberry_type] # noqa: UP045
|
|
63
61
|
|
|
64
|
-
return Optional[list[strawberry_type]]
|
|
62
|
+
return Optional[list[strawberry_type]] # noqa: UP045
|
|
65
63
|
|
|
66
64
|
|
|
67
65
|
def error_type(
|
|
68
66
|
model: type[BaseModel],
|
|
69
67
|
*,
|
|
70
|
-
fields:
|
|
71
|
-
name:
|
|
72
|
-
description:
|
|
73
|
-
directives:
|
|
68
|
+
fields: list[str] | None = None,
|
|
69
|
+
name: str | None = None,
|
|
70
|
+
description: str | None = None,
|
|
71
|
+
directives: Sequence[object] | None = (),
|
|
74
72
|
all_fields: bool = False,
|
|
75
73
|
) -> Callable[..., type]:
|
|
76
74
|
def wrap(cls: type) -> type:
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import builtins
|
|
2
|
-
from
|
|
2
|
+
from types import UnionType
|
|
3
|
+
from typing import (
|
|
4
|
+
Annotated,
|
|
5
|
+
Any,
|
|
6
|
+
Union,
|
|
7
|
+
)
|
|
8
|
+
from typing import GenericAlias as TypingGenericAlias # type: ignore
|
|
3
9
|
|
|
4
10
|
from pydantic import BaseModel
|
|
5
11
|
|
|
@@ -14,18 +20,6 @@ from strawberry.experimental.pydantic.exceptions import (
|
|
|
14
20
|
)
|
|
15
21
|
from strawberry.types.base import StrawberryObjectDefinition
|
|
16
22
|
|
|
17
|
-
try:
|
|
18
|
-
from types import UnionType as TypingUnionType
|
|
19
|
-
except ImportError:
|
|
20
|
-
import sys
|
|
21
|
-
|
|
22
|
-
if sys.version_info < (3, 10):
|
|
23
|
-
TypingUnionType = ()
|
|
24
|
-
else:
|
|
25
|
-
raise
|
|
26
|
-
|
|
27
|
-
from typing import GenericAlias as TypingGenericAlias # type: ignore
|
|
28
|
-
|
|
29
23
|
|
|
30
24
|
def replace_pydantic_types(type_: Any, is_input: bool) -> Any:
|
|
31
25
|
if lenient_issubclass(type_, BaseModel):
|
|
@@ -55,8 +49,8 @@ def replace_types_recursively(
|
|
|
55
49
|
|
|
56
50
|
if isinstance(replaced_type, TypingGenericAlias):
|
|
57
51
|
return TypingGenericAlias(origin, converted)
|
|
58
|
-
if isinstance(replaced_type,
|
|
59
|
-
return Union[converted]
|
|
52
|
+
if isinstance(replaced_type, UnionType):
|
|
53
|
+
return Union[converted] # noqa: UP007
|
|
60
54
|
|
|
61
55
|
# TODO: investigate if we could move the check for annotated to the top
|
|
62
56
|
if origin is Annotated and converted:
|
|
@@ -6,7 +6,6 @@ import warnings
|
|
|
6
6
|
from typing import (
|
|
7
7
|
TYPE_CHECKING,
|
|
8
8
|
Any,
|
|
9
|
-
Callable,
|
|
10
9
|
Optional,
|
|
11
10
|
cast,
|
|
12
11
|
)
|
|
@@ -36,7 +35,7 @@ from strawberry.types.type_resolver import _get_fields
|
|
|
36
35
|
|
|
37
36
|
if TYPE_CHECKING:
|
|
38
37
|
import builtins
|
|
39
|
-
from collections.abc import Sequence
|
|
38
|
+
from collections.abc import Callable, Sequence
|
|
40
39
|
|
|
41
40
|
from graphql import GraphQLResolveInfo
|
|
42
41
|
|
|
@@ -50,7 +49,7 @@ def get_type_for_field(field: CompatModelField, is_input: bool, compat: Pydantic
|
|
|
50
49
|
# only pydantic v1 has this Optional logic
|
|
51
50
|
should_add_optional: bool = field.allow_none
|
|
52
51
|
if should_add_optional:
|
|
53
|
-
return Optional[replaced_type]
|
|
52
|
+
return Optional[replaced_type] # noqa: UP045
|
|
54
53
|
|
|
55
54
|
return replaced_type
|
|
56
55
|
|
|
@@ -119,12 +118,12 @@ if TYPE_CHECKING:
|
|
|
119
118
|
def type(
|
|
120
119
|
model: builtins.type[PydanticModel],
|
|
121
120
|
*,
|
|
122
|
-
fields:
|
|
123
|
-
name:
|
|
121
|
+
fields: list[str] | None = None,
|
|
122
|
+
name: str | None = None,
|
|
124
123
|
is_input: bool = False,
|
|
125
124
|
is_interface: bool = False,
|
|
126
|
-
description:
|
|
127
|
-
directives:
|
|
125
|
+
description: str | None = None,
|
|
126
|
+
directives: Sequence[object] | None = (),
|
|
128
127
|
all_fields: bool = False,
|
|
129
128
|
include_computed: bool = False,
|
|
130
129
|
use_pydantic_alias: bool = True,
|
|
@@ -247,8 +246,6 @@ def type(
|
|
|
247
246
|
# https://github.com/python/cpython/issues/89961
|
|
248
247
|
if sys.version_info >= (3, 10, 1):
|
|
249
248
|
kwargs["kw_only"] = dataclasses.MISSING
|
|
250
|
-
else:
|
|
251
|
-
kwargs["init"] = False
|
|
252
249
|
|
|
253
250
|
cls = dataclasses.make_dataclass(
|
|
254
251
|
cls.__name__,
|
|
@@ -258,11 +255,6 @@ def type(
|
|
|
258
255
|
**kwargs, # type: ignore
|
|
259
256
|
)
|
|
260
257
|
|
|
261
|
-
if sys.version_info < (3, 10, 1):
|
|
262
|
-
from strawberry.utils.dataclasses import add_custom_init_fn
|
|
263
|
-
|
|
264
|
-
add_custom_init_fn(cls)
|
|
265
|
-
|
|
266
258
|
_process_type(
|
|
267
259
|
cls,
|
|
268
260
|
name=name,
|
|
@@ -279,7 +271,7 @@ def type(
|
|
|
279
271
|
cls._pydantic_type = model
|
|
280
272
|
|
|
281
273
|
def from_pydantic_default(
|
|
282
|
-
instance: PydanticModel, extra:
|
|
274
|
+
instance: PydanticModel, extra: dict[str, Any] | None = None
|
|
283
275
|
) -> StrawberryTypeFromPydantic[PydanticModel]:
|
|
284
276
|
ret = convert_pydantic_model_to_strawberry_class(
|
|
285
277
|
cls=cls, model_instance=instance, extra=extra
|
|
@@ -310,11 +302,11 @@ def type(
|
|
|
310
302
|
def input(
|
|
311
303
|
model: builtins.type[PydanticModel],
|
|
312
304
|
*,
|
|
313
|
-
fields:
|
|
314
|
-
name:
|
|
305
|
+
fields: list[str] | None = None,
|
|
306
|
+
name: str | None = None,
|
|
315
307
|
is_interface: bool = False,
|
|
316
|
-
description:
|
|
317
|
-
directives:
|
|
308
|
+
description: str | None = None,
|
|
309
|
+
directives: Sequence[object] | None = (),
|
|
318
310
|
all_fields: bool = False,
|
|
319
311
|
use_pydantic_alias: bool = True,
|
|
320
312
|
) -> Callable[..., builtins.type[StrawberryTypeFromPydantic[PydanticModel]]]:
|
|
@@ -340,11 +332,11 @@ def input(
|
|
|
340
332
|
def interface(
|
|
341
333
|
model: builtins.type[PydanticModel],
|
|
342
334
|
*,
|
|
343
|
-
fields:
|
|
344
|
-
name:
|
|
335
|
+
fields: list[str] | None = None,
|
|
336
|
+
name: str | None = None,
|
|
345
337
|
is_input: bool = False,
|
|
346
|
-
description:
|
|
347
|
-
directives:
|
|
338
|
+
description: str | None = None,
|
|
339
|
+
directives: Sequence[object] | None = (),
|
|
348
340
|
all_fields: bool = False,
|
|
349
341
|
use_pydantic_alias: bool = True,
|
|
350
342
|
) -> Callable[..., builtins.type[StrawberryTypeFromPydantic[PydanticModel]]]:
|
|
@@ -5,7 +5,6 @@ from typing import (
|
|
|
5
5
|
TYPE_CHECKING,
|
|
6
6
|
Any,
|
|
7
7
|
NamedTuple,
|
|
8
|
-
Union,
|
|
9
8
|
cast,
|
|
10
9
|
)
|
|
11
10
|
|
|
@@ -69,7 +68,7 @@ class DataclassCreationFields(NamedTuple):
|
|
|
69
68
|
def get_default_factory_for_field(
|
|
70
69
|
field: CompatModelField,
|
|
71
70
|
compat: PydanticCompat,
|
|
72
|
-
) ->
|
|
71
|
+
) -> NoArgAnyCallable | dataclasses._MISSING_TYPE:
|
|
73
72
|
"""Gets the default factory for a pydantic field.
|
|
74
73
|
|
|
75
74
|
Handles mutable defaults when making the dataclass by
|
strawberry/ext/mypy_plugin.py
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
-
import typing
|
|
5
4
|
import warnings
|
|
6
5
|
from decimal import Decimal
|
|
7
6
|
from typing import (
|
|
8
7
|
TYPE_CHECKING,
|
|
9
8
|
Any,
|
|
10
|
-
Callable,
|
|
11
|
-
Optional,
|
|
12
|
-
Union,
|
|
13
9
|
cast,
|
|
14
10
|
)
|
|
15
11
|
|
|
@@ -57,7 +53,7 @@ try:
|
|
|
57
53
|
except ImportError:
|
|
58
54
|
TypeVarDef = TypeVarType
|
|
59
55
|
|
|
60
|
-
PYDANTIC_VERSION:
|
|
56
|
+
PYDANTIC_VERSION: tuple[int, ...] | None = None
|
|
61
57
|
|
|
62
58
|
# To be compatible with user who don't use pydantic
|
|
63
59
|
try:
|
|
@@ -74,6 +70,8 @@ except ImportError:
|
|
|
74
70
|
|
|
75
71
|
|
|
76
72
|
if TYPE_CHECKING:
|
|
73
|
+
from collections.abc import Callable
|
|
74
|
+
|
|
77
75
|
from mypy.nodes import ClassDef, Expression
|
|
78
76
|
from mypy.plugins import ( # type: ignore
|
|
79
77
|
AnalyzeTypeContext,
|
|
@@ -241,7 +239,7 @@ def enum_hook(ctx: DynamicClassDefContext) -> None:
|
|
|
241
239
|
)
|
|
242
240
|
return
|
|
243
241
|
|
|
244
|
-
enum_type:
|
|
242
|
+
enum_type: Type | None
|
|
245
243
|
|
|
246
244
|
try:
|
|
247
245
|
enum_type = _get_type_for_expr(first_argument, ctx.api)
|
|
@@ -289,7 +287,7 @@ def scalar_hook(ctx: DynamicClassDefContext) -> None:
|
|
|
289
287
|
)
|
|
290
288
|
return
|
|
291
289
|
|
|
292
|
-
scalar_type:
|
|
290
|
+
scalar_type: Type | None
|
|
293
291
|
|
|
294
292
|
# TODO: add proper support for NewType
|
|
295
293
|
|
|
@@ -314,12 +312,12 @@ def scalar_hook(ctx: DynamicClassDefContext) -> None:
|
|
|
314
312
|
|
|
315
313
|
|
|
316
314
|
def add_static_method_to_class(
|
|
317
|
-
api:
|
|
315
|
+
api: SemanticAnalyzerPluginInterface | CheckerPluginInterface,
|
|
318
316
|
cls: ClassDef,
|
|
319
317
|
name: str,
|
|
320
318
|
args: list[Argument],
|
|
321
319
|
return_type: Type,
|
|
322
|
-
tvar_def:
|
|
320
|
+
tvar_def: TypeVarType | None = None,
|
|
323
321
|
) -> None:
|
|
324
322
|
"""Adds a static method.
|
|
325
323
|
|
|
@@ -355,7 +353,7 @@ def add_static_method_to_class(
|
|
|
355
353
|
arg_types, arg_kinds, arg_names, return_type, function_type
|
|
356
354
|
)
|
|
357
355
|
if tvar_def:
|
|
358
|
-
signature.variables = [tvar_def]
|
|
356
|
+
signature.variables = [tvar_def] # type: ignore[assignment]
|
|
359
357
|
|
|
360
358
|
func = FuncDef(name, args, Block([PassStmt()]))
|
|
361
359
|
|
|
@@ -527,7 +525,7 @@ def strawberry_pydantic_class_callback(ctx: ClassDefContext) -> None:
|
|
|
527
525
|
class StrawberryPlugin(Plugin):
|
|
528
526
|
def get_dynamic_class_hook(
|
|
529
527
|
self, fullname: str
|
|
530
|
-
) ->
|
|
528
|
+
) -> Callable[[DynamicClassDefContext], None] | None:
|
|
531
529
|
# TODO: investigate why we need this instead of `strawberry.union.union` on CI
|
|
532
530
|
# we have the same issue in the other hooks
|
|
533
531
|
if self._is_strawberry_union(fullname):
|
|
@@ -544,7 +542,7 @@ class StrawberryPlugin(Plugin):
|
|
|
544
542
|
|
|
545
543
|
return None
|
|
546
544
|
|
|
547
|
-
def get_type_analyze_hook(self, fullname: str) ->
|
|
545
|
+
def get_type_analyze_hook(self, fullname: str) -> Callable[..., Type] | None:
|
|
548
546
|
if self._is_strawberry_lazy_type(fullname):
|
|
549
547
|
return lazy_type_analyze_callback
|
|
550
548
|
|
|
@@ -552,7 +550,7 @@ class StrawberryPlugin(Plugin):
|
|
|
552
550
|
|
|
553
551
|
def get_class_decorator_hook(
|
|
554
552
|
self, fullname: str
|
|
555
|
-
) ->
|
|
553
|
+
) -> Callable[[ClassDefContext], None] | None:
|
|
556
554
|
if self._is_strawberry_pydantic_decorator(fullname):
|
|
557
555
|
return strawberry_pydantic_class_callback
|
|
558
556
|
|
|
@@ -613,7 +611,7 @@ class StrawberryPlugin(Plugin):
|
|
|
613
611
|
)
|
|
614
612
|
|
|
615
613
|
|
|
616
|
-
def plugin(version: str) ->
|
|
614
|
+
def plugin(version: str) -> type[StrawberryPlugin]:
|
|
617
615
|
match = VERSION_RE.match(version)
|
|
618
616
|
if match:
|
|
619
617
|
MypyVersion.VERSION = Decimal(".".join(match.groups()))
|