We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Failure when returning List[List[int]] as a strawberry type in a query
The follow code doesn't run

strawberry server schema
Then running a graphiql query is sufficient to reproduce this error.

error message TypeError: 'float' object is not iterable

```python
@strawberry.type(description="list of list breaks it")
class Polygon:
    polygon_of_death: typing.List[typing.List[float]]


def get_polygon() -> Polygon:
    not_polygon_of_death = Polygon([])
    polygon_of_death = Polygon(polygon_of_death=[[2.0,6.0]])
    return polygon_of_death


@strawberry.type(description="This is the root level query description")
class Query:
    get_polygons: Polygon = strawberry.field(resolver=get_polygon)


schema = strawberry.Schema(query=Query)

```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `strawberry/field.py`
Content:
```
1 import dataclasses
2 import enum
3 import typing
4 from inspect import iscoroutine
5 from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Type, Union
6 
7 from graphql import GraphQLResolveInfo
8 
9 from strawberry.arguments import UNSET, convert_arguments
10 from strawberry.types.info import Info
11 from strawberry.utils.typing import get_parameters, has_type_var, is_type_var
12 
13 from .arguments import StrawberryArgument
14 from .permission import BasePermission
15 from .types.fields.resolver import StrawberryResolver
16 from .types.types import FederationFieldParams
17 from .union import StrawberryUnion
18 from .utils.str_converters import to_camel_case
19 
20 
21 _RESOLVER_TYPE = Union[StrawberryResolver, Callable]
22 
23 
24 class StrawberryField(dataclasses.Field):
25     def __init__(
26         self,
27         python_name: Optional[str],
28         graphql_name: Optional[str],
29         type_: Optional[Union[Type, StrawberryUnion]],
30         origin: Optional[Union[Type, Callable]] = None,
31         child: Optional["StrawberryField"] = None,
32         is_subscription: bool = False,
33         is_optional: bool = False,
34         is_child_optional: bool = False,
35         is_list: bool = False,
36         is_union: bool = False,
37         federation: FederationFieldParams = None,
38         description: Optional[str] = None,
39         base_resolver: Optional[StrawberryResolver] = None,
40         permission_classes: List[Type[BasePermission]] = (),  # type: ignore
41         default_value: Any = UNSET,
42         default_factory: Union[Callable, object] = UNSET,
43         deprecation_reason: Optional[str] = None,
44     ):
45         federation = federation or FederationFieldParams()
46 
47         # basic fields are fields with no provided resolver
48         is_basic_field = not base_resolver
49 
50         super().__init__(  # type: ignore
51             default=(default_value if default_value != UNSET else dataclasses.MISSING),
52             default_factory=(
53                 default_factory if default_factory != UNSET else dataclasses.MISSING
54             ),
55             init=is_basic_field,
56             repr=is_basic_field,
57             compare=is_basic_field,
58             hash=None,
59             metadata=None,
60         )
61 
62         self._graphql_name = graphql_name
63         if python_name is not None:
64             self.python_name = python_name
65         if type_ is not None:
66             # TODO: Clean up the typing around StrawberryField.type
67             self.type = typing.cast(type, type_)
68 
69         self.description: Optional[str] = description
70         self.origin: Optional[Union[Type, Callable]] = origin
71 
72         self._base_resolver: Optional[StrawberryResolver] = None
73         if base_resolver is not None:
74             self.base_resolver = base_resolver
75 
76         self.default_value = default_value
77 
78         self.child = child
79         self.is_child_optional = is_child_optional
80 
81         self.is_list = is_list
82         self.is_optional = is_optional
83         self.is_subscription = is_subscription
84         self.is_union = is_union
85 
86         self.federation: FederationFieldParams = federation
87         self.permission_classes: List[Type[BasePermission]] = list(permission_classes)
88 
89         self.deprecation_reason = deprecation_reason
90 
91     def __call__(self, resolver: _RESOLVER_TYPE) -> "StrawberryField":
92         """Add a resolver to the field"""
93 
94         # Allow for StrawberryResolvers or bare functions to be provided
95         if not isinstance(resolver, StrawberryResolver):
96             resolver = StrawberryResolver(resolver)
97 
98         self.base_resolver = resolver
99         self.type = resolver.type
100 
101         return self
102 
103     @property
104     def arguments(self) -> List[StrawberryArgument]:
105         if not self.base_resolver:
106             return []
107 
108         return self.base_resolver.arguments
109 
110     @property
111     def graphql_name(self) -> Optional[str]:
112         if self._graphql_name:
113             return self._graphql_name
114         if self.python_name:
115             return to_camel_case(self.python_name)
116         if self.base_resolver:
117             return to_camel_case(self.base_resolver.name)
118         return None
119 
120     @property
121     def python_name(self) -> str:
122         return self.name
123 
124     @python_name.setter
125     def python_name(self, name: str) -> None:
126         self.name = name
127 
128     @property
129     def base_resolver(self) -> Optional[StrawberryResolver]:
130         return self._base_resolver
131 
132     @base_resolver.setter
133     def base_resolver(self, resolver: StrawberryResolver) -> None:
134         self._base_resolver = resolver
135         self.origin = resolver.wrapped_func
136 
137         # Don't add field to __init__, __repr__ and __eq__ once it has a resolver
138         self.init = False
139         self.compare = False
140         self.repr = False
141 
142         # TODO: See test_resolvers.test_raises_error_when_argument_annotation_missing
143         #       (https://github.com/strawberry-graphql/strawberry/blob/8e102d3/tests/types/test_resolvers.py#L89-L98)
144         #
145         #       Currently we expect the exception to be thrown when the StrawberryField
146         #       is constructed, but this only happens if we explicitly retrieve the
147         #       arguments.
148         #
149         #       If we want to change when the exception is thrown, this line can be
150         #       removed.
151         _ = resolver.arguments
152 
153     @property
154     def type_params(self) -> Optional[List[Type]]:
155         if self.is_list:
156             assert self.child is not None
157             return self.child.type_params
158 
159         if isinstance(self.type, StrawberryUnion):
160             types = self.type.types
161             type_vars = [t for t in types if is_type_var(t)]
162 
163             if type_vars:
164                 return type_vars
165 
166         if is_type_var(self.type):
167             return [self.type]
168 
169         if has_type_var(self.type):
170             return get_parameters(self.type)
171 
172         return None
173 
174     def _get_arguments(
175         self, kwargs: Dict[str, Any], source: Any, info: Any
176     ) -> Tuple[List[Any], Dict[str, Any]]:
177         assert self.base_resolver is not None
178 
179         kwargs = convert_arguments(kwargs, self.arguments)
180 
181         # the following code allows to omit info and root arguments
182         # by inspecting the original resolver arguments,
183         # if it asks for self, the source will be passed as first argument
184         # if it asks for root, the source it will be passed as kwarg
185         # if it asks for info, the info will be passed as kwarg
186 
187         args = []
188 
189         if self.base_resolver.has_self_arg:
190             args.append(source)
191 
192         if self.base_resolver.has_root_arg:
193             kwargs["root"] = source
194 
195         if self.base_resolver.has_info_arg:
196             kwargs["info"] = info
197 
198         return args, kwargs
199 
200     def get_result(
201         self, kwargs: Dict[str, Any], source: Any, info: Any
202     ) -> Union[Awaitable[Any], Any]:
203         """
204         Calls the resolver defined for the StrawberryField. If the field doesn't have a
205         resolver defined we default to using getattr on `source`.
206         """
207 
208         if self.base_resolver:
209             args, kwargs = self._get_arguments(kwargs, source=source, info=info)
210 
211             return self.base_resolver(*args, **kwargs)
212 
213         return getattr(source, self.python_name)
214 
215     def get_wrapped_resolver(self) -> Callable:
216         # TODO: This could potentially be handled by StrawberryResolver in the future
217         def _check_permissions(source, info: Info, **kwargs):
218             """
219             Checks if the permission should be accepted and
220             raises an exception if not
221             """
222             for permission_class in self.permission_classes:
223                 permission = permission_class()
224 
225                 if not permission.has_permission(source, info, **kwargs):
226                     message = getattr(permission, "message", None)
227                     raise PermissionError(message)
228 
229         def _convert_enums_to_values(field_: StrawberryField, result: Any) -> Any:
230             # graphql-core expects a resolver for an Enum type to return
231             # the enum's *value* (not its name or an instance of the enum).
232 
233             # short circuit to skip checks when result is falsy
234             if not result:
235                 return result
236 
237             if isinstance(result, enum.Enum):
238                 return result.value
239 
240             if field_.is_list:
241                 assert self.child is not None
242                 return [_convert_enums_to_values(self.child, item) for item in result]
243 
244             return result
245 
246         def _strawberry_info_from_graphql(info: GraphQLResolveInfo) -> Info:
247             return Info(
248                 field_name=info.field_name,
249                 field_nodes=info.field_nodes,
250                 context=info.context,
251                 root_value=info.root_value,
252                 variable_values=info.variable_values,
253                 return_type=self._get_return_type(),
254                 operation=info.operation,
255                 path=info.path,
256             )
257 
258         def _resolver(source, info: GraphQLResolveInfo, **kwargs):
259             strawberry_info = _strawberry_info_from_graphql(info)
260             _check_permissions(source, strawberry_info, **kwargs)
261 
262             result = self.get_result(kwargs=kwargs, info=strawberry_info, source=source)
263 
264             if iscoroutine(result):  # pragma: no cover
265 
266                 async def await_result(result):
267                     return _convert_enums_to_values(self, await result)
268 
269                 return await_result(result)
270 
271             result = _convert_enums_to_values(self, result)
272             return result
273 
274         _resolver._is_default = not self.base_resolver  # type: ignore
275         return _resolver
276 
277     def _get_return_type(self):
278         # using type ignore to make mypy happy,
279         # this codepath will change in future anyway, so this is ok
280         if self.is_list:
281             assert self.child
282 
283             type_ = List[self.child._get_return_type()]  # type: ignore
284         else:
285             type_ = self.type
286 
287         if self.is_optional:
288             type_ = Optional[type_]  # type: ignore
289 
290         return type_
291 
292 
293 def field(
294     resolver: Optional[_RESOLVER_TYPE] = None,
295     *,
296     name: Optional[str] = None,
297     is_subscription: bool = False,
298     description: Optional[str] = None,
299     permission_classes: Optional[List[Type[BasePermission]]] = None,
300     federation: Optional[FederationFieldParams] = None,
301     deprecation_reason: Optional[str] = None,
302     default: Any = UNSET,
303     default_factory: Union[Callable, object] = UNSET,
304 ) -> StrawberryField:
305     """Annotates a method or property as a GraphQL field.
306 
307     This is normally used inside a type declaration:
308 
309     >>> @strawberry.type:
310     >>> class X:
311     >>>     field_abc: str = strawberry.field(description="ABC")
312 
313     >>>     @strawberry.field(description="ABC")
314     >>>     def field_with_resolver(self) -> str:
315     >>>         return "abc"
316 
317     it can be used both as decorator and as a normal function.
318     """
319 
320     field_ = StrawberryField(
321         python_name=None,
322         graphql_name=name,
323         type_=None,
324         description=description,
325         is_subscription=is_subscription,
326         permission_classes=permission_classes or [],
327         federation=federation or FederationFieldParams(),
328         deprecation_reason=deprecation_reason,
329         default_value=default,
330         default_factory=default_factory,
331     )
332 
333     if resolver:
334         return field_(resolver)
335     return field_
336 
337 
338 __all__ = ["FederationFieldParams", "StrawberryField", "field"]
339
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/strawberry/field.py b/strawberry/field.py
--- a/strawberry/field.py
+++ b/strawberry/field.py
@@ -238,8 +238,8 @@
                 return result.value
 
             if field_.is_list:
-                assert self.child is not None
-                return [_convert_enums_to_values(self.child, item) for item in result]
+                assert field_.child is not None
+                return [_convert_enums_to_values(field_.child, item) for item in result]
 
             return result

{"golden_diff": "diff --git a/strawberry/field.py b/strawberry/field.py\n--- a/strawberry/field.py\n+++ b/strawberry/field.py\n@@ -238,8 +238,8 @@\n                 return result.value\n \n             if field_.is_list:\n-                assert self.child is not None\n-                return [_convert_enums_to_values(self.child, item) for item in result]\n+                assert field_.child is not None\n+                return [_convert_enums_to_values(field_.child, item) for item in result]\n \n             return result\n", "issue": "Bug: Failure when returning List[List[int]] as a strawberry type in a query\nThe follow code doesn't run\r\n\r\nstrawberry server schema\r\nThen running a graphiql query is sufficient to reproduce this error.\r\n\r\nerror message TypeError: 'float' object is not iterable\r\n\r\n```python\r\n@strawberry.type(description=\"list of list breaks it\")\r\nclass Polygon:\r\n    polygon_of_death: typing.List[typing.List[float]]\r\n\r\n\r\ndef get_polygon() -> Polygon:\r\n    not_polygon_of_death = Polygon([])\r\n    polygon_of_death = Polygon(polygon_of_death=[[2.0,6.0]])\r\n    return polygon_of_death\r\n\r\n\r\n@strawberry.type(description=\"This is the root level query description\")\r\nclass Query:\r\n    get_polygons: Polygon = strawberry.field(resolver=get_polygon)\r\n\r\n\r\nschema = strawberry.Schema(query=Query)\r\n\r\n```\r\n\r\n\n", "before_files": [{"content": "import dataclasses\nimport enum\nimport typing\nfrom inspect import iscoroutine\nfrom typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Type, Union\n\nfrom graphql import GraphQLResolveInfo\n\nfrom strawberry.arguments import UNSET, convert_arguments\nfrom strawberry.types.info import Info\nfrom strawberry.utils.typing import get_parameters, has_type_var, is_type_var\n\nfrom .arguments import StrawberryArgument\nfrom .permission import BasePermission\nfrom .types.fields.resolver import StrawberryResolver\nfrom .types.types import FederationFieldParams\nfrom .union import StrawberryUnion\nfrom .utils.str_converters import to_camel_case\n\n\n_RESOLVER_TYPE = Union[StrawberryResolver, Callable]\n\n\nclass StrawberryField(dataclasses.Field):\n    def __init__(\n        self,\n        python_name: Optional[str],\n        graphql_name: Optional[str],\n        type_: Optional[Union[Type, StrawberryUnion]],\n        origin: Optional[Union[Type, Callable]] = None,\n        child: Optional[\"StrawberryField\"] = None,\n        is_subscription: bool = False,\n        is_optional: bool = False,\n        is_child_optional: bool = False,\n        is_list: bool = False,\n        is_union: bool = False,\n        federation: FederationFieldParams = None,\n        description: Optional[str] = None,\n        base_resolver: Optional[StrawberryResolver] = None,\n        permission_classes: List[Type[BasePermission]] = (),  # type: ignore\n        default_value: Any = UNSET,\n        default_factory: Union[Callable, object] = UNSET,\n        deprecation_reason: Optional[str] = None,\n    ):\n        federation = federation or FederationFieldParams()\n\n        # basic fields are fields with no provided resolver\n        is_basic_field = not base_resolver\n\n        super().__init__(  # type: ignore\n            default=(default_value if default_value != UNSET else dataclasses.MISSING),\n            default_factory=(\n                default_factory if default_factory != UNSET else dataclasses.MISSING\n            ),\n            init=is_basic_field,\n            repr=is_basic_field,\n            compare=is_basic_field,\n            hash=None,\n            metadata=None,\n        )\n\n        self._graphql_name = graphql_name\n        if python_name is not None:\n            self.python_name = python_name\n        if type_ is not None:\n            # TODO: Clean up the typing around StrawberryField.type\n            self.type = typing.cast(type, type_)\n\n        self.description: Optional[str] = description\n        self.origin: Optional[Union[Type, Callable]] = origin\n\n        self._base_resolver: Optional[StrawberryResolver] = None\n        if base_resolver is not None:\n            self.base_resolver = base_resolver\n\n        self.default_value = default_value\n\n        self.child = child\n        self.is_child_optional = is_child_optional\n\n        self.is_list = is_list\n        self.is_optional = is_optional\n        self.is_subscription = is_subscription\n        self.is_union = is_union\n\n        self.federation: FederationFieldParams = federation\n        self.permission_classes: List[Type[BasePermission]] = list(permission_classes)\n\n        self.deprecation_reason = deprecation_reason\n\n    def __call__(self, resolver: _RESOLVER_TYPE) -> \"StrawberryField\":\n        \"\"\"Add a resolver to the field\"\"\"\n\n        # Allow for StrawberryResolvers or bare functions to be provided\n        if not isinstance(resolver, StrawberryResolver):\n            resolver = StrawberryResolver(resolver)\n\n        self.base_resolver = resolver\n        self.type = resolver.type\n\n        return self\n\n    @property\n    def arguments(self) -> List[StrawberryArgument]:\n        if not self.base_resolver:\n            return []\n\n        return self.base_resolver.arguments\n\n    @property\n    def graphql_name(self) -> Optional[str]:\n        if self._graphql_name:\n            return self._graphql_name\n        if self.python_name:\n            return to_camel_case(self.python_name)\n        if self.base_resolver:\n            return to_camel_case(self.base_resolver.name)\n        return None\n\n    @property\n    def python_name(self) -> str:\n        return self.name\n\n    @python_name.setter\n    def python_name(self, name: str) -> None:\n        self.name = name\n\n    @property\n    def base_resolver(self) -> Optional[StrawberryResolver]:\n        return self._base_resolver\n\n    @base_resolver.setter\n    def base_resolver(self, resolver: StrawberryResolver) -> None:\n        self._base_resolver = resolver\n        self.origin = resolver.wrapped_func\n\n        # Don't add field to __init__, __repr__ and __eq__ once it has a resolver\n        self.init = False\n        self.compare = False\n        self.repr = False\n\n        # TODO: See test_resolvers.test_raises_error_when_argument_annotation_missing\n        #       (https://github.com/strawberry-graphql/strawberry/blob/8e102d3/tests/types/test_resolvers.py#L89-L98)\n        #\n        #       Currently we expect the exception to be thrown when the StrawberryField\n        #       is constructed, but this only happens if we explicitly retrieve the\n        #       arguments.\n        #\n        #       If we want to change when the exception is thrown, this line can be\n        #       removed.\n        _ = resolver.arguments\n\n    @property\n    def type_params(self) -> Optional[List[Type]]:\n        if self.is_list:\n            assert self.child is not None\n            return self.child.type_params\n\n        if isinstance(self.type, StrawberryUnion):\n            types = self.type.types\n            type_vars = [t for t in types if is_type_var(t)]\n\n            if type_vars:\n                return type_vars\n\n        if is_type_var(self.type):\n            return [self.type]\n\n        if has_type_var(self.type):\n            return get_parameters(self.type)\n\n        return None\n\n    def _get_arguments(\n        self, kwargs: Dict[str, Any], source: Any, info: Any\n    ) -> Tuple[List[Any], Dict[str, Any]]:\n        assert self.base_resolver is not None\n\n        kwargs = convert_arguments(kwargs, self.arguments)\n\n        # the following code allows to omit info and root arguments\n        # by inspecting the original resolver arguments,\n        # if it asks for self, the source will be passed as first argument\n        # if it asks for root, the source it will be passed as kwarg\n        # if it asks for info, the info will be passed as kwarg\n\n        args = []\n\n        if self.base_resolver.has_self_arg:\n            args.append(source)\n\n        if self.base_resolver.has_root_arg:\n            kwargs[\"root\"] = source\n\n        if self.base_resolver.has_info_arg:\n            kwargs[\"info\"] = info\n\n        return args, kwargs\n\n    def get_result(\n        self, kwargs: Dict[str, Any], source: Any, info: Any\n    ) -> Union[Awaitable[Any], Any]:\n        \"\"\"\n        Calls the resolver defined for the StrawberryField. If the field doesn't have a\n        resolver defined we default to using getattr on `source`.\n        \"\"\"\n\n        if self.base_resolver:\n            args, kwargs = self._get_arguments(kwargs, source=source, info=info)\n\n            return self.base_resolver(*args, **kwargs)\n\n        return getattr(source, self.python_name)\n\n    def get_wrapped_resolver(self) -> Callable:\n        # TODO: This could potentially be handled by StrawberryResolver in the future\n        def _check_permissions(source, info: Info, **kwargs):\n            \"\"\"\n            Checks if the permission should be accepted and\n            raises an exception if not\n            \"\"\"\n            for permission_class in self.permission_classes:\n                permission = permission_class()\n\n                if not permission.has_permission(source, info, **kwargs):\n                    message = getattr(permission, \"message\", None)\n                    raise PermissionError(message)\n\n        def _convert_enums_to_values(field_: StrawberryField, result: Any) -> Any:\n            # graphql-core expects a resolver for an Enum type to return\n            # the enum's *value* (not its name or an instance of the enum).\n\n            # short circuit to skip checks when result is falsy\n            if not result:\n                return result\n\n            if isinstance(result, enum.Enum):\n                return result.value\n\n            if field_.is_list:\n                assert self.child is not None\n                return [_convert_enums_to_values(self.child, item) for item in result]\n\n            return result\n\n        def _strawberry_info_from_graphql(info: GraphQLResolveInfo) -> Info:\n            return Info(\n                field_name=info.field_name,\n                field_nodes=info.field_nodes,\n                context=info.context,\n                root_value=info.root_value,\n                variable_values=info.variable_values,\n                return_type=self._get_return_type(),\n                operation=info.operation,\n                path=info.path,\n            )\n\n        def _resolver(source, info: GraphQLResolveInfo, **kwargs):\n            strawberry_info = _strawberry_info_from_graphql(info)\n            _check_permissions(source, strawberry_info, **kwargs)\n\n            result = self.get_result(kwargs=kwargs, info=strawberry_info, source=source)\n\n            if iscoroutine(result):  # pragma: no cover\n\n                async def await_result(result):\n                    return _convert_enums_to_values(self, await result)\n\n                return await_result(result)\n\n            result = _convert_enums_to_values(self, result)\n            return result\n\n        _resolver._is_default = not self.base_resolver  # type: ignore\n        return _resolver\n\n    def _get_return_type(self):\n        # using type ignore to make mypy happy,\n        # this codepath will change in future anyway, so this is ok\n        if self.is_list:\n            assert self.child\n\n            type_ = List[self.child._get_return_type()]  # type: ignore\n        else:\n            type_ = self.type\n\n        if self.is_optional:\n            type_ = Optional[type_]  # type: ignore\n\n        return type_\n\n\ndef field(\n    resolver: Optional[_RESOLVER_TYPE] = None,\n    *,\n    name: Optional[str] = None,\n    is_subscription: bool = False,\n    description: Optional[str] = None,\n    permission_classes: Optional[List[Type[BasePermission]]] = None,\n    federation: Optional[FederationFieldParams] = None,\n    deprecation_reason: Optional[str] = None,\n    default: Any = UNSET,\n    default_factory: Union[Callable, object] = UNSET,\n) -> StrawberryField:\n    \"\"\"Annotates a method or property as a GraphQL field.\n\n    This is normally used inside a type declaration:\n\n    >>> @strawberry.type:\n    >>> class X:\n    >>>     field_abc: str = strawberry.field(description=\"ABC\")\n\n    >>>     @strawberry.field(description=\"ABC\")\n    >>>     def field_with_resolver(self) -> str:\n    >>>         return \"abc\"\n\n    it can be used both as decorator and as a normal function.\n    \"\"\"\n\n    field_ = StrawberryField(\n        python_name=None,\n        graphql_name=name,\n        type_=None,\n        description=description,\n        is_subscription=is_subscription,\n        permission_classes=permission_classes or [],\n        federation=federation or FederationFieldParams(),\n        deprecation_reason=deprecation_reason,\n        default_value=default,\n        default_factory=default_factory,\n    )\n\n    if resolver:\n        return field_(resolver)\n    return field_\n\n\n__all__ = [\"FederationFieldParams\", \"StrawberryField\", \"field\"]\n", "path": "strawberry/field.py"}], "after_files": [{"content": "import dataclasses\nimport enum\nimport typing\nfrom inspect import iscoroutine\nfrom typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Type, Union\n\nfrom graphql import GraphQLResolveInfo\n\nfrom strawberry.arguments import UNSET, convert_arguments\nfrom strawberry.types.info import Info\nfrom strawberry.utils.typing import get_parameters, has_type_var, is_type_var\n\nfrom .arguments import StrawberryArgument\nfrom .permission import BasePermission\nfrom .types.fields.resolver import StrawberryResolver\nfrom .types.types import FederationFieldParams\nfrom .union import StrawberryUnion\nfrom .utils.str_converters import to_camel_case\n\n\n_RESOLVER_TYPE = Union[StrawberryResolver, Callable]\n\n\nclass StrawberryField(dataclasses.Field):\n    def __init__(\n        self,\n        python_name: Optional[str],\n        graphql_name: Optional[str],\n        type_: Optional[Union[Type, StrawberryUnion]],\n        origin: Optional[Union[Type, Callable]] = None,\n        child: Optional[\"StrawberryField\"] = None,\n        is_subscription: bool = False,\n        is_optional: bool = False,\n        is_child_optional: bool = False,\n        is_list: bool = False,\n        is_union: bool = False,\n        federation: FederationFieldParams = None,\n        description: Optional[str] = None,\n        base_resolver: Optional[StrawberryResolver] = None,\n        permission_classes: List[Type[BasePermission]] = (),  # type: ignore\n        default_value: Any = UNSET,\n        default_factory: Union[Callable, object] = UNSET,\n        deprecation_reason: Optional[str] = None,\n    ):\n        federation = federation or FederationFieldParams()\n\n        # basic fields are fields with no provided resolver\n        is_basic_field = not base_resolver\n\n        super().__init__(  # type: ignore\n            default=(default_value if default_value != UNSET else dataclasses.MISSING),\n            default_factory=(\n                default_factory if default_factory != UNSET else dataclasses.MISSING\n            ),\n            init=is_basic_field,\n            repr=is_basic_field,\n            compare=is_basic_field,\n            hash=None,\n            metadata=None,\n        )\n\n        self._graphql_name = graphql_name\n        if python_name is not None:\n            self.python_name = python_name\n        if type_ is not None:\n            # TODO: Clean up the typing around StrawberryField.type\n            self.type = typing.cast(type, type_)\n\n        self.description: Optional[str] = description\n        self.origin: Optional[Union[Type, Callable]] = origin\n\n        self._base_resolver: Optional[StrawberryResolver] = None\n        if base_resolver is not None:\n            self.base_resolver = base_resolver\n\n        self.default_value = default_value\n\n        self.child = child\n        self.is_child_optional = is_child_optional\n\n        self.is_list = is_list\n        self.is_optional = is_optional\n        self.is_subscription = is_subscription\n        self.is_union = is_union\n\n        self.federation: FederationFieldParams = federation\n        self.permission_classes: List[Type[BasePermission]] = list(permission_classes)\n\n        self.deprecation_reason = deprecation_reason\n\n    def __call__(self, resolver: _RESOLVER_TYPE) -> \"StrawberryField\":\n        \"\"\"Add a resolver to the field\"\"\"\n\n        # Allow for StrawberryResolvers or bare functions to be provided\n        if not isinstance(resolver, StrawberryResolver):\n            resolver = StrawberryResolver(resolver)\n\n        self.base_resolver = resolver\n        self.type = resolver.type\n\n        return self\n\n    @property\n    def arguments(self) -> List[StrawberryArgument]:\n        if not self.base_resolver:\n            return []\n\n        return self.base_resolver.arguments\n\n    @property\n    def graphql_name(self) -> Optional[str]:\n        if self._graphql_name:\n            return self._graphql_name\n        if self.python_name:\n            return to_camel_case(self.python_name)\n        if self.base_resolver:\n            return to_camel_case(self.base_resolver.name)\n        return None\n\n    @property\n    def python_name(self) -> str:\n        return self.name\n\n    @python_name.setter\n    def python_name(self, name: str) -> None:\n        self.name = name\n\n    @property\n    def base_resolver(self) -> Optional[StrawberryResolver]:\n        return self._base_resolver\n\n    @base_resolver.setter\n    def base_resolver(self, resolver: StrawberryResolver) -> None:\n        self._base_resolver = resolver\n        self.origin = resolver.wrapped_func\n\n        # Don't add field to __init__, __repr__ and __eq__ once it has a resolver\n        self.init = False\n        self.compare = False\n        self.repr = False\n\n        # TODO: See test_resolvers.test_raises_error_when_argument_annotation_missing\n        #       (https://github.com/strawberry-graphql/strawberry/blob/8e102d3/tests/types/test_resolvers.py#L89-L98)\n        #\n        #       Currently we expect the exception to be thrown when the StrawberryField\n        #       is constructed, but this only happens if we explicitly retrieve the\n        #       arguments.\n        #\n        #       If we want to change when the exception is thrown, this line can be\n        #       removed.\n        _ = resolver.arguments\n\n    @property\n    def type_params(self) -> Optional[List[Type]]:\n        if self.is_list:\n            assert self.child is not None\n            return self.child.type_params\n\n        if isinstance(self.type, StrawberryUnion):\n            types = self.type.types\n            type_vars = [t for t in types if is_type_var(t)]\n\n            if type_vars:\n                return type_vars\n\n        if is_type_var(self.type):\n            return [self.type]\n\n        if has_type_var(self.type):\n            return get_parameters(self.type)\n\n        return None\n\n    def _get_arguments(\n        self, kwargs: Dict[str, Any], source: Any, info: Any\n    ) -> Tuple[List[Any], Dict[str, Any]]:\n        assert self.base_resolver is not None\n\n        kwargs = convert_arguments(kwargs, self.arguments)\n\n        # the following code allows to omit info and root arguments\n        # by inspecting the original resolver arguments,\n        # if it asks for self, the source will be passed as first argument\n        # if it asks for root, the source it will be passed as kwarg\n        # if it asks for info, the info will be passed as kwarg\n\n        args = []\n\n        if self.base_resolver.has_self_arg:\n            args.append(source)\n\n        if self.base_resolver.has_root_arg:\n            kwargs[\"root\"] = source\n\n        if self.base_resolver.has_info_arg:\n            kwargs[\"info\"] = info\n\n        return args, kwargs\n\n    def get_result(\n        self, kwargs: Dict[str, Any], source: Any, info: Any\n    ) -> Union[Awaitable[Any], Any]:\n        \"\"\"\n        Calls the resolver defined for the StrawberryField. If the field doesn't have a\n        resolver defined we default to using getattr on `source`.\n        \"\"\"\n\n        if self.base_resolver:\n            args, kwargs = self._get_arguments(kwargs, source=source, info=info)\n\n            return self.base_resolver(*args, **kwargs)\n\n        return getattr(source, self.python_name)\n\n    def get_wrapped_resolver(self) -> Callable:\n        # TODO: This could potentially be handled by StrawberryResolver in the future\n        def _check_permissions(source, info: Info, **kwargs):\n            \"\"\"\n            Checks if the permission should be accepted and\n            raises an exception if not\n            \"\"\"\n            for permission_class in self.permission_classes:\n                permission = permission_class()\n\n                if not permission.has_permission(source, info, **kwargs):\n                    message = getattr(permission, \"message\", None)\n                    raise PermissionError(message)\n\n        def _convert_enums_to_values(field_: StrawberryField, result: Any) -> Any:\n            # graphql-core expects a resolver for an Enum type to return\n            # the enum's *value* (not its name or an instance of the enum).\n\n            # short circuit to skip checks when result is falsy\n            if not result:\n                return result\n\n            if isinstance(result, enum.Enum):\n                return result.value\n\n            if field_.is_list:\n                assert field_.child is not None\n                return [_convert_enums_to_values(field_.child, item) for item in result]\n\n            return result\n\n        def _strawberry_info_from_graphql(info: GraphQLResolveInfo) -> Info:\n            return Info(\n                field_name=info.field_name,\n                field_nodes=info.field_nodes,\n                context=info.context,\n                root_value=info.root_value,\n                variable_values=info.variable_values,\n                return_type=self._get_return_type(),\n                operation=info.operation,\n                path=info.path,\n            )\n\n        def _resolver(source, info: GraphQLResolveInfo, **kwargs):\n            strawberry_info = _strawberry_info_from_graphql(info)\n            _check_permissions(source, strawberry_info, **kwargs)\n\n            result = self.get_result(kwargs=kwargs, info=strawberry_info, source=source)\n\n            if iscoroutine(result):  # pragma: no cover\n\n                async def await_result(result):\n                    return _convert_enums_to_values(self, await result)\n\n                return await_result(result)\n\n            result = _convert_enums_to_values(self, result)\n            return result\n\n        _resolver._is_default = not self.base_resolver  # type: ignore\n        return _resolver\n\n    def _get_return_type(self):\n        # using type ignore to make mypy happy,\n        # this codepath will change in future anyway, so this is ok\n        if self.is_list:\n            assert self.child\n\n            type_ = List[self.child._get_return_type()]  # type: ignore\n        else:\n            type_ = self.type\n\n        if self.is_optional:\n            type_ = Optional[type_]  # type: ignore\n\n        return type_\n\n\ndef field(\n    resolver: Optional[_RESOLVER_TYPE] = None,\n    *,\n    name: Optional[str] = None,\n    is_subscription: bool = False,\n    description: Optional[str] = None,\n    permission_classes: Optional[List[Type[BasePermission]]] = None,\n    federation: Optional[FederationFieldParams] = None,\n    deprecation_reason: Optional[str] = None,\n    default: Any = UNSET,\n    default_factory: Union[Callable, object] = UNSET,\n) -> StrawberryField:\n    \"\"\"Annotates a method or property as a GraphQL field.\n\n    This is normally used inside a type declaration:\n\n    >>> @strawberry.type:\n    >>> class X:\n    >>>     field_abc: str = strawberry.field(description=\"ABC\")\n\n    >>>     @strawberry.field(description=\"ABC\")\n    >>>     def field_with_resolver(self) -> str:\n    >>>         return \"abc\"\n\n    it can be used both as decorator and as a normal function.\n    \"\"\"\n\n    field_ = StrawberryField(\n        python_name=None,\n        graphql_name=name,\n        type_=None,\n        description=description,\n        is_subscription=is_subscription,\n        permission_classes=permission_classes or [],\n        federation=federation or FederationFieldParams(),\n        deprecation_reason=deprecation_reason,\n        default_value=default,\n        default_factory=default_factory,\n    )\n\n    if resolver:\n        return field_(resolver)\n    return field_\n\n\n__all__ = [\"FederationFieldParams\", \"StrawberryField\", \"field\"]\n", "path": "strawberry/field.py"}]}