We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Generic input type broken from 0.69.0 onward
Generic input types were working correctly until version `0.68.4` but after `0.69.0` it's throwing a type error.
here's a test for it
```python
def test_generic_input():
    E = TypeVar('E')

    @strawberry.input
    class EnumInput(Generic[E]):
        value: E

    @strawberry.enum
    class Make(Enum):
        FORD = 'ford'
        TOYOTA = 'toyota'
        HONDA = 'honda'

    @strawberry.type
    class Car:
        make: Make

    @strawberry.type
    class Query:
        @strawberry.field
        def cars(self, make: Optional[EnumInput[Make]] = None) -> List[Car]:
            return []

    schema = strawberry.Schema(query=Query)
    query = '''
        query CarsList {
            cars(make: {value: FORD}) {
                __typename
            }
        }
        '''
    result = schema.execute_sync(query)
    assert result.errors is None
```
output error
```
self = <GraphQLObjectType 'Query'>

    @cached_property
    def fields(self) -> GraphQLFieldMap:
        """Get provided fields, wrapping them as GraphQLFields if needed."""
        try:
            fields = resolve_thunk(self._fields)
        except Exception as error:
>           raise TypeError(f"{self.name} fields cannot be resolved. {error}")
E           TypeError: Query fields cannot be resolved. 'EnumDefinition' object has no attribute '__name__'

.venv/lib/python3.9/site-packages/graphql/type/definition.py:769: TypeError
```

Generic input type broken from 0.69.0 onward
Generic input types were working correctly until version `0.68.4` but after `0.69.0` it's throwing a type error.
here's a test for it
```python
def test_generic_input():
    E = TypeVar('E')

    @strawberry.input
    class EnumInput(Generic[E]):
        value: E

    @strawberry.enum
    class Make(Enum):
        FORD = 'ford'
        TOYOTA = 'toyota'
        HONDA = 'honda'

    @strawberry.type
    class Car:
        make: Make

    @strawberry.type
    class Query:
        @strawberry.field
        def cars(self, make: Optional[EnumInput[Make]] = None) -> List[Car]:
            return []

    schema = strawberry.Schema(query=Query)
    query = '''
        query CarsList {
            cars(make: {value: FORD}) {
                __typename
            }
        }
        '''
    result = schema.execute_sync(query)
    assert result.errors is None
```
output error
```
self = <GraphQLObjectType 'Query'>

    @cached_property
    def fields(self) -> GraphQLFieldMap:
        """Get provided fields, wrapping them as GraphQLFields if needed."""
        try:
            fields = resolve_thunk(self._fields)
        except Exception as error:
>           raise TypeError(f"{self.name} fields cannot be resolved. {error}")
E           TypeError: Query fields cannot be resolved. 'EnumDefinition' object has no attribute '__name__'

.venv/lib/python3.9/site-packages/graphql/type/definition.py:769: TypeError
```


