strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
3.94k stars 520 forks source link

Can not use Union with custom Strawberry types inside a generic type. #2959

Open anwitars opened 1 year ago

anwitars commented 1 year ago

When trying to return union type of custom types, the schema generator fails.

Describe the Bug

Two custom types declared, and one that contains the union of them.

T = TypeVar("T")

@strawberry.type
class MySubType:
    data: str

@strawberry.type
class MySubType2:
    data: int

@strawberry.type
class MyType(Generic[T]):
    data: T

@strawberry.type
class Mutation:

    @strawberry.field
    async def test_mutation(self) -> MyType[Union[MySubType, MySubType2]]:
        return MyType(data=MySubType(data="test"))

The startup fails, with the following traceback: Traceback (most recent call last): File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/graphql/type/definition.py", line 808, in fields fields = resolve_thunk(self._fields) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/graphql/type/definition.py", line 300, in resolve_thunk return thunk() if callable(thunk) else thunk File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 509, in fields=lambda: self.get_graphql_fields(object_type), File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 373, in get_graphql_fields return _get_thunk_mapping( File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 133, in _get_thunk_mapping thunk_mapping[name_converter(field)] = field_converter( File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 314, in from_field self.from_maybe_optional( File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 762, in from_maybe_optional return GraphQLNonNull(self.fromtype(type)) File "/home/dewitars/programming/dvrt-graphene-tools/dvrt_graphene_tools/schema.py", line 61, in from_type return super().fromtype(type) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 780, in from_type return self.fromobject(type.__strawberry_definition__) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/schema_converter.py", line 476, in from_object object_type_name = self.config.name_converter.from_type(object_type) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/name_converter.py", line 55, in from_type return self.fromobject(type) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/name_converter.py", line 70, in from_object return self.from_generic( File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/name_converter.py", line 136, in from_generic name = self.get_fromtype(type) File "/home/dewitars/.pyenv/versions/3.10.5/envs/fax-api/lib/python3.10/site-packages/strawberry/schema/name_converter.py", line 150, in get_fromtype assert type.graphql_name AssertionError

But if we are specific, and put the Union in 'MyType', it works just fine:

T = TypeVar("T")

@strawberry.type
class MySubType:
    data: str

@strawberry.type
class MySubType2:
    data: int

@strawberry.type
class MyType:
    data: Union[MySubType, MySubType2]

@strawberry.type
class Mutation:

    @strawberry.field
    async def test_mutation(self) -> MyType:
        return MyType(data=MySubType(data="test"))

System Information

Additional Context

I can not provide the lines that are related to dvrt-graphene-tools (proprietary), but I can ensure that it just calls the strawberry.schema.schema_converter.GraphQLCoreConverter.from_type function with the provided type.

Upvote & Fund

Fund with Polar

Yukirin5b25 commented 1 year ago
@strawberry.field
async def test_mutation(self) -> Union[MyType[MySubType], MyType[MySubType2]]:
        return MyType(data=MySubType(data="test"))

This annotation works with a similar case of mine.