11from __future__ import annotations
22
3- from graphql .execution import execute_sync
3+ import pytest
4+
5+ from graphql .execution import ExecutionResult , execute , execute_sync
46from graphql .language import parse
57from graphql .type import (
68 GraphQLBoolean ,
1315 GraphQLUnionType ,
1416)
1517
18+ pytestmark = pytest .mark .anyio
19+
1620
1721class Dog :
1822 name : str
@@ -44,20 +48,30 @@ def __init__(self, name: str, meows: bool):
4448 self .progeny = []
4549
4650
51+ class Plant :
52+ name : str
53+
54+ def __init__ (self , name : str ):
55+ self .name = name
56+
57+
4758class Person :
4859 name : str
4960 pets : list [Dog | Cat ] | None
5061 friends : list [Dog | Cat | Person ] | None
62+ responsibilities : list [Dog | Cat | Plant ] | None
5163
5264 def __init__ (
5365 self ,
5466 name : str ,
5567 pets : list [Dog | Cat ] | None = None ,
5668 friends : list [Dog | Cat | Person ] | None = None ,
69+ responsibilities : list [Dog | Cat | Plant ] | None = None ,
5770 ):
5871 self .name = name
5972 self .pets = pets
6073 self .friends = friends
74+ self .responsibilities = responsibilities
6175
6276
6377NamedType = GraphQLInterfaceType ("Named" , {"name" : GraphQLField (GraphQLString )})
@@ -104,24 +118,39 @@ def __init__(
104118)
105119
106120
121+ async def resolve_plant_type (_value , _info ) -> bool :
122+ raise RuntimeError ("Not sure if this is a plant" )
123+
124+
125+ PlantType = GraphQLObjectType (
126+ "Plant" ,
127+ lambda : {"name" : GraphQLField (GraphQLString )},
128+ interfaces = [NamedType ],
129+ is_type_of = resolve_plant_type ,
130+ )
131+
132+
107133def resolve_pet_type (value , _info , _type ):
108134 if isinstance (value , Dog ):
109135 return DogType .name
110136 if isinstance (value , Cat ):
111137 return CatType .name
112138
113139 # Not reachable. All possible types have been considered.
114- assert False , "Unexpected pet type" # pragma: no cover
140+ pytest . fail ( "Unexpected pet type" ) # pragma: no cover
115141
116142
117143PetType = GraphQLUnionType ("Pet" , [DogType , CatType ], resolve_type = resolve_pet_type )
118144
145+ PetOrPlantType = GraphQLUnionType ("PetOrPlantType" , [PlantType , DogType , CatType ])
146+
119147PersonType = GraphQLObjectType (
120148 "Person" ,
121149 lambda : {
122150 "name" : GraphQLField (GraphQLString ),
123151 "pets" : GraphQLField (GraphQLList (PetType )),
124152 "friends" : GraphQLField (GraphQLList (NamedType )),
153+ "responsibilities" : GraphQLField (GraphQLList (PetOrPlantType )),
125154 "progeny" : GraphQLField (GraphQLList (PersonType )), # type: ignore
126155 "mother" : GraphQLField (PersonType ), # type: ignore
127156 "father" : GraphQLField (PersonType ), # type: ignore
@@ -140,8 +169,9 @@ def resolve_pet_type(value, _info, _type):
140169odie .mother = Dog ("Odie's Mom" , True )
141170odie .mother .progeny = [odie ]
142171
172+ fern = Plant ("Fern" )
143173liz = Person ("Liz" , [], [])
144- john = Person ("John" , [garfield , odie ], [liz , odie ])
174+ john = Person ("John" , [garfield , odie ], [liz , odie ], [ garfield , fern ] )
145175
146176
147177def describe_execute_union_and_intersection_types ():
@@ -191,6 +221,7 @@ def can_introspect_on_union_and_intersection_types():
191221 {"name" : "Dog" },
192222 {"name" : "Cat" },
193223 {"name" : "Person" },
224+ {"name" : "Plant" },
194225 ],
195226 "enumValues" : None ,
196227 "inputFields" : None ,
@@ -525,3 +556,38 @@ def resolve_type(_source, info, _type):
525556 "root_value" : root_value ,
526557 "context" : context_value ,
527558 }
559+
560+ @pytest .mark .filterwarnings ("error:.*was never awaited:RuntimeWarning" )
561+ async def handles_rejections_from_is_type_of_after_an_is_type_of_returns_true ():
562+ document = parse ("""
563+ {
564+ responsibilities {
565+ __typename
566+ ... on Dog {
567+ name
568+ barks
569+ }
570+ ... on Cat {
571+ name
572+ meows
573+ }
574+ }
575+ }
576+ """ )
577+
578+ root_value = Person ("John" , [], [liz ], [garfield ])
579+ context_value = {"authToken" : "123abc" }
580+
581+ result = execute (schema , document , root_value , context_value )
582+ assert not isinstance (result , ExecutionResult )
583+ result = await result
584+ assert isinstance (result , ExecutionResult )
585+
586+ assert result == (
587+ {
588+ "responsibilities" : [
589+ {"__typename" : "Cat" , "name" : "Garfield" , "meows" : False },
590+ ],
591+ },
592+ None ,
593+ )
0 commit comments