--- 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/types/types.py`
Content:
```
1 from __future__ import annotations
2 
3 import dataclasses
4 from typing import (
5     TYPE_CHECKING,
6     Iterable,
7     List,
8     Mapping,
9     Optional,
10     Type,
11     TypeVar,
12     Union,
13 )
14 
15 from strawberry.type import StrawberryType, StrawberryTypeVar
16 from strawberry.utils.str_converters import capitalize_first
17 from strawberry.utils.typing import is_generic as is_type_generic
18 
19 
20 if TYPE_CHECKING:
21     from strawberry.field import StrawberryField
22 
23 
24 @dataclasses.dataclass
25 class FederationTypeParams:
26     keys: List[str] = dataclasses.field(default_factory=list)
27     extend: bool = False
28 
29 
30 @dataclasses.dataclass(eq=False)
31 class TypeDefinition(StrawberryType):
32     name: str
33     is_input: bool
34     is_interface: bool
35     origin: Type
36     description: Optional[str]
37     federation: FederationTypeParams
38     interfaces: List["TypeDefinition"]
39 
40     _fields: List["StrawberryField"]
41 
42     concrete_of: Optional["TypeDefinition"] = None
43     """Concrete implementations of Generic TypeDefinitions fill this in"""
44     type_var_map: Mapping[TypeVar, Union[StrawberryType, type]] = dataclasses.field(
45         default_factory=dict
46     )
47 
48     # TODO: remove wrapped cls when we "merge" this with `StrawberryObject`
49     def resolve_generic(self, wrapped_cls: type) -> type:
50         from strawberry.annotation import StrawberryAnnotation
51 
52         passed_types = wrapped_cls.__args__  # type: ignore
53         params = wrapped_cls.__origin__.__parameters__  # type: ignore
54 
55         # Make sure all passed_types are turned into StrawberryTypes
56         resolved_types = []
57         for passed_type in passed_types:
58             resolved_type = StrawberryAnnotation(passed_type).resolve()
59             resolved_types.append(resolved_type)
60 
61         type_var_map = dict(zip(params, resolved_types))
62 
63         return self.copy_with(type_var_map)
64 
65     # TODO: Return a StrawberryObject
66     def copy_with(
67         self, type_var_map: Mapping[TypeVar, Union[StrawberryType, type]]
68     ) -> type:
69         name = self.get_name_from_types(type_var_map.values())
70 
71         fields = []
72         for field in self.fields:
73             # TODO: Logic unnecessary with StrawberryObject
74             field_type = field.type
75             if hasattr(field_type, "_type_definition"):
76                 field_type = field_type._type_definition  # type: ignore
77 
78             # TODO: All types should end up being StrawberryTypes
79             #       The first check is here as a symptom of strawberry.ID being a
80             #       Scalar, but not a StrawberryType
81             if isinstance(field_type, StrawberryType) and field_type.is_generic:
82                 field = field.copy_with(type_var_map)
83 
84             fields.append(field)
85 
86         new_type_definition = TypeDefinition(
87             name=name,
88             is_input=self.is_input,
89             origin=self.origin,
90             is_interface=self.is_interface,
91             federation=self.federation,
92             interfaces=self.interfaces,
93             description=self.description,
94             _fields=fields,
95             concrete_of=self,
96             type_var_map=type_var_map,
97         )
98 
99         new_type = type(
100             new_type_definition.name,
101             (self.origin,),
102             {"_type_definition": new_type_definition},
103         )
104 
105         new_type_definition.origin = new_type
106 
107         return new_type
108 
109     def get_field(self, python_name: str) -> Optional["StrawberryField"]:
110         return next(
111             (field for field in self.fields if field.python_name == python_name), None
112         )
113 
114     def get_name_from_types(self, types: Iterable[Union[StrawberryType, type]]) -> str:
115         from strawberry.union import StrawberryUnion
116 
117         names: List[str] = []
118 
119         for type_ in types:
120             if isinstance(type_, StrawberryUnion):
121                 name = type_.name
122             elif hasattr(type_, "_type_definition"):
123                 field_type = type_._type_definition  # type: ignore
124 
125                 name = capitalize_first(field_type.name)
126             else:
127                 name = capitalize_first(type_.__name__)  # type: ignore
128 
129             names.append(name)
130 
131         return "".join(names) + self.name
132 
133     @property
134     def fields(self) -> List["StrawberryField"]:
135         # TODO: rename _fields to fields and remove this property
136         return self._fields
137 
138     @property
139     def is_generic(self) -> bool:
140         return is_type_generic(self.origin)
141 
142     @property
143     def type_params(self) -> List[TypeVar]:
144         type_params: List[TypeVar] = []
145         for field in self.fields:
146             type_params.extend(field.type_params)
147 
148         return type_params
149 
150     def is_implemented_by(self, root: Union[type, dict]) -> bool:
151         # TODO: Accept StrawberryObject instead
152         # TODO: Support dicts
153         if isinstance(root, dict):
154             raise NotImplementedError()
155 
156         type_definition = root._type_definition  # type: ignore
157 
158         if type_definition is self:
159             # No generics involved. Exact type match
160             return True
161 
162         if type_definition is not self.concrete_of:
163             # Either completely different type, or concrete type of a different generic
164             return False
165 
166         # Check the mapping of all fields' TypeVars
167         for generic_field in type_definition.fields:
168             generic_field_type = generic_field.type
169             if not isinstance(generic_field_type, StrawberryTypeVar):
170                 continue
171 
172             # For each TypeVar found, get the expected type from the copy's type map
173             expected_concrete_type = self.type_var_map.get(generic_field_type.type_var)
174             if expected_concrete_type is None:
175                 # TODO: Should this return False?
176                 continue
177 
178             # Check if the expected type matches the type found on the type_map
179             real_concrete_type = type(getattr(root, generic_field.name))
180             if real_concrete_type is not expected_concrete_type:
181                 return False
182 
183         # All field mappings succeeded. This is a match
184         return True
185 
186 
187 @dataclasses.dataclass
188 class FederationFieldParams:
189     provides: List[str] = dataclasses.field(default_factory=list)
190     requires: List[str] = dataclasses.field(default_factory=list)
191     external: bool = False
192
```
--- 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/types/types.py b/strawberry/types/types.py
--- a/strawberry/types/types.py
+++ b/strawberry/types/types.py
@@ -12,6 +12,8 @@
     Union,
 )
 
+from strawberry.enum import EnumDefinition
+from strawberry.lazy_type import LazyType
 from strawberry.type import StrawberryType, StrawberryTypeVar
 from strawberry.utils.str_converters import capitalize_first
 from strawberry.utils.typing import is_generic as is_type_generic
@@ -117,7 +119,11 @@
         names: List[str] = []
 
         for type_ in types:
-            if isinstance(type_, StrawberryUnion):
+            if isinstance(type_, LazyType):
+                name = type_.type_name
+            elif isinstance(type_, EnumDefinition):
+                name = type_.name
+            elif isinstance(type_, StrawberryUnion):
                 name = type_.name
             elif hasattr(type_, "_type_definition"):
                 field_type = type_._type_definition  # type: ignore

{"golden_diff": "diff --git a/strawberry/types/types.py b/strawberry/types/types.py\n--- a/strawberry/types/types.py\n+++ b/strawberry/types/types.py\n@@ -12,6 +12,8 @@\n     Union,\n )\n \n+from strawberry.enum import EnumDefinition\n+from strawberry.lazy_type import LazyType\n from strawberry.type import StrawberryType, StrawberryTypeVar\n from strawberry.utils.str_converters import capitalize_first\n from strawberry.utils.typing import is_generic as is_type_generic\n@@ -117,7 +119,11 @@\n         names: List[str] = []\n \n         for type_ in types:\n-            if isinstance(type_, StrawberryUnion):\n+            if isinstance(type_, LazyType):\n+                name = type_.type_name\n+            elif isinstance(type_, EnumDefinition):\n+                name = type_.name\n+            elif isinstance(type_, StrawberryUnion):\n                 name = type_.name\n             elif hasattr(type_, \"_type_definition\"):\n                 field_type = type_._type_definition  # type: ignore\n", "issue": "Generic input type broken from 0.69.0 onward\nGeneric input types were working correctly until version `0.68.4` but after `0.69.0` it's throwing a type error.\r\nhere's a test for it\r\n```python\r\ndef test_generic_input():\r\n    E = TypeVar('E')\r\n\r\n    @strawberry.input\r\n    class EnumInput(Generic[E]):\r\n        value: E\r\n\r\n    @strawberry.enum\r\n    class Make(Enum):\r\n        FORD = 'ford'\r\n        TOYOTA = 'toyota'\r\n        HONDA = 'honda'\r\n\r\n    @strawberry.type\r\n    class Car:\r\n        make: Make\r\n\r\n    @strawberry.type\r\n    class Query:\r\n        @strawberry.field\r\n        def cars(self, make: Optional[EnumInput[Make]] = None) -> List[Car]:\r\n            return []\r\n\r\n    schema = strawberry.Schema(query=Query)\r\n    query = '''\r\n        query CarsList {\r\n            cars(make: {value: FORD}) {\r\n                __typename\r\n            }\r\n        }\r\n        '''\r\n    result = schema.execute_sync(query)\r\n    assert result.errors is None\r\n```\r\noutput error\r\n```\r\nself = <GraphQLObjectType 'Query'>\r\n\r\n    @cached_property\r\n    def fields(self) -> GraphQLFieldMap:\r\n        \"\"\"Get provided fields, wrapping them as GraphQLFields if needed.\"\"\"\r\n        try:\r\n            fields = resolve_thunk(self._fields)\r\n        except Exception as error:\r\n>           raise TypeError(f\"{self.name} fields cannot be resolved. {error}\")\r\nE           TypeError: Query fields cannot be resolved. 'EnumDefinition' object has no attribute '__name__'\r\n\r\n.venv/lib/python3.9/site-packages/graphql/type/definition.py:769: TypeError\r\n```\r\n\nGeneric input type broken from 0.69.0 onward\nGeneric input types were working correctly until version `0.68.4` but after `0.69.0` it's throwing a type error.\r\nhere's a test for it\r\n```python\r\ndef test_generic_input():\r\n    E = TypeVar('E')\r\n\r\n    @strawberry.input\r\n    class EnumInput(Generic[E]):\r\n        value: E\r\n\r\n    @strawberry.enum\r\n    class Make(Enum):\r\n        FORD = 'ford'\r\n        TOYOTA = 'toyota'\r\n        HONDA = 'honda'\r\n\r\n    @strawberry.type\r\n    class Car:\r\n        make: Make\r\n\r\n    @strawberry.type\r\n    class Query:\r\n        @strawberry.field\r\n        def cars(self, make: Optional[EnumInput[Make]] = None) -> List[Car]:\r\n            return []\r\n\r\n    schema = strawberry.Schema(query=Query)\r\n    query = '''\r\n        query CarsList {\r\n            cars(make: {value: FORD}) {\r\n                __typename\r\n            }\r\n        }\r\n        '''\r\n    result = schema.execute_sync(query)\r\n    assert result.errors is None\r\n```\r\noutput error\r\n```\r\nself = <GraphQLObjectType 'Query'>\r\n\r\n    @cached_property\r\n    def fields(self) -> GraphQLFieldMap:\r\n        \"\"\"Get provided fields, wrapping them as GraphQLFields if needed.\"\"\"\r\n        try:\r\n            fields = resolve_thunk(self._fields)\r\n        except Exception as error:\r\n>           raise TypeError(f\"{self.name} fields cannot be resolved. {error}\")\r\nE           TypeError: Query fields cannot be resolved. 'EnumDefinition' object has no attribute '__name__'\r\n\r\n.venv/lib/python3.9/site-packages/graphql/type/definition.py:769: TypeError\r\n```\r\n\n", "before_files": [{"content": "from __future__ import annotations\n\nimport dataclasses\nfrom typing import (\n    TYPE_CHECKING,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Type,\n    TypeVar,\n    Union,\n)\n\nfrom strawberry.type import StrawberryType, StrawberryTypeVar\nfrom strawberry.utils.str_converters import capitalize_first\nfrom strawberry.utils.typing import is_generic as is_type_generic\n\n\nif TYPE_CHECKING:\n    from strawberry.field import StrawberryField\n\n\n@dataclasses.dataclass\nclass FederationTypeParams:\n    keys: List[str] = dataclasses.field(default_factory=list)\n    extend: bool = False\n\n\n@dataclasses.dataclass(eq=False)\nclass TypeDefinition(StrawberryType):\n    name: str\n    is_input: bool\n    is_interface: bool\n    origin: Type\n    description: Optional[str]\n    federation: FederationTypeParams\n    interfaces: List[\"TypeDefinition\"]\n\n    _fields: List[\"StrawberryField\"]\n\n    concrete_of: Optional[\"TypeDefinition\"] = None\n    \"\"\"Concrete implementations of Generic TypeDefinitions fill this in\"\"\"\n    type_var_map: Mapping[TypeVar, Union[StrawberryType, type]] = dataclasses.field(\n        default_factory=dict\n    )\n\n    # TODO: remove wrapped cls when we \"merge\" this with `StrawberryObject`\n    def resolve_generic(self, wrapped_cls: type) -> type:\n        from strawberry.annotation import StrawberryAnnotation\n\n        passed_types = wrapped_cls.__args__  # type: ignore\n        params = wrapped_cls.__origin__.__parameters__  # type: ignore\n\n        # Make sure all passed_types are turned into StrawberryTypes\n        resolved_types = []\n        for passed_type in passed_types:\n            resolved_type = StrawberryAnnotation(passed_type).resolve()\n            resolved_types.append(resolved_type)\n\n        type_var_map = dict(zip(params, resolved_types))\n\n        return self.copy_with(type_var_map)\n\n    # TODO: Return a StrawberryObject\n    def copy_with(\n        self, type_var_map: Mapping[TypeVar, Union[StrawberryType, type]]\n    ) -> type:\n        name = self.get_name_from_types(type_var_map.values())\n\n        fields = []\n        for field in self.fields:\n            # TODO: Logic unnecessary with StrawberryObject\n            field_type = field.type\n            if hasattr(field_type, \"_type_definition\"):\n                field_type = field_type._type_definition  # type: ignore\n\n            # TODO: All types should end up being StrawberryTypes\n            #       The first check is here as a symptom of strawberry.ID being a\n            #       Scalar, but not a StrawberryType\n            if isinstance(field_type, StrawberryType) and field_type.is_generic:\n                field = field.copy_with(type_var_map)\n\n            fields.append(field)\n\n        new_type_definition = TypeDefinition(\n            name=name,\n            is_input=self.is_input,\n            origin=self.origin,\n            is_interface=self.is_interface,\n            federation=self.federation,\n            interfaces=self.interfaces,\n            description=self.description,\n            _fields=fields,\n            concrete_of=self,\n            type_var_map=type_var_map,\n        )\n\n        new_type = type(\n            new_type_definition.name,\n            (self.origin,),\n            {\"_type_definition\": new_type_definition},\n        )\n\n        new_type_definition.origin = new_type\n\n        return new_type\n\n    def get_field(self, python_name: str) -> Optional[\"StrawberryField\"]:\n        return next(\n            (field for field in self.fields if field.python_name == python_name), None\n        )\n\n    def get_name_from_types(self, types: Iterable[Union[StrawberryType, type]]) -> str:\n        from strawberry.union import StrawberryUnion\n\n        names: List[str] = []\n\n        for type_ in types:\n            if isinstance(type_, StrawberryUnion):\n                name = type_.name\n            elif hasattr(type_, \"_type_definition\"):\n                field_type = type_._type_definition  # type: ignore\n\n                name = capitalize_first(field_type.name)\n            else:\n                name = capitalize_first(type_.__name__)  # type: ignore\n\n            names.append(name)\n\n        return \"\".join(names) + self.name\n\n    @property\n    def fields(self) -> List[\"StrawberryField\"]:\n        # TODO: rename _fields to fields and remove this property\n        return self._fields\n\n    @property\n    def is_generic(self) -> bool:\n        return is_type_generic(self.origin)\n\n    @property\n    def type_params(self) -> List[TypeVar]:\n        type_params: List[TypeVar] = []\n        for field in self.fields:\n            type_params.extend(field.type_params)\n\n        return type_params\n\n    def is_implemented_by(self, root: Union[type, dict]) -> bool:\n        # TODO: Accept StrawberryObject instead\n        # TODO: Support dicts\n        if isinstance(root, dict):\n            raise NotImplementedError()\n\n        type_definition = root._type_definition  # type: ignore\n\n        if type_definition is self:\n            # No generics involved. Exact type match\n            return True\n\n        if type_definition is not self.concrete_of:\n            # Either completely different type, or concrete type of a different generic\n            return False\n\n        # Check the mapping of all fields' TypeVars\n        for generic_field in type_definition.fields:\n            generic_field_type = generic_field.type\n            if not isinstance(generic_field_type, StrawberryTypeVar):\n                continue\n\n            # For each TypeVar found, get the expected type from the copy's type map\n            expected_concrete_type = self.type_var_map.get(generic_field_type.type_var)\n            if expected_concrete_type is None:\n                # TODO: Should this return False?\n                continue\n\n            # Check if the expected type matches the type found on the type_map\n            real_concrete_type = type(getattr(root, generic_field.name))\n            if real_concrete_type is not expected_concrete_type:\n                return False\n\n        # All field mappings succeeded. This is a match\n        return True\n\n\n@dataclasses.dataclass\nclass FederationFieldParams:\n    provides: List[str] = dataclasses.field(default_factory=list)\n    requires: List[str] = dataclasses.field(default_factory=list)\n    external: bool = False\n", "path": "strawberry/types/types.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport dataclasses\nfrom typing import (\n    TYPE_CHECKING,\n    Iterable,\n    List,\n    Mapping,\n    Optional,\n    Type,\n    TypeVar,\n    Union,\n)\n\nfrom strawberry.enum import EnumDefinition\nfrom strawberry.lazy_type import LazyType\nfrom strawberry.type import StrawberryType, StrawberryTypeVar\nfrom strawberry.utils.str_converters import capitalize_first\nfrom strawberry.utils.typing import is_generic as is_type_generic\n\n\nif TYPE_CHECKING:\n    from strawberry.field import StrawberryField\n\n\n@dataclasses.dataclass\nclass FederationTypeParams:\n    keys: List[str] = dataclasses.field(default_factory=list)\n    extend: bool = False\n\n\n@dataclasses.dataclass(eq=False)\nclass TypeDefinition(StrawberryType):\n    name: str\n    is_input: bool\n    is_interface: bool\n    origin: Type\n    description: Optional[str]\n    federation: FederationTypeParams\n    interfaces: List[\"TypeDefinition\"]\n\n    _fields: List[\"StrawberryField\"]\n\n    concrete_of: Optional[\"TypeDefinition\"] = None\n    \"\"\"Concrete implementations of Generic TypeDefinitions fill this in\"\"\"\n    type_var_map: Mapping[TypeVar, Union[StrawberryType, type]] = dataclasses.field(\n        default_factory=dict\n    )\n\n    # TODO: remove wrapped cls when we \"merge\" this with `StrawberryObject`\n    def resolve_generic(self, wrapped_cls: type) -> type:\n        from strawberry.annotation import StrawberryAnnotation\n\n        passed_types = wrapped_cls.__args__  # type: ignore\n        params = wrapped_cls.__origin__.__parameters__  # type: ignore\n\n        # Make sure all passed_types are turned into StrawberryTypes\n        resolved_types = []\n        for passed_type in passed_types:\n            resolved_type = StrawberryAnnotation(passed_type).resolve()\n            resolved_types.append(resolved_type)\n\n        type_var_map = dict(zip(params, resolved_types))\n\n        return self.copy_with(type_var_map)\n\n    # TODO: Return a StrawberryObject\n    def copy_with(\n        self, type_var_map: Mapping[TypeVar, Union[StrawberryType, type]]\n    ) -> type:\n        name = self.get_name_from_types(type_var_map.values())\n\n        fields = []\n        for field in self.fields:\n            # TODO: Logic unnecessary with StrawberryObject\n            field_type = field.type\n            if hasattr(field_type, \"_type_definition\"):\n                field_type = field_type._type_definition  # type: ignore\n\n            # TODO: All types should end up being StrawberryTypes\n            #       The first check is here as a symptom of strawberry.ID being a\n            #       Scalar, but not a StrawberryType\n            if isinstance(field_type, StrawberryType) and field_type.is_generic:\n                field = field.copy_with(type_var_map)\n\n            fields.append(field)\n\n        new_type_definition = TypeDefinition(\n            name=name,\n            is_input=self.is_input,\n            origin=self.origin,\n            is_interface=self.is_interface,\n            federation=self.federation,\n            interfaces=self.interfaces,\n            description=self.description,\n            _fields=fields,\n            concrete_of=self,\n            type_var_map=type_var_map,\n        )\n\n        new_type = type(\n            new_type_definition.name,\n            (self.origin,),\n            {\"_type_definition\": new_type_definition},\n        )\n\n        new_type_definition.origin = new_type\n\n        return new_type\n\n    def get_field(self, python_name: str) -> Optional[\"StrawberryField\"]:\n        return next(\n            (field for field in self.fields if field.python_name == python_name), None\n        )\n\n    def get_name_from_types(self, types: Iterable[Union[StrawberryType, type]]) -> str:\n        from strawberry.union import StrawberryUnion\n\n        names: List[str] = []\n\n        for type_ in types:\n            if isinstance(type_, LazyType):\n                name = type_.type_name\n            elif isinstance(type_, EnumDefinition):\n                name = type_.name\n            elif isinstance(type_, StrawberryUnion):\n                name = type_.name\n            elif hasattr(type_, \"_type_definition\"):\n                field_type = type_._type_definition  # type: ignore\n\n                name = capitalize_first(field_type.name)\n            else:\n                name = capitalize_first(type_.__name__)  # type: ignore\n\n            names.append(name)\n\n        return \"\".join(names) + self.name\n\n    @property\n    def fields(self) -> List[\"StrawberryField\"]:\n        # TODO: rename _fields to fields and remove this property\n        return self._fields\n\n    @property\n    def is_generic(self) -> bool:\n        return is_type_generic(self.origin)\n\n    @property\n    def type_params(self) -> List[TypeVar]:\n        type_params: List[TypeVar] = []\n        for field in self.fields:\n            type_params.extend(field.type_params)\n\n        return type_params\n\n    def is_implemented_by(self, root: Union[type, dict]) -> bool:\n        # TODO: Accept StrawberryObject instead\n        # TODO: Support dicts\n        if isinstance(root, dict):\n            raise NotImplementedError()\n\n        type_definition = root._type_definition  # type: ignore\n\n        if type_definition is self:\n            # No generics involved. Exact type match\n            return True\n\n        if type_definition is not self.concrete_of:\n            # Either completely different type, or concrete type of a different generic\n            return False\n\n        # Check the mapping of all fields' TypeVars\n        for generic_field in type_definition.fields:\n            generic_field_type = generic_field.type\n            if not isinstance(generic_field_type, StrawberryTypeVar):\n                continue\n\n            # For each TypeVar found, get the expected type from the copy's type map\n            expected_concrete_type = self.type_var_map.get(generic_field_type.type_var)\n            if expected_concrete_type is None:\n                # TODO: Should this return False?\n                continue\n\n            # Check if the expected type matches the type found on the type_map\n            real_concrete_type = type(getattr(root, generic_field.name))\n            if real_concrete_type is not expected_concrete_type:\n                return False\n\n        # All field mappings succeeded. This is a match\n        return True\n\n\n@dataclasses.dataclass\nclass FederationFieldParams:\n    provides: List[str] = dataclasses.field(default_factory=list)\n    requires: List[str] = dataclasses.field(default_factory=list)\n    external: bool = False\n", "path": "strawberry/types/types.py"}]}