strawberry icon indicating copy to clipboard operation
strawberry copied to clipboard

DuplicatedTypeName exception raised for nested generics

Open bikeshedder opened this issue 2 years ago • 5 comments
trafficstars

Using nested generics causes an invalid DuplicatedTypeName exception to be raised when using the same type twice.

Minimal reproducible example

from typing import Generic, TypeVar

import strawberry

T = TypeVar("T")

@strawberry.type
class Wrapper(Generic[T]):
    value: T

@strawberry.type
class Query:
    a: Wrapper[Wrapper[int]]
    b: Wrapper[Wrapper[int]]

schema = strawberry.Schema(query=Query)

Exception

strawberry.exceptions.duplicated_type_name.DuplicatedTypeName:
Type IntWrapperWrapper is defined multiple times in the schema

System Information

  • Operating system: Ubuntu 22.04.1 LTS
  • Strawberry version: The check was first introduced in 0.144 and up until 0.159 it fails.

bikeshedder avatar Mar 01 '23 17:03 bikeshedder

Any updates on this?

yallxe avatar May 30 '23 07:05 yallxe

I'm also encountering this, is there any known workaround?

Skeen avatar Aug 17 '23 17:08 Skeen

Any update on this?

alidin000 avatar Jan 16 '25 13:01 alidin000

For that example, do specializing the wrapper works? e.g.

from typing import Generic, TypeVar

import strawberry

T = TypeVar("T")

@strawberry.type
class Wrapper(Generic[T]):
    value: T

@strawberry.type
class IntWrapper(Wrapper[int]):
    ...

@strawberry.type
class Query:
    a: Wrapper[IntWrapper]
    b: Wrapper[IntWrapper]

schema = strawberry.Schema(query=Query)

This still a bug, but maybe that's a possible workaround for now?

bellini666 avatar Jan 16 '25 18:01 bellini666

I am encountering this issue as well. This issue occurs only if more than one attribute has same specific type. Here coordinates attribute in both Location and DataClassification has a specific type ListFilter[float, RelationalOpNumeric[float]], so getting an error strawberry.exceptions.duplicated_type_name.DuplicatedTypeName: Type FloatFloatRelationalOpNumericListFilter is defined multiple times in the schema

@strawberry.input
class ListFilter(Generic[T, O]):
    list_op: ListOp
    filter: list[O] = strawberry.field(default_factory=list)
    negate: bool = False
    op: LogicalOperator = LogicalOperator.AND

    def _build_quantified_filter(self, attr: T) -> Any:
        ...

@strawberry.input
class RelationalOpNumeric(Generic[N], BaseOp[N]):
    equals: Optional[N] = None
    greater_than: Optional[N] = None
    greater_than_equals: Optional[N] = None
    is_empty: Optional[bool] = None
    less_than: Optional[N] = None
    less_than_equals: Optional[N] = None
    not_equals: Optional[N] = None

@strawberry.input
class LocationInput(BaseInput):
    coordinates: Optional[ListFilter[float, RelationalOpNumeric[float]]] = None

@strawberry.input
class DataClassificationInput(BaseInput):
    coordinates: Optional[ListFilter[float, RelationalOpNumeric[float]]] = None

srotsinha avatar Mar 24 '25 15:03 srotsinha