Giter VIP home page Giter VIP logo

Comments (3)

Speedy1991 avatar Speedy1991 commented on June 13, 2024 1

I guess the problem is in this line

The outer Type (which implements the interface) is checked but not the nested values in items

image

But the outer loop here is still on the inner type

from strawberry.

patrick91 avatar patrick91 commented on June 13, 2024 1

I've done some digging in this, and we have the same issue with unions:

def test_using_generics_with_union():
    @strawberry.type
    class JsonBlock:
        data: JSON

    @strawberry.type
    class BlockRowType(Generic[GenericType]):
        total: int
        items: List[GenericType]

    @strawberry.type
    class Query:
        @strawberry.field
        def blocks(
            self,
        ) -> List[Union[BlockRowType[int], BlockRowType[str], JsonBlock]]:
            return [
                BlockRowType(total=3, items=["a", "b", "c"]),
                BlockRowType(total=1, items=[1, 2, 3, 4]),
                JsonBlock(data=JSON({"a": 1})),
            ]

    schema = strawberry.Schema(query=Query)

    result = schema.execute_sync("""query {
        blocks {
            __typename
            ... on IntBlockRowType {
                a: items
            }
            ... on StrBlockRowType {
                b: items
            }
            ... on JsonBlock {
                data
            }
        }
    }""")

    assert not result.errors

    assert result.data == {
        "blocks": [
            {"id": "3", "__typename": "StrBlockRowType", "items": ["a", "b", "c"]},
            {"id": "1", "__typename": "IntBlockRowType", "items": [1, 2, 3, 4]},
            {"id": "2", "__typename": "JsonBlock", "data": {"a": 1}},
        ]
    }

fix this in unions, means touching this codebase:

def get_type_resolver(self, type_map: TypeMap) -> GraphQLTypeResolver:
def _resolve_union_type(
root: Any, info: GraphQLResolveInfo, type_: GraphQLAbstractType
) -> str:
assert isinstance(type_, GraphQLUnionType)
from strawberry.types.types import StrawberryObjectDefinition
# If the type given is not an Object type, try resolving using `is_type_of`
# defined on the union's inner types
if not has_object_definition(root):
for inner_type in type_.types:
if inner_type.is_type_of is not None and inner_type.is_type_of(
root, info
):
return inner_type.name
# Couldn't resolve using `is_type_of`
raise WrongReturnTypeForUnion(info.field_name, str(type(root)))
return_type: Optional[GraphQLType]
# Iterate over all of our known types and find the first concrete
# type that implements the type. We prioritise checking types named in the
# Union in case a nested generic object matches against more than one type.
concrete_types_for_union = (type_map[x.name] for x in type_.types)
# TODO: do we still need to iterate over all types in `type_map`?
for possible_concrete_type in chain(
concrete_types_for_union, type_map.values()
):
possible_type = possible_concrete_type.definition
if not isinstance(possible_type, StrawberryObjectDefinition):
continue
if possible_type.is_implemented_by(root):
return_type = possible_concrete_type.implementation
break
else:
return_type = None
# Make sure the found type is expected by the Union
if return_type is None or return_type not in type_.types:
raise UnallowedReturnTypeForUnion(
info.field_name, str(type(root)), set(type_.types)
)
# Return the name of the type. Returning the actual type is now deprecated
if isinstance(return_type, GraphQLNamedType):
# TODO: Can return_type ever _not_ be a GraphQLNamedType?
return return_type.name
else:
# TODO: check if this is correct
return return_type.__name__ # type: ignore
return _resolve_union_type

which is separated from the interface part, so I need to think how we could combine both

from strawberry.

Speedy1991 avatar Speedy1991 commented on June 13, 2024

Could I assist in making progress on this issue? :)

from strawberry.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.