Skip to content

Commit 9d18518

Browse files
committed
WIP
1 parent d4ac1a0 commit 9d18518

File tree

5 files changed

+50
-77
lines changed

5 files changed

+50
-77
lines changed

strawberry/types/_dataclasses_field.py

Lines changed: 0 additions & 36 deletions
This file was deleted.

strawberry/types/field.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,11 @@ def __init__(
8989
directives: Sequence[object] = (),
9090
extensions: list[FieldExtension] = (), # type: ignore
9191
) -> None:
92-
kwargs: Any = {}
92+
self.default = default
9393
self.default_factory = default_factory
94+
self.graphql_name = graphql_name
9495
self.metadata = metadata
95-
self.default = default
9696

97-
# kw_only was added to python 3.10 and it is required
98-
if sys.version_info >= (3, 10):
99-
kwargs["kw_only"] = dataclasses.MISSING
100-
101-
self.graphql_name = graphql_name
102-
self.name: Optional[str] = None # Initialize the name attribute
10397
if python_name is not None:
10498
self.python_name = python_name
10599

@@ -145,6 +139,27 @@ def __init__(
145139
)
146140
self.deprecation_reason = deprecation_reason
147141

142+
def as_dataclass_field(self) -> dataclasses.Field:
143+
# basic fields are fields with no provided resolver
144+
is_basic_field = not self.base_resolver
145+
146+
kwargs: Any = {}
147+
148+
# kw_only was added to python 3.10 and it is required
149+
if sys.version_info >= (3, 10):
150+
kwargs["kw_only"] = dataclasses.MISSING
151+
152+
return dataclasses.field(
153+
default=self.default,
154+
default_factory=self.default_factory, # type: ignore
155+
init=is_basic_field,
156+
repr=is_basic_field,
157+
compare=is_basic_field,
158+
hash=None,
159+
metadata=self.metadata or {},
160+
**kwargs,
161+
)
162+
148163
def __copy__(self) -> Self:
149164
new_field = type(self)(
150165
python_name=self.python_name,

strawberry/types/info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def __class_getitem__(cls, types: Union[type, tuple[type, ...]]) -> type[Info]:
7878
https://discuss.python.org/t/passing-only-one-typevar-of-two-when-using-defaults/49134
7979
"""
8080
if not isinstance(types, tuple):
81-
types = (types, Any) # type: ignore
81+
types = (types, Any)
8282

8383
return super().__class_getitem__(types) # type: ignore
8484

strawberry/types/object_type.py

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from strawberry.utils.deprecations import DEPRECATION_MESSAGES, DeprecatedDescriptor
2626
from strawberry.utils.str_converters import to_camel_case
2727

28-
from ._dataclasses_field import StrawberryDataclassField
2928
from .base import StrawberryObjectDefinition
3029
from .field import StrawberryField, field
3130
from .type_resolver import _get_fields
@@ -134,17 +133,22 @@ def _inject_default_for_maybe_annotations(
134133
setattr(cls, name, None)
135134

136135

137-
def _convert_field_annotations_to_dataclass_fields(
138-
cls: builtins.type[T], annotations: dict[str, Any]
136+
def _preprocess_type(
137+
cls: T, original_type_annotations: dict[str, Any], is_input: bool
139138
) -> None:
139+
annotations = getattr(cls, "__annotations__", {})
140+
140141
for field_name in annotations:
141142
field = getattr(cls, field_name, None)
142143

143144
if field and isinstance(field, StrawberryField):
144-
dataclass_field = StrawberryDataclassField.from_strawberry_field(field)
145-
annotations[field_name] = dataclass_field.type
145+
if field.type_annotation:
146+
original_type_annotations[field_name] = field.type_annotation.annotation
147+
148+
field = field.as_dataclass_field()
146149

147-
setattr(cls, field_name, dataclass_field)
150+
if is_input:
151+
_inject_default_for_maybe_annotations(cls, annotations)
148152

149153

150154
def _process_type(
@@ -156,8 +160,20 @@ def _process_type(
156160
description: Optional[str] = None,
157161
directives: Optional[Sequence[object]] = (),
158162
extend: bool = False,
159-
original_type_annotations: Optional[dict[str, Any]] = None,
160163
) -> T:
164+
# when running `_wrap_dataclass` we lose some of the information about the
165+
# the passed types, especially the type_annotation inside the StrawberryField
166+
# this makes it impossible to customise the field type, like this:
167+
# >>> @strawberry.type
168+
# >>> class Query:
169+
# >>> a: int = strawberry.field(graphql_type=str)
170+
# so we need to extract the information before running `_wrap_dataclass`
171+
original_type_annotations: dict[str, Any] = {}
172+
173+
_preprocess_type(cls, original_type_annotations, is_input)
174+
175+
cls = _wrap_dataclass(cls)
176+
161177
name = name or to_camel_case(cls.__name__)
162178
original_type_annotations = original_type_annotations or {}
163179

@@ -300,33 +316,14 @@ def wrap(cls: T) -> T:
300316
exc = ObjectIsNotClassError.type
301317
raise exc(cls)
302318

303-
# when running `_wrap_dataclass` we lose some of the information about the
304-
# the passed types, especially the type_annotation inside the StrawberryField
305-
# this makes it impossible to customise the field type, like this:
306-
# >>> @strawberry.type
307-
# >>> class Query:
308-
# >>> a: int = strawberry.field(graphql_type=str)
309-
# so we need to extract the information before running `_wrap_dataclass`
310-
original_type_annotations: dict[str, Any] = {}
311-
312-
annotations = getattr(cls, "__annotations__", {})
313-
314-
_convert_field_annotations_to_dataclass_fields(cls, annotations)
315-
316-
if is_input:
317-
_inject_default_for_maybe_annotations(cls, annotations)
318-
319-
wrapped = _wrap_dataclass(cls)
320-
321319
return _process_type( # type: ignore
322-
wrapped,
320+
cls,
323321
name=name,
324322
is_input=is_input,
325323
is_interface=is_interface,
326324
description=description,
327325
directives=directives,
328326
extend=extend,
329-
original_type_annotations=original_type_annotations,
330327
)
331328

332329
if cls is None:

strawberry/utils/typing.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,7 @@ def is_concrete_generic(annotation: type) -> bool:
130130

131131

132132
def is_generic_subclass(annotation: type) -> bool:
133-
return isinstance(annotation, type) and issubclass(
134-
annotation,
135-
Generic, # type:ignore
136-
)
133+
return isinstance(annotation, type) and issubclass(annotation, Generic)
137134

138135

139136
def is_generic(annotation: type) -> bool:
@@ -185,7 +182,7 @@ def get_parameters(annotation: type) -> Union[tuple[object], tuple[()]]:
185182
and issubclass(annotation, Generic) # type:ignore
186183
and annotation is not Generic
187184
):
188-
return annotation.__parameters__ # type: ignore[union-attr]
185+
return annotation.__parameters__
189186
return () # pragma: no cover
190187

191188

0 commit comments

Comments
 (0)