strawberry-graphql 0.235.2__py3-none-any.whl → 0.236.1__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.
- strawberry/__init__.py +17 -11
- strawberry/aiohttp/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/aiohttp/handlers/graphql_ws_handler.py +3 -0
- strawberry/aiohttp/test/client.py +3 -0
- strawberry/aiohttp/views.py +3 -0
- strawberry/annotation.py +19 -19
- strawberry/asgi/__init__.py +3 -3
- strawberry/asgi/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/asgi/handlers/graphql_ws_handler.py +3 -0
- strawberry/asgi/test/client.py +3 -0
- strawberry/chalice/views.py +12 -3
- strawberry/channels/handlers/__init__.py +0 -0
- strawberry/channels/handlers/base.py +5 -5
- strawberry/channels/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/channels/handlers/graphql_ws_handler.py +3 -0
- strawberry/channels/handlers/http_handler.py +5 -2
- strawberry/channels/handlers/ws_handler.py +4 -1
- strawberry/channels/router.py +9 -5
- strawberry/channels/testing.py +11 -4
- strawberry/cli/commands/upgrade/__init__.py +13 -5
- strawberry/cli/commands/upgrade/_fake_progress.py +2 -1
- strawberry/cli/commands/upgrade/_run_codemod.py +18 -1
- strawberry/codegen/exceptions.py +8 -0
- strawberry/codegen/query_codegen.py +16 -7
- strawberry/codegen/types.py +32 -1
- strawberry/codemods/update_imports.py +136 -0
- strawberry/dataloader.py +13 -0
- strawberry/directive.py +52 -4
- strawberry/django/context.py +4 -1
- strawberry/django/test/client.py +3 -0
- strawberry/django/views.py +3 -0
- strawberry/exceptions/__init__.py +5 -5
- strawberry/exceptions/duplicated_type_name.py +1 -1
- strawberry/exceptions/invalid_argument_type.py +3 -3
- strawberry/exceptions/invalid_union_type.py +5 -6
- strawberry/exceptions/missing_arguments_annotations.py +1 -1
- strawberry/exceptions/missing_dependencies.py +10 -2
- strawberry/exceptions/missing_return_annotation.py +1 -1
- strawberry/exceptions/permission_fail_silently_requires_optional.py +3 -3
- strawberry/exceptions/scalar_already_registered.py +1 -1
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +5 -2
- strawberry/experimental/pydantic/conversion.py +5 -5
- strawberry/experimental/pydantic/conversion_types.py +4 -2
- strawberry/experimental/pydantic/error_type.py +2 -2
- strawberry/experimental/pydantic/fields.py +2 -2
- strawberry/experimental/pydantic/object_type.py +11 -7
- strawberry/experimental/pydantic/utils.py +4 -5
- strawberry/ext/dataclasses/dataclasses.py +2 -1
- strawberry/ext/mypy_plugin.py +10 -8
- strawberry/extensions/add_validation_rules.py +27 -23
- strawberry/extensions/base_extension.py +6 -4
- strawberry/extensions/directives.py +4 -1
- strawberry/extensions/disable_validation.py +15 -12
- strawberry/extensions/field_extension.py +11 -5
- strawberry/extensions/mask_errors.py +3 -0
- strawberry/extensions/max_aliases.py +21 -19
- strawberry/extensions/max_tokens.py +14 -16
- strawberry/extensions/parser_cache.py +22 -19
- strawberry/extensions/pyinstrument.py +4 -8
- strawberry/extensions/query_depth_limiter.py +22 -23
- strawberry/extensions/runner.py +3 -0
- strawberry/extensions/tracing/apollo.py +3 -0
- strawberry/extensions/tracing/datadog.py +7 -2
- strawberry/extensions/tracing/opentelemetry.py +3 -0
- strawberry/extensions/tracing/sentry.py +3 -0
- strawberry/extensions/tracing/utils.py +3 -0
- strawberry/extensions/utils.py +3 -0
- strawberry/extensions/validation_cache.py +23 -20
- strawberry/fastapi/context.py +3 -0
- strawberry/fastapi/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/fastapi/handlers/graphql_ws_handler.py +3 -0
- strawberry/fastapi/router.py +3 -0
- strawberry/federation/argument.py +4 -1
- strawberry/federation/enum.py +5 -3
- strawberry/federation/field.py +6 -3
- strawberry/federation/mutation.py +2 -0
- strawberry/federation/object_type.py +7 -4
- strawberry/federation/scalar.py +43 -20
- strawberry/federation/schema.py +12 -9
- strawberry/federation/schema_directive.py +2 -2
- strawberry/federation/schema_directives.py +19 -1
- strawberry/federation/types.py +5 -2
- strawberry/federation/union.py +27 -8
- strawberry/field_extensions/input_mutation.py +5 -2
- strawberry/file_uploads/scalars.py +3 -1
- strawberry/file_uploads/utils.py +3 -0
- strawberry/flask/views.py +6 -0
- strawberry/http/__init__.py +9 -0
- strawberry/http/async_base_view.py +4 -3
- strawberry/http/base.py +3 -0
- strawberry/http/exceptions.py +3 -0
- strawberry/http/ides.py +3 -0
- strawberry/http/sync_base_view.py +4 -3
- strawberry/http/temporal_response.py +3 -0
- strawberry/http/types.py +3 -0
- strawberry/http/typevars.py +3 -0
- strawberry/litestar/controller.py +6 -0
- strawberry/litestar/handlers/__init__.py +0 -0
- strawberry/litestar/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/litestar/handlers/graphql_ws_handler.py +3 -0
- strawberry/parent.py +27 -21
- strawberry/permission.py +70 -27
- strawberry/printer/ast_from_value.py +4 -1
- strawberry/printer/printer.py +8 -5
- strawberry/quart/views.py +3 -0
- strawberry/relay/exceptions.py +7 -0
- strawberry/relay/fields.py +70 -45
- strawberry/relay/types.py +78 -78
- strawberry/relay/utils.py +10 -1
- strawberry/resolvers.py +3 -0
- strawberry/sanic/context.py +3 -0
- strawberry/sanic/utils.py +10 -8
- strawberry/sanic/views.py +4 -2
- strawberry/scalars.py +6 -2
- strawberry/schema/base.py +7 -4
- strawberry/schema/compat.py +12 -2
- strawberry/schema/config.py +3 -0
- strawberry/schema/exceptions.py +3 -0
- strawberry/schema/execute.py +3 -0
- strawberry/schema/name_converter.py +12 -9
- strawberry/schema/schema.py +46 -9
- strawberry/schema/schema_converter.py +16 -14
- strawberry/schema/types/base_scalars.py +3 -1
- strawberry/schema/types/concrete_type.py +4 -4
- strawberry/schema/types/scalar.py +8 -1
- strawberry/schema/validation_rules/one_of.py +3 -0
- strawberry/schema_codegen/__init__.py +3 -0
- strawberry/schema_directive.py +2 -2
- strawberry/starlite/controller.py +3 -0
- strawberry/starlite/handlers/__init__.py +0 -0
- strawberry/starlite/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/starlite/handlers/graphql_ws_handler.py +3 -0
- strawberry/subscriptions/__init__.py +6 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py +5 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +12 -17
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +21 -25
- strawberry/subscriptions/protocols/graphql_ws/__init__.py +14 -0
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +8 -5
- strawberry/subscriptions/protocols/graphql_ws/types.py +11 -0
- strawberry/test/client.py +44 -29
- strawberry/tools/create_type.py +27 -8
- strawberry/tools/merge_types.py +5 -3
- strawberry/types/__init__.py +8 -1
- strawberry/{arguments.py → types/arguments.py} +44 -13
- strawberry/{auto.py → types/auto.py} +21 -3
- strawberry/types/{types.py → base.py} +234 -10
- strawberry/{enum.py → types/enum.py} +69 -9
- strawberry/types/execution.py +3 -0
- strawberry/{field.py → types/field.py} +46 -23
- strawberry/types/fields/resolver.py +2 -2
- strawberry/types/graphql.py +3 -0
- strawberry/types/info.py +50 -7
- strawberry/{lazy_type.py → types/lazy_type.py} +56 -4
- strawberry/types/mutation.py +351 -0
- strawberry/types/nodes.py +4 -2
- strawberry/{object_type.py → types/object_type.py} +108 -29
- strawberry/{private.py → types/private.py} +13 -6
- strawberry/{custom_scalar.py → types/scalar.py} +39 -23
- strawberry/types/type_resolver.py +21 -16
- strawberry/{union.py → types/union.py} +24 -9
- strawberry/{unset.py → types/unset.py} +20 -0
- strawberry/utils/aio.py +8 -0
- strawberry/utils/await_maybe.py +3 -0
- strawberry/utils/dataclasses.py +3 -0
- strawberry/utils/debug.py +5 -2
- strawberry/utils/deprecations.py +3 -0
- strawberry/utils/graphql_lexer.py +3 -0
- strawberry/utils/importer.py +3 -0
- strawberry/utils/inspect.py +39 -30
- strawberry/utils/logging.py +3 -0
- strawberry/utils/operation.py +3 -0
- strawberry/utils/str_converters.py +3 -0
- strawberry/utils/typing.py +33 -16
- {strawberry_graphql-0.235.2.dist-info → strawberry_graphql-0.236.1.dist-info}/METADATA +1 -1
- strawberry_graphql-0.236.1.dist-info/RECORD +255 -0
- strawberry/mutation.py +0 -8
- strawberry/type.py +0 -232
- strawberry_graphql-0.235.2.dist-info/RECORD +0 -252
- {strawberry_graphql-0.235.2.dist-info → strawberry_graphql-0.236.1.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.235.2.dist-info → strawberry_graphql-0.236.1.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.235.2.dist-info → strawberry_graphql-0.236.1.dist-info}/entry_points.txt +0 -0
@@ -16,9 +16,8 @@ from typing import (
|
|
16
16
|
)
|
17
17
|
|
18
18
|
from strawberry.exceptions import InvalidUnionTypeError
|
19
|
-
from strawberry.
|
20
|
-
|
21
|
-
from .utils.str_converters import to_camel_case
|
19
|
+
from strawberry.types.base import StrawberryType
|
20
|
+
from strawberry.utils.str_converters import to_camel_case
|
22
21
|
|
23
22
|
if TYPE_CHECKING:
|
24
23
|
from graphql import GraphQLScalarType
|
@@ -166,30 +165,44 @@ def scalar(
|
|
166
165
|
) -> Any:
|
167
166
|
"""Annotates a class or type as a GraphQL custom scalar.
|
168
167
|
|
168
|
+
Args:
|
169
|
+
cls: The class or type to annotate.
|
170
|
+
name: The GraphQL name of the scalar.
|
171
|
+
description: The description of the scalar.
|
172
|
+
specified_by_url: The URL of the specification.
|
173
|
+
serialize: The function to serialize the scalar.
|
174
|
+
parse_value: The function to parse the value.
|
175
|
+
parse_literal: The function to parse the literal.
|
176
|
+
directives: The directives to apply to the scalar.
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
The decorated class or type.
|
180
|
+
|
169
181
|
Example usages:
|
170
182
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
>>> Base64Encoded = strawberry.scalar(
|
178
|
-
>>> NewType("Base64Encoded", bytes),
|
179
|
-
>>> serialize=base64.b64encode,
|
180
|
-
>>> parse_value=base64.b64decode
|
181
|
-
>>> )
|
182
|
-
|
183
|
-
>>> @strawberry.scalar(
|
184
|
-
>>> serialize=lambda value: ",".join(value.items),
|
185
|
-
>>> parse_value=lambda value: CustomList(value.split(","))
|
186
|
-
>>> )
|
187
|
-
>>> class CustomList:
|
188
|
-
>>> def __init__(self, items):
|
189
|
-
>>> self.items = items
|
183
|
+
```python
|
184
|
+
strawberry.scalar(
|
185
|
+
datetime.date,
|
186
|
+
serialize=lambda value: value.isoformat(),
|
187
|
+
parse_value=datetime.parse_date,
|
188
|
+
)
|
190
189
|
|
191
|
-
|
190
|
+
Base64Encoded = strawberry.scalar(
|
191
|
+
NewType("Base64Encoded", bytes),
|
192
|
+
serialize=base64.b64encode,
|
193
|
+
parse_value=base64.b64decode,
|
194
|
+
)
|
192
195
|
|
196
|
+
|
197
|
+
@strawberry.scalar(
|
198
|
+
serialize=lambda value: ",".join(value.items),
|
199
|
+
parse_value=lambda value: CustomList(value.split(",")),
|
200
|
+
)
|
201
|
+
class CustomList:
|
202
|
+
def __init__(self, items):
|
203
|
+
self.items = items
|
204
|
+
```
|
205
|
+
"""
|
193
206
|
if parse_value is None:
|
194
207
|
parse_value = cls
|
195
208
|
|
@@ -209,3 +222,6 @@ def scalar(
|
|
209
222
|
return wrap
|
210
223
|
|
211
224
|
return wrap(cls)
|
225
|
+
|
226
|
+
|
227
|
+
__all__ = ["ScalarDefinition", "ScalarWrapper", "scalar"]
|
@@ -10,16 +10,16 @@ from strawberry.exceptions import (
|
|
10
10
|
FieldWithResolverAndDefaultValueError,
|
11
11
|
PrivateStrawberryFieldError,
|
12
12
|
)
|
13
|
-
from strawberry.
|
14
|
-
from strawberry.
|
15
|
-
from strawberry.
|
16
|
-
from strawberry.unset import UNSET
|
13
|
+
from strawberry.types.base import has_object_definition
|
14
|
+
from strawberry.types.field import StrawberryField
|
15
|
+
from strawberry.types.private import is_private
|
16
|
+
from strawberry.types.unset import UNSET
|
17
17
|
|
18
18
|
|
19
19
|
def _get_fields(
|
20
20
|
cls: Type[Any], original_type_annotations: Dict[str, Type[Any]]
|
21
21
|
) -> List[StrawberryField]:
|
22
|
-
"""Get all the strawberry fields off a strawberry.type cls
|
22
|
+
"""Get all the strawberry fields off a strawberry.type cls.
|
23
23
|
|
24
24
|
This function returns a list of StrawberryFields (one for each field item), while
|
25
25
|
also paying attention the name and typing of the field.
|
@@ -27,16 +27,19 @@ def _get_fields(
|
|
27
27
|
StrawberryFields can be defined on a strawberry.type class as either a dataclass-
|
28
28
|
style field or using strawberry.field as a decorator.
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
```python
|
31
|
+
import strawberry
|
32
|
+
|
33
|
+
|
34
|
+
@strawberry.type
|
35
|
+
class Query:
|
36
|
+
type_1a: int = 5
|
37
|
+
type_1b: int = strawberry.field(...)
|
38
|
+
type_1c: int = strawberry.field(resolver=...)
|
39
|
+
|
40
|
+
@strawberry.field
|
41
|
+
def type_2(self) -> int: ...
|
42
|
+
```
|
40
43
|
|
41
44
|
Type #1:
|
42
45
|
A pure dataclass-style field. Will not have a StrawberryField; one will need to
|
@@ -51,7 +54,6 @@ def _get_fields(
|
|
51
54
|
passing a named function (i.e. not an anonymous lambda) to strawberry.field
|
52
55
|
(typically as a decorator).
|
53
56
|
"""
|
54
|
-
|
55
57
|
fields: Dict[str, StrawberryField] = {}
|
56
58
|
|
57
59
|
# before trying to find any fields, let's first add the fields defined in
|
@@ -163,3 +165,6 @@ def _get_fields(
|
|
163
165
|
fields[field_name] = field
|
164
166
|
|
165
167
|
return list(fields.values())
|
168
|
+
|
169
|
+
|
170
|
+
__all__ = ["_get_fields"]
|
@@ -31,12 +31,12 @@ from strawberry.exceptions import (
|
|
31
31
|
WrongReturnTypeForUnion,
|
32
32
|
)
|
33
33
|
from strawberry.exceptions.handler import should_use_rich_exceptions
|
34
|
-
from strawberry.
|
35
|
-
from strawberry.type import (
|
34
|
+
from strawberry.types.base import (
|
36
35
|
StrawberryOptional,
|
37
36
|
StrawberryType,
|
38
37
|
has_object_definition,
|
39
38
|
)
|
39
|
+
from strawberry.types.lazy_type import LazyType
|
40
40
|
|
41
41
|
if TYPE_CHECKING:
|
42
42
|
from graphql import (
|
@@ -173,7 +173,7 @@ class StrawberryUnion(StrawberryType):
|
|
173
173
|
) -> str:
|
174
174
|
assert isinstance(type_, GraphQLUnionType)
|
175
175
|
|
176
|
-
from strawberry.types.
|
176
|
+
from strawberry.types.base import StrawberryObjectDefinition
|
177
177
|
|
178
178
|
# If the type given is not an Object type, try resolving using `is_type_of`
|
179
179
|
# defined on the union's inner types
|
@@ -250,15 +250,27 @@ def union(
|
|
250
250
|
) -> StrawberryUnion:
|
251
251
|
"""Creates a new named Union type.
|
252
252
|
|
253
|
+
Args:
|
254
|
+
name: The GraphQL name of the Union type.
|
255
|
+
types: The types that the Union can be.
|
256
|
+
(Deprecated, use `Annotated[U, strawberry.union("Name")]` instead)
|
257
|
+
description: The GraphQL description of the Union type.
|
258
|
+
directives: The directives to attach to the Union type.
|
259
|
+
|
253
260
|
Example usages:
|
254
261
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
262
|
+
```python
|
263
|
+
import strawberry
|
264
|
+
from typing import Annotated
|
265
|
+
|
266
|
+
@strawberry.type
|
267
|
+
class A: ...
|
268
|
+
|
269
|
+
@strawberry.type
|
270
|
+
class B: ...
|
261
271
|
|
272
|
+
MyUnion = Annotated[A | B, strawberry.union("Name")]
|
273
|
+
"""
|
262
274
|
if types is None:
|
263
275
|
union = StrawberryUnion(
|
264
276
|
name=name,
|
@@ -299,3 +311,6 @@ def union(
|
|
299
311
|
description=description,
|
300
312
|
directives=directives,
|
301
313
|
)
|
314
|
+
|
315
|
+
|
316
|
+
__all__ = ["StrawberryUnion", "union"]
|
@@ -28,6 +28,26 @@ class UnsetType:
|
|
28
28
|
|
29
29
|
|
30
30
|
UNSET: Any = UnsetType()
|
31
|
+
"""A special value that can be used to represent an unset value in a field or argument.
|
32
|
+
Similar to `undefined` in JavaScript, this value can be used to differentiate between
|
33
|
+
a field that was not set and a field that was set to `None` or `null`.
|
34
|
+
|
35
|
+
Example:
|
36
|
+
|
37
|
+
```python
|
38
|
+
import strawberry
|
39
|
+
|
40
|
+
|
41
|
+
@strawberry.input
|
42
|
+
class UserInput:
|
43
|
+
name: str | None = strawberry.UNSET
|
44
|
+
age: int | None = strawberry.UNSET
|
45
|
+
```
|
46
|
+
|
47
|
+
In the example above, if `name` or `age` are not provided when creating a `UserInput`
|
48
|
+
object, they will be set to `UNSET` instead of `None`. Use `is UNSET` to check
|
49
|
+
whether a value is unset.
|
50
|
+
"""
|
31
51
|
|
32
52
|
|
33
53
|
def _deprecated_is_unset(value: Any) -> bool:
|
strawberry/utils/aio.py
CHANGED
@@ -67,3 +67,11 @@ async def resolve_awaitable(
|
|
67
67
|
) -> _R:
|
68
68
|
"""Resolves an awaitable object and calls a callback with the resolved value."""
|
69
69
|
return callback(await awaitable)
|
70
|
+
|
71
|
+
|
72
|
+
__all__ = [
|
73
|
+
"aenumerate",
|
74
|
+
"aislice",
|
75
|
+
"asyncgen_to_list",
|
76
|
+
"resolve_awaitable",
|
77
|
+
]
|
strawberry/utils/await_maybe.py
CHANGED
strawberry/utils/dataclasses.py
CHANGED
strawberry/utils/debug.py
CHANGED
@@ -14,8 +14,8 @@ def pretty_print_graphql_operation(
|
|
14
14
|
) -> None:
|
15
15
|
"""Pretty print a GraphQL operation using pygments.
|
16
16
|
|
17
|
-
Won't print introspection operation to prevent noise in the output.
|
18
|
-
|
17
|
+
Won't print introspection operation to prevent noise in the output.
|
18
|
+
"""
|
19
19
|
try:
|
20
20
|
from pygments import highlight, lexers
|
21
21
|
from pygments.formatters import Terminal256Formatter
|
@@ -41,3 +41,6 @@ def pretty_print_graphql_operation(
|
|
41
41
|
print( # noqa: T201
|
42
42
|
highlight(variables_json, lexers.JsonLexer(), Terminal256Formatter())
|
43
43
|
)
|
44
|
+
|
45
|
+
|
46
|
+
__all__ = ["pretty_print_graphql_operation"]
|
strawberry/utils/deprecations.py
CHANGED
strawberry/utils/importer.py
CHANGED
strawberry/utils/inspect.py
CHANGED
@@ -12,7 +12,6 @@ from typing import (
|
|
12
12
|
)
|
13
13
|
from typing_extensions import get_args
|
14
14
|
|
15
|
-
from strawberry.type import has_object_definition
|
16
15
|
from strawberry.utils.typing import is_generic_alias
|
17
16
|
|
18
17
|
|
@@ -29,8 +28,7 @@ def in_async_context() -> bool:
|
|
29
28
|
|
30
29
|
@lru_cache(maxsize=250)
|
31
30
|
def get_func_args(func: Callable[[Any], Any]) -> List[str]:
|
32
|
-
"""Returns a list of arguments for the function"""
|
33
|
-
|
31
|
+
"""Returns a list of arguments for the function."""
|
34
32
|
sig = inspect.signature(func)
|
35
33
|
|
36
34
|
return [
|
@@ -45,38 +43,46 @@ def get_specialized_type_var_map(cls: type) -> Optional[Dict[str, type]]:
|
|
45
43
|
|
46
44
|
Consider the following:
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
```python
|
47
|
+
class Foo(Generic[T]): ...
|
48
|
+
|
49
|
+
|
50
|
+
class Bar(Generic[K]): ...
|
51
|
+
|
52
|
+
|
53
|
+
class IntBar(Bar[int]): ...
|
54
|
+
|
55
|
+
|
56
|
+
class IntBarSubclass(IntBar): ...
|
57
|
+
|
58
|
+
|
59
|
+
class IntBarFoo(IntBar, Foo[str]): ...
|
60
|
+
```
|
63
61
|
|
64
62
|
This would return:
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
64
|
+
```python
|
65
|
+
get_specialized_type_var_map(object)
|
66
|
+
# None
|
67
|
+
|
68
|
+
get_specialized_type_var_map(Foo)
|
69
|
+
# {}
|
70
|
+
|
71
|
+
get_specialized_type_var_map(Bar)
|
72
|
+
# {~T: ~T}
|
73
|
+
|
74
|
+
get_specialized_type_var_map(IntBar)
|
75
|
+
# {~T: int}
|
78
76
|
|
77
|
+
get_specialized_type_var_map(IntBarSubclass)
|
78
|
+
# {~T: int}
|
79
|
+
|
80
|
+
get_specialized_type_var_map(IntBarFoo)
|
81
|
+
# {~T: int, ~K: str}
|
82
|
+
```
|
79
83
|
"""
|
84
|
+
from strawberry.types.base import has_object_definition
|
85
|
+
|
80
86
|
orig_bases = getattr(cls, "__orig_bases__", None)
|
81
87
|
if orig_bases is None:
|
82
88
|
# Specialized generic aliases will not have __orig_bases__
|
@@ -114,3 +120,6 @@ def get_specialized_type_var_map(cls: type) -> Optional[Dict[str, type]]:
|
|
114
120
|
)
|
115
121
|
|
116
122
|
return type_var_map
|
123
|
+
|
124
|
+
|
125
|
+
__all__ = ["in_async_context", "get_func_args", "get_specialized_type_var_map"]
|
strawberry/utils/logging.py
CHANGED
strawberry/utils/operation.py
CHANGED
@@ -24,3 +24,6 @@ def capitalize_first(name: str) -> str:
|
|
24
24
|
def to_snake_case(name: str) -> str:
|
25
25
|
name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
|
26
26
|
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower()
|
27
|
+
|
28
|
+
|
29
|
+
__all__ = ["to_camel_case", "to_kebab_case", "capitalize_first", "to_snake_case"]
|
strawberry/utils/typing.py
CHANGED
@@ -44,10 +44,13 @@ def get_generic_alias(type_: Type) -> Type:
|
|
44
44
|
Given a type, its generic alias from `typing` module will be returned
|
45
45
|
if it exists. For example:
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
```python
|
48
|
+
get_generic_alias(list)
|
49
|
+
# typing.List
|
50
|
+
|
51
|
+
get_generic_alias(dict)
|
52
|
+
# typing.Dict
|
53
|
+
```
|
51
54
|
|
52
55
|
This is mostly useful for python versions prior to 3.9, to get a version
|
53
56
|
of a concrete type which supports `__class_getitem__`. In 3.9+ types like
|
@@ -78,16 +81,14 @@ def is_generic_alias(type_: Any) -> TypeGuard[_GenericAlias]:
|
|
78
81
|
|
79
82
|
|
80
83
|
def is_list(annotation: object) -> bool:
|
81
|
-
"""Returns True if annotation is a List"""
|
82
|
-
|
84
|
+
"""Returns True if annotation is a List."""
|
83
85
|
annotation_origin = getattr(annotation, "__origin__", None)
|
84
86
|
|
85
87
|
return annotation_origin == list
|
86
88
|
|
87
89
|
|
88
90
|
def is_union(annotation: object) -> bool:
|
89
|
-
"""Returns True if annotation is a Union"""
|
90
|
-
|
91
|
+
"""Returns True if annotation is a Union."""
|
91
92
|
# this check is needed because unions declared with the new syntax `A | B`
|
92
93
|
# don't have a `__origin__` property on them, but they are instances of
|
93
94
|
# `UnionType`, which is only available in Python 3.10+
|
@@ -105,8 +106,7 @@ def is_union(annotation: object) -> bool:
|
|
105
106
|
|
106
107
|
|
107
108
|
def is_optional(annotation: Type) -> bool:
|
108
|
-
"""Returns True if the annotation is Optional[SomeType]"""
|
109
|
-
|
109
|
+
"""Returns True if the annotation is Optional[SomeType]."""
|
110
110
|
# Optionals are represented as unions
|
111
111
|
|
112
112
|
if not is_union(annotation):
|
@@ -153,7 +153,6 @@ def is_generic_subclass(annotation: type) -> bool:
|
|
153
153
|
|
154
154
|
def is_generic(annotation: type) -> bool:
|
155
155
|
"""Returns True if the annotation is or extends a generic."""
|
156
|
-
|
157
156
|
return (
|
158
157
|
# TODO: These two lines appear to have the same effect. When will an
|
159
158
|
# annotation have parameters but not satisfy the first condition?
|
@@ -164,7 +163,6 @@ def is_generic(annotation: type) -> bool:
|
|
164
163
|
|
165
164
|
def is_type_var(annotation: Type) -> bool:
|
166
165
|
"""Returns True if the annotation is a TypeVar."""
|
167
|
-
|
168
166
|
return isinstance(annotation, TypeVar)
|
169
167
|
|
170
168
|
|
@@ -259,7 +257,7 @@ def _get_namespace_from_ast(
|
|
259
257
|
globalns: Optional[Dict] = None,
|
260
258
|
localns: Optional[Dict] = None,
|
261
259
|
) -> Dict[str, Type]:
|
262
|
-
from strawberry.lazy_type import StrawberryLazyReference
|
260
|
+
from strawberry.types.lazy_type import StrawberryLazyReference
|
263
261
|
|
264
262
|
extra = {}
|
265
263
|
|
@@ -328,9 +326,9 @@ def eval_type(
|
|
328
326
|
localns: Optional[Dict] = None,
|
329
327
|
) -> Type:
|
330
328
|
"""Evaluates a type, resolving forward references."""
|
331
|
-
from strawberry.auto import StrawberryAuto
|
332
|
-
from strawberry.lazy_type import StrawberryLazyReference
|
333
|
-
from strawberry.private import StrawberryPrivate
|
329
|
+
from strawberry.types.auto import StrawberryAuto
|
330
|
+
from strawberry.types.lazy_type import StrawberryLazyReference
|
331
|
+
from strawberry.types.private import StrawberryPrivate
|
334
332
|
|
335
333
|
globalns = globalns or {}
|
336
334
|
# If this is not a string, maybe its args are (e.g. List["Foo"])
|
@@ -411,3 +409,22 @@ def eval_type(
|
|
411
409
|
)
|
412
410
|
|
413
411
|
return type_
|
412
|
+
|
413
|
+
|
414
|
+
__all__ = [
|
415
|
+
"get_generic_alias",
|
416
|
+
"is_generic_alias",
|
417
|
+
"is_list",
|
418
|
+
"is_union",
|
419
|
+
"is_optional",
|
420
|
+
"get_optional_annotation",
|
421
|
+
"get_list_annotation",
|
422
|
+
"is_concrete_generic",
|
423
|
+
"is_generic_subclass",
|
424
|
+
"is_generic",
|
425
|
+
"is_type_var",
|
426
|
+
"is_classvar",
|
427
|
+
"type_has_annotation",
|
428
|
+
"get_parameters",
|
429
|
+
"eval_type",
|
430
|
+
]
|