def _compile_property_ast(schema, current_schema_type, ast, location, context, unique_local_directives): """Process property directives at this AST node, updating the query context as appropriate. Args: schema: GraphQL schema object, obtained from the graphql library current_schema_type: GraphQLType, the schema type at the current location ast: GraphQL AST node, obtained from the graphql library. Only for function signature uniformity at the moment -- it is currently not used. location: Location object representing the current location in the query context: dict, various per-compilation data (e.g. declared tags, whether the current block is optional, etc.). May be mutated in-place in this function! unique_local_directives: dict, directive name string -> directive object, containing unique directives present on the current AST node *only* """ validate_property_directives(unique_local_directives) # step P-2: process property-only directives tag_directive = unique_local_directives.get('tag', None) if tag_directive: if is_in_fold_scope(context): raise GraphQLCompilationError( u'Tagging values within a @fold vertex field is ' u'not allowed! Location: {}'.format(location)) # Schema validation has ensured that the fields below exist. tag_name = tag_directive.arguments[0].value.value if tag_name in context['tags']: raise GraphQLCompilationError( u'Cannot reuse tag name: {}'.format(tag_name)) validate_safe_string(tag_name) context['tags'][tag_name] = { 'location': location, 'optional': is_in_optional_scope(context), 'type': strip_non_null_from_type(current_schema_type), } output_directive = unique_local_directives.get('output', None) if output_directive: # Schema validation has ensured that the fields below exist. output_name = output_directive.arguments[0].value.value if output_name in context['outputs']: raise GraphQLCompilationError(u'Cannot reuse output name: ' u'{}, {}'.format( output_name, context)) validate_safe_string(output_name) graphql_type = strip_non_null_from_type(current_schema_type) if is_in_fold_scope(context): graphql_type = GraphQLList(graphql_type) # Fold outputs are only allowed at the last level of traversal context['fold_innermost_scope'] = None context['outputs'][output_name] = { 'location': location, 'optional': is_in_optional_scope(context), 'type': graphql_type, 'fold': context.get('fold', None), }
def test_is_type_of_used_to_resolve_runtime_type_for_interface(): PetType = GraphQLInterfaceType( name='Pet', fields={ 'name': GraphQLField(GraphQLString) } ) DogType = GraphQLObjectType( name='Dog', interfaces=[PetType], is_type_of=is_type_of(Dog), fields={ 'name': GraphQLField(GraphQLString), 'woofs': GraphQLField(GraphQLBoolean) } ) CatType = GraphQLObjectType( name='Cat', interfaces=[PetType], is_type_of=is_type_of(Cat), fields={ 'name': GraphQLField(GraphQLString), 'meows': GraphQLField(GraphQLBoolean) } ) schema = GraphQLSchema( query=GraphQLObjectType( name='Query', fields={ 'pets': GraphQLField( GraphQLList(PetType), resolver=lambda *_: [Dog('Odie', True), Cat('Garfield', False)] ) } ), types=[CatType, DogType] ) query = ''' { pets { name ... on Dog { woofs } ... on Cat { meows } } } ''' result = graphql(schema, query) assert not result.errors assert result.data == {'pets': [{'woofs': True, 'name': 'Odie'}, {'name': 'Garfield', 'meows': False}]}
def test_is_type_of_used_to_resolve_runtime_type_for_interface(): # type: () -> None PetType = GraphQLInterfaceType( name="Pet", fields={"name": GraphQLField(GraphQLString)} ) DogType = GraphQLObjectType( name="Dog", interfaces=[PetType], is_type_of=is_type_of(Dog), fields={ "name": GraphQLField(GraphQLString), "woofs": GraphQLField(GraphQLBoolean), }, ) CatType = GraphQLObjectType( name="Cat", interfaces=[PetType], is_type_of=is_type_of(Cat), fields={ "name": GraphQLField(GraphQLString), "meows": GraphQLField(GraphQLBoolean), }, ) schema = GraphQLSchema( query=GraphQLObjectType( name="Query", fields={ "pets": GraphQLField( GraphQLList(PetType), resolver=lambda *_: [Dog("Odie", True), Cat("Garfield", False)], ) }, ), types=[CatType, DogType], ) query = """ { pets { name ... on Dog { woofs } ... on Cat { meows } } } """ result = graphql(schema, query) assert not result.errors assert result.data == { "pets": [{"woofs": True, "name": "Odie"}, {"name": "Garfield", "meows": False}] }
def test_resolve_type_on_union_yields_useful_error(): DogType = GraphQLObjectType(name='Dog', fields={ 'name': GraphQLField(GraphQLString), 'woofs': GraphQLField(GraphQLBoolean) }) HumanType = GraphQLObjectType(name='Human', fields={ 'name': GraphQLField(GraphQLString), }) CatType = GraphQLObjectType(name='Cat', fields={ 'name': GraphQLField(GraphQLString), 'meows': GraphQLField(GraphQLBoolean) }) PetType = GraphQLUnionType( name='Pet', types=[DogType, CatType], resolve_type=make_type_resolver( lambda: [(Dog, DogType), (Cat, CatType), (Human, HumanType)])) schema = GraphQLSchema( query=GraphQLObjectType(name='Query', fields={ 'pets': GraphQLField(GraphQLList(PetType), resolver=lambda *_: [ Dog('Odie', True), Cat('Garfield', False), Human('Jon') ]) })) query = ''' { pets { ... on Dog { name woofs } ... on Cat { name meows } } } ''' result = graphql(schema, query) assert result.errors[ 0].message == 'Runtime Object type "Human" is not a possible type for "Pet".' assert result.data == { 'pets': [{ 'woofs': True, 'name': 'Odie' }, { 'name': 'Garfield', 'meows': False }, None] }
def test_resolve_type_can_use_type_string(): def type_string_resolver(obj, *_): if isinstance(obj, Dog): return 'Dog' if isinstance(obj, Cat): return 'Cat' PetType = GraphQLInterfaceType( name='Pet', fields={'name': GraphQLField(GraphQLString)}, resolve_type=type_string_resolver) DogType = GraphQLObjectType(name='Dog', interfaces=[PetType], fields={ 'name': GraphQLField(GraphQLString), 'woofs': GraphQLField(GraphQLBoolean) }) CatType = GraphQLObjectType(name='Cat', interfaces=[PetType], fields={ 'name': GraphQLField(GraphQLString), 'meows': GraphQLField(GraphQLBoolean) }) schema = GraphQLSchema(query=GraphQLObjectType( name='Query', fields={ 'pets': GraphQLField( GraphQLList(PetType), resolver=lambda *_: [Dog('Odie', True), Cat('Garfield', False)]) }), types=[CatType, DogType]) query = ''' { pets { name ... on Dog { woofs } ... on Cat { meows } } } ''' result = graphql(schema, query) assert not result.errors assert result.data == { 'pets': [{ 'woofs': True, 'name': 'Odie' }, { 'name': 'Garfield', 'meows': False }] }
SomeBox = GraphQLInterfaceType( "SomeBox", fields=lambda: { "deepBox": GraphQLField(SomeBox), "unrelatedField": GraphQLField(GraphQLString), }, resolve_type=lambda *_: StringBox, ) StringBox = GraphQLObjectType( "StringBox", fields=lambda: { "scalar": GraphQLField(GraphQLString), "deepBox": GraphQLField(StringBox), "unrelatedField": GraphQLField(GraphQLString), "listStringBox": GraphQLField(GraphQLList(StringBox)), "stringBox": GraphQLField(StringBox), "intBox": GraphQLField(IntBox), }, interfaces=[SomeBox], ) IntBox = GraphQLObjectType( "IntBox", fields=lambda: { "scalar": GraphQLField(GraphQLInt), "deepBox": GraphQLField(IntBox), "unrelatedField": GraphQLField(GraphQLString), "listStringBox": GraphQLField(GraphQLList(StringBox)), "stringBox": GraphQLField(StringBox), "intBox": GraphQLField(IntBox),
"name": GraphQLString, "value": GraphQLString } ) QueryRootType = GraphQLObjectType( name="QueryRoot", fields={ "thrower": GraphQLField(GraphQLNonNull(GraphQLString), resolve=resolve_raises), "request": GraphQLField( GraphQLNonNull(GraphQLString), resolve=lambda obj, info: info.context["request"].args.get("q"), ), "movies": GraphQLField( description="This is a list of books", type_=GraphQLList(MovieType), resolve=lambda x, y: movies ), "groverZeroZero": GraphQLField( description="Grover search alg 00", type_=GroverType, resolve=lambda x, y: GroverTwo() ), "context": GraphQLField( GraphQLObjectType( name="context", fields={ "session": GraphQLField(GraphQLString), "request": GraphQLField( GraphQLNonNull(GraphQLString), resolve=lambda obj, info: info.context["request"],
def test_converts_list_singletons(): assert ast_from_value("FOO", GraphQLList(my_enum)) == ast.EnumValue("FOO")
def test_resolve_type_can_use_type_string(): # type: () -> None def type_string_resolver(obj, *_): # type: (Union[Cat, Dog], *ResolveInfo) -> str if isinstance(obj, Dog): return "Dog" if isinstance(obj, Cat): return "Cat" PetType = GraphQLInterfaceType( name="Pet", fields={"name": GraphQLField(GraphQLString)}, resolve_type=type_string_resolver, ) DogType = GraphQLObjectType( name="Dog", interfaces=[PetType], fields={ "name": GraphQLField(GraphQLString), "woofs": GraphQLField(GraphQLBoolean), }, ) CatType = GraphQLObjectType( name="Cat", interfaces=[PetType], fields={ "name": GraphQLField(GraphQLString), "meows": GraphQLField(GraphQLBoolean), }, ) schema = GraphQLSchema( query=GraphQLObjectType( name="Query", fields={ "pets": GraphQLField( GraphQLList(PetType), resolver=lambda *_: [Dog("Odie", True), Cat("Garfield", False)], ) }, ), types=[CatType, DogType], ) query = """ { pets { name ... on Dog { woofs } ... on Cat { meows } } } """ result = graphql(schema, query) assert not result.errors assert result.data == { "pets": [{"woofs": True, "name": "Odie"}, {"name": "Garfield", "meows": False}] }
def test_resolve_type_on_union_yields_useful_error(): # type: () -> None DogType = GraphQLObjectType( name="Dog", fields={ "name": GraphQLField(GraphQLString), "woofs": GraphQLField(GraphQLBoolean), }, ) HumanType = GraphQLObjectType( name="Human", fields={"name": GraphQLField(GraphQLString)} ) CatType = GraphQLObjectType( name="Cat", fields={ "name": GraphQLField(GraphQLString), "meows": GraphQLField(GraphQLBoolean), }, ) PetType = GraphQLUnionType( name="Pet", types=[DogType, CatType], resolve_type=make_type_resolver( lambda: [(Dog, DogType), (Cat, CatType), (Human, HumanType)] ), ) schema = GraphQLSchema( query=GraphQLObjectType( name="Query", fields={ "pets": GraphQLField( GraphQLList(PetType), resolver=lambda *_: [ Dog("Odie", True), Cat("Garfield", False), Human("Jon"), ], ) }, ) ) query = """ { pets { ... on Dog { name woofs } ... on Cat { name meows } } } """ result = graphql(schema, query) assert ( result.errors[0].message == 'Runtime Object type "Human" is not a possible type for "Pet".' ) assert result.data == { "pets": [ {"woofs": True, "name": "Odie"}, {"name": "Garfield", "meows": False}, None, ] }
SomeBox = GraphQLInterfaceType( 'SomeBox', fields=lambda: { 'deepBox': GraphQLField(SomeBox), 'unrelatedField': GraphQLField(GraphQLString) }, resolve_type=lambda *_: StringBox ) StringBox = GraphQLObjectType( 'StringBox', fields=lambda: { 'scalar': GraphQLField(GraphQLString), 'deepBox': GraphQLField(StringBox), 'unrelatedField': GraphQLField(GraphQLString), 'listStringBox': GraphQLField(GraphQLList(StringBox)), 'stringBox': GraphQLField(StringBox), 'intBox': GraphQLField(IntBox), }, interfaces=[SomeBox] ) IntBox = GraphQLObjectType( 'IntBox', fields=lambda: { 'scalar': GraphQLField(GraphQLInt), 'deepBox': GraphQLField(IntBox), 'unrelatedField': GraphQLField(GraphQLString), 'listStringBox': GraphQLField(GraphQLList(StringBox)), 'stringBox': GraphQLField(StringBox), 'intBox': GraphQLField(IntBox),