def is_type_of_used_to_resolve_runtime_type_for_union():
        DogType = GraphQLObjectType(
            "Dog",
            {
                "name": GraphQLField(GraphQLString),
                "woofs": GraphQLField(GraphQLBoolean),
            },
            is_type_of=get_is_type_of(Dog),
        )

        CatType = GraphQLObjectType(
            "Cat",
            {
                "name": GraphQLField(GraphQLString),
                "meows": GraphQLField(GraphQLBoolean),
            },
            is_type_of=get_is_type_of(Cat),
        )

        PetType = GraphQLUnionType("Pet", [CatType, DogType])

        schema = GraphQLSchema(
            GraphQLObjectType(
                "Query",
                {
                    "pets":
                    GraphQLField(
                        GraphQLList(PetType),
                        resolve=lambda *_args: [
                            Dog("Odie", True),
                            Cat("Garfield", False),
                        ],
                    )
                },
            ))

        query = """
            {
              pets {
                ... on Dog {
                  name
                  woofs
                }
                ... on Cat {
                  name
                  meows
                }
              }
            }
            """

        result = graphql_sync(schema, query)
        assert result == (
            {
                "pets": [
                    {
                        "name": "Odie",
                        "woofs": True
                    },
                    {
                        "name": "Garfield",
                        "meows": False
                    },
                ]
            },
            None,
        )
Esempio n. 2
0
    def define_sample_schema():
        BlogImage = GraphQLObjectType(
            "Image",
            {
                "url": GraphQLField(GraphQLString),
                "width": GraphQLField(GraphQLInt),
                "height": GraphQLField(GraphQLInt),
            },
        )

        BlogArticle: GraphQLObjectType

        BlogAuthor = GraphQLObjectType(
            "Author",
            lambda: {
                "id":
                GraphQLField(GraphQLString),
                "name":
                GraphQLField(GraphQLString),
                "pic":
                GraphQLField(
                    BlogImage,
                    args={
                        "width": GraphQLArgument(GraphQLInt),
                        "height": GraphQLArgument(GraphQLInt),
                    },
                ),
                "recentArticle":
                GraphQLField(BlogArticle),
            },
        )

        BlogArticle = GraphQLObjectType(
            "Article",
            lambda: {
                "id": GraphQLField(GraphQLString),
                "isPublished": GraphQLField(GraphQLBoolean),
                "author": GraphQLField(BlogAuthor),
                "title": GraphQLField(GraphQLString),
                "body": GraphQLField(GraphQLString),
            },
        )

        BlogQuery = GraphQLObjectType(
            "Query",
            {
                "article":
                GraphQLField(BlogArticle,
                             args={"id": GraphQLArgument(GraphQLString)}),
                "feed":
                GraphQLField(GraphQLList(BlogArticle)),
            },
        )

        BlogMutation = GraphQLObjectType(
            "Mutation", {"writeArticle": GraphQLField(BlogArticle)})

        BlogSubscription = GraphQLObjectType(
            "Subscription",
            {
                "articleSubscribe":
                GraphQLField(args={"id": GraphQLArgument(GraphQLString)},
                             type_=BlogArticle)
            },
        )

        schema = GraphQLSchema(
            BlogQuery,
            BlogMutation,
            BlogSubscription,
            description="Sample schema",
        )

        kwargs = schema.to_kwargs()
        types = kwargs.pop("types")
        assert types == list(schema.type_map.values())
        assert kwargs == {
            "query": BlogQuery,
            "mutation": BlogMutation,
            "subscription": BlogSubscription,
            "directives": specified_directives,
            "description": "Sample schema",
            "extensions": None,
            "ast_node": None,
            "extension_ast_nodes": [],
            "assume_valid": False,
        }

        assert print_schema(schema) == dedent('''
            """Sample schema"""
            schema {
              query: Query
              mutation: Mutation
              subscription: Subscription
            }

            type Query {
              article(id: String): Article
              feed: [Article]
            }

            type Article {
              id: String
              isPublished: Boolean
              author: Author
              title: String
              body: String
            }

            type Author {
              id: String
              name: String
              pic(width: Int, height: Int): Image
              recentArticle: Article
            }

            type Image {
              url: String
              width: Int
              height: Int
            }

            type Mutation {
              writeArticle: Article
            }

            type Subscription {
              articleSubscribe(id: String): Article
            }
            ''')
Esempio n. 3
0
)

InboxType = GraphQLObjectType(
    "Inbox",
    {
        "total":
        GraphQLField(GraphQLInt,
                     resolve=lambda inbox, _info: len(inbox["emails"])),
        "unread":
        GraphQLField(
            GraphQLInt,
            resolve=lambda inbox, _info: sum(1 for email in inbox["emails"]
                                             if email["unread"]),
        ),
        "emails":
        GraphQLField(GraphQLList(EmailType)),
    },
)

QueryType = GraphQLObjectType("Query", {"inbox": GraphQLField(InboxType)})

EmailEventType = GraphQLObjectType("EmailEvent", {
    "email": GraphQLField(EmailType),
    "inbox": GraphQLField(InboxType)
})


async def anext(iterable):
    """Return the next item from an async iterator."""
    return await iterable.__anext__()
Esempio n. 4
0
CatOrDog = GraphQLUnionType('CatOrDog', [Dog, Cat])

Intelligent = GraphQLInterfaceType('Intelligent', {
    'iq': GraphQLField(GraphQLInt),
})

Human = GraphQLObjectType(
    name='Human',
    interfaces=[Being, Intelligent],
    is_type_of=lambda: None,
    fields={
        'name': GraphQLField(GraphQLString, {
            'surname': GraphQLArgument(GraphQLBoolean),
        }),
        'pets': GraphQLField(GraphQLList(Pet)),
        'iq': GraphQLField(GraphQLInt),
    },
)

Alien = GraphQLObjectType(
    name='Alien',
    is_type_of=lambda *args: True,
    interfaces=[Being, Intelligent],
    fields={
        'iq': GraphQLField(GraphQLInt),
        'name': GraphQLField(GraphQLString, {
            'surname': GraphQLArgument(GraphQLBoolean),
        }),
        'numEyes': GraphQLField(GraphQLInt),
    },
Esempio n. 5
0
def describe_value_from_ast():
    def _test_case(type_, value_text, expected):
        value_node = parse_value(value_text)
        assert value_from_ast(value_node, type_) == expected

    def _test_case_expect_nan(type_, value_text):
        value_node = parse_value(value_text)
        assert isnan(value_from_ast(value_node, type_))

    def _test_case_with_vars(variables, type_, value_text, expected):
        value_node = parse_value(value_text)
        assert value_from_ast(value_node, type_, variables) == expected

    def rejects_empty_input():
        # noinspection PyTypeChecker
        assert value_from_ast(None, GraphQLBoolean) is INVALID

    def converts_according_to_input_coercion_rules():
        _test_case(GraphQLBoolean, "true", True)
        _test_case(GraphQLBoolean, "false", False)
        _test_case(GraphQLInt, "123", 123)
        _test_case(GraphQLFloat, "123", 123)
        _test_case(GraphQLFloat, "123.456", 123.456)
        _test_case(GraphQLString, '"abc123"', "abc123")
        _test_case(GraphQLID, "123456", "123456")
        _test_case(GraphQLID, '"123456"', "123456")

    def does_not_convert_when_input_coercion_rules_reject_a_value():
        _test_case(GraphQLBoolean, "123", INVALID)
        _test_case(GraphQLInt, "123.456", INVALID)
        _test_case(GraphQLInt, "true", INVALID)
        _test_case(GraphQLInt, '"123"', INVALID)
        _test_case(GraphQLFloat, '"123"', INVALID)
        _test_case(GraphQLString, "123", INVALID)
        _test_case(GraphQLString, "true", INVALID)
        _test_case(GraphQLID, "123.456", INVALID)

    test_enum = GraphQLEnumType(
        "TestColor",
        {
            "RED": 1,
            "GREEN": 2,
            "BLUE": 3,
            "NULL": None,
            "INVALID": INVALID,
            "NAN": nan
        },
    )

    def converts_enum_values_according_to_input_coercion_rules():
        _test_case(test_enum, "RED", 1)
        _test_case(test_enum, "BLUE", 3)
        _test_case(test_enum, "YELLOW", INVALID)
        _test_case(test_enum, "3", INVALID)
        _test_case(test_enum, '"BLUE"', INVALID)
        _test_case(test_enum, "null", None)
        _test_case(test_enum, "NULL", None)
        _test_case(test_enum, "INVALID", INVALID)
        # nan is not equal to itself, needs a special test case
        _test_case_expect_nan(test_enum, "NAN")

    # Boolean!
    non_null_bool = GraphQLNonNull(GraphQLBoolean)
    # [Boolean]
    list_of_bool = GraphQLList(GraphQLBoolean)
    # [Boolean!]
    list_of_non_null_bool = GraphQLList(non_null_bool)
    # [Boolean]!
    non_null_list_of_bool = GraphQLNonNull(list_of_bool)
    # [Boolean!]!
    non_null_list_of_non_mull_bool = GraphQLNonNull(list_of_non_null_bool)

    def coerces_to_null_unless_non_null():
        _test_case(GraphQLBoolean, "null", None)
        _test_case(non_null_bool, "null", INVALID)

    def coerces_lists_of_values():
        _test_case(list_of_bool, "true", [True])
        _test_case(list_of_bool, "123", INVALID)
        _test_case(list_of_bool, "null", None)
        _test_case(list_of_bool, "[true, false]", [True, False])
        _test_case(list_of_bool, "[true, 123]", INVALID)
        _test_case(list_of_bool, "[true, null]", [True, None])
        _test_case(list_of_bool, "{ true: true }", INVALID)

    def coerces_non_null_lists_of_values():
        _test_case(non_null_list_of_bool, "true", [True])
        _test_case(non_null_list_of_bool, "123", INVALID)
        _test_case(non_null_list_of_bool, "null", INVALID)
        _test_case(non_null_list_of_bool, "[true, false]", [True, False])
        _test_case(non_null_list_of_bool, "[true, 123]", INVALID)
        _test_case(non_null_list_of_bool, "[true, null]", [True, None])

    def coerces_lists_of_non_null_values():
        _test_case(list_of_non_null_bool, "true", [True])
        _test_case(list_of_non_null_bool, "123", INVALID)
        _test_case(list_of_non_null_bool, "null", None)
        _test_case(list_of_non_null_bool, "[true, false]", [True, False])
        _test_case(list_of_non_null_bool, "[true, 123]", INVALID)
        _test_case(list_of_non_null_bool, "[true, null]", INVALID)

    def coerces_non_null_lists_of_non_null_values():
        _test_case(non_null_list_of_non_mull_bool, "true", [True])
        _test_case(non_null_list_of_non_mull_bool, "123", INVALID)
        _test_case(non_null_list_of_non_mull_bool, "null", INVALID)
        _test_case(non_null_list_of_non_mull_bool, "[true, false]",
                   [True, False])
        _test_case(non_null_list_of_non_mull_bool, "[true, 123]", INVALID)
        _test_case(non_null_list_of_non_mull_bool, "[true, null]", INVALID)

    test_input_obj = GraphQLInputObjectType(
        "TestInput",
        {
            "int": GraphQLInputField(GraphQLInt, default_value=42),
            "bool": GraphQLInputField(GraphQLBoolean),
            "requiredBool": GraphQLInputField(non_null_bool),
        },
    )

    def coerces_input_objects_according_to_input_coercion_rules():
        _test_case(test_input_obj, "null", None)
        _test_case(test_input_obj, "123", INVALID)
        _test_case(test_input_obj, "[]", INVALID)
        _test_case(
            test_input_obj,
            "{ int: 123, requiredBool: false }",
            {
                "int": 123,
                "requiredBool": False
            },
        )
        _test_case(
            test_input_obj,
            "{ bool: true, requiredBool: false }",
            {
                "int": 42,
                "bool": True,
                "requiredBool": False
            },
        )
        _test_case(test_input_obj, "{ int: true, requiredBool: true }",
                   INVALID)
        _test_case(test_input_obj, "{ requiredBool: null }", INVALID)
        _test_case(test_input_obj, "{ bool: true }", INVALID)

    def accepts_variable_values_assuming_already_coerced():
        _test_case_with_vars({}, GraphQLBoolean, "$var", INVALID)
        _test_case_with_vars({"var": True}, GraphQLBoolean, "$var", True)
        _test_case_with_vars({"var": None}, GraphQLBoolean, "$var", None)

    def asserts_variables_are_provided_as_items_in_lists():
        _test_case_with_vars({}, list_of_bool, "[ $foo ]", [None])
        _test_case_with_vars({}, list_of_non_null_bool, "[ $foo ]", INVALID)
        _test_case_with_vars({"foo": True}, list_of_non_null_bool, "[ $foo ]",
                             [True])
        # Note: variables are expected to have already been coerced, so we
        # do not expect the singleton wrapping behavior for variables.
        _test_case_with_vars({"foo": True}, list_of_non_null_bool, "$foo",
                             True)
        _test_case_with_vars({"foo": [True]}, list_of_non_null_bool, "$foo",
                             [True])

    def omits_input_object_fields_for_unprovided_variables():
        _test_case_with_vars(
            {},
            test_input_obj,
            "{ int: $foo, bool: $foo, requiredBool: true }",
            {
                "int": 42,
                "requiredBool": True
            },
        )
        _test_case_with_vars({}, test_input_obj, "{ requiredBool: $foo }",
                             INVALID)
        _test_case_with_vars(
            {"foo": True},
            test_input_obj,
            "{ requiredBool: $foo }",
            {
                "int": 42,
                "requiredBool": True
            },
        )

    def transforms_names_using_out_name():
        # This is an extension of GraphQL.js.
        complex_input_obj = GraphQLInputObjectType(
            "Complex",
            {
                "realPart":
                GraphQLInputField(GraphQLFloat, out_name="real_part"),
                "imagPart":
                GraphQLInputField(
                    GraphQLFloat, default_value=0, out_name="imag_part"),
            },
        )
        _test_case(complex_input_obj, "{ realPart: 1 }", {
            "real_part": 1,
            "imag_part": 0
        })

    def transforms_values_with_out_type():
        # This is an extension of GraphQL.js.
        complex_input_obj = GraphQLInputObjectType(
            "Complex",
            {
                "real": GraphQLInputField(GraphQLFloat),
                "imag": GraphQLInputField(GraphQLFloat),
            },
            out_type=lambda value: complex(value["real"], value["imag"]),
        )
        _test_case(complex_input_obj, "{ real: 1, imag: 2 }", 1 + 2j)
 def converts_list_singletons():
     assert ast_from_value(
         "FOO", GraphQLList(GraphQLString)) == StringValueNode(value="FOO")
Esempio n. 7
0
    'Interface', {'fieldName': GraphQLField(GraphQLString)})

DirectiveInputType = GraphQLInputObjectType(
    'DirInput', {'field': GraphQLInputField(GraphQLString)})

WrappedDirectiveInputType = GraphQLInputObjectType(
    'WrappedDirInput', {'field': GraphQLInputField(GraphQLString)})

Directive = GraphQLDirective(name='dir',
                             locations=[DirectiveLocation.OBJECT],
                             args={
                                 'arg':
                                 GraphQLArgument(DirectiveInputType),
                                 'argList':
                                 GraphQLArgument(
                                     GraphQLList(WrappedDirectiveInputType))
                             })

Schema = GraphQLSchema(query=GraphQLObjectType(
    'Query', {'getObject': GraphQLField(InterfaceType, resolve=lambda: {})}),
                       directives=[Directive])


def describe_type_system_schema():
    def describe_type_map():
        def includes_input_types_only_used_in_directives():
            assert 'DirInput' in Schema.type_map
            assert 'WrappedDirInput' in Schema.type_map

    def describe_validity():
        def describe_when_not_assumed_valid():
Esempio n. 8
0
def describe_value_from_ast():
    def _value_from(value_text, type_, variables=None):
        ast = parse_value(value_text)
        return value_from_ast(ast, type_, variables)

    def rejects_empty_input():
        # noinspection PyTypeChecker
        assert value_from_ast(None, GraphQLBoolean) is Undefined

    def converts_according_to_input_coercion_rules():
        assert _value_from("true", GraphQLBoolean) is True
        assert _value_from("false", GraphQLBoolean) is False
        assert _value_from("123", GraphQLInt) == 123
        assert _value_from("123", GraphQLFloat) == 123
        assert _value_from("123.456", GraphQLFloat) == 123.456
        assert _value_from('"abc123"', GraphQLString) == "abc123"
        assert _value_from("123456", GraphQLID) == "123456"
        assert _value_from('"123456"', GraphQLID) == "123456"

    def does_not_convert_when_input_coercion_rules_reject_a_value():
        assert _value_from("123", GraphQLBoolean) is Undefined
        assert _value_from("123.456", GraphQLInt) is Undefined
        assert _value_from("true", GraphQLInt) is Undefined
        assert _value_from('"123"', GraphQLInt) is Undefined
        assert _value_from('"123"', GraphQLFloat) is Undefined
        assert _value_from("123", GraphQLString) is Undefined
        assert _value_from("true", GraphQLString) is Undefined
        assert _value_from("123.456", GraphQLID) is Undefined

    def convert_using_parse_literal_from_a_custom_scalar_type():
        def pass_through_parse_literal(node, _vars=None):
            assert node.kind == "string_value"
            return node.value

        pass_through_scalar = GraphQLScalarType(
            "PassThroughScalar",
            parse_literal=pass_through_parse_literal,
            parse_value=lambda value: value,
        )

        assert _value_from('"value"', pass_through_scalar) == "value"

        def throw_parse_literal(_node, _vars=None):
            raise RuntimeError("Test")

        throw_scalar = GraphQLScalarType(
            "ThrowScalar",
            parse_literal=throw_parse_literal,
            parse_value=lambda value: value,
        )

        assert _value_from("value", throw_scalar) is Undefined

        return_undefined_scalar = GraphQLScalarType(
            "ReturnUndefinedScalar",
            parse_literal=lambda _node, _vars=None: Undefined,
            parse_value=lambda value: value,
        )

        assert _value_from("value", return_undefined_scalar) is Undefined

    def converts_enum_values_according_to_input_coercion_rules():
        test_enum = GraphQLEnumType(
            "TestColor",
            {
                "RED": 1,
                "GREEN": 2,
                "BLUE": 3,
                "NULL": None,
                "NAN": nan,
                "NO_CUSTOM_VALUE": Undefined,
            },
        )

        assert _value_from("RED", test_enum) == 1
        assert _value_from("BLUE", test_enum) == 3
        assert _value_from("YELLOW", test_enum) is Undefined
        assert _value_from("3", test_enum) is Undefined
        assert _value_from('"BLUE"', test_enum) is Undefined
        assert _value_from("null", test_enum) is None
        assert _value_from("NULL", test_enum) is None
        assert _value_from("NULL", GraphQLNonNull(test_enum)) is None
        assert isnan(_value_from("NAN", test_enum))
        assert _value_from("NO_CUSTOM_VALUE", test_enum) is Undefined

    # Boolean!
    non_null_bool = GraphQLNonNull(GraphQLBoolean)
    # [Boolean]
    list_of_bool = GraphQLList(GraphQLBoolean)
    # [Boolean!]
    list_of_non_null_bool = GraphQLList(non_null_bool)
    # [Boolean]!
    non_null_list_of_bool = GraphQLNonNull(list_of_bool)
    # [Boolean!]!
    non_null_list_of_non_mull_bool = GraphQLNonNull(list_of_non_null_bool)

    def coerces_to_null_unless_non_null():
        assert _value_from("null", GraphQLBoolean) is None
        assert _value_from("null", non_null_bool) is Undefined

    def coerces_lists_of_values():
        assert _value_from("true", list_of_bool) == [True]
        assert _value_from("123", list_of_bool) is Undefined
        assert _value_from("null", list_of_bool) is None
        assert _value_from("[true, false]", list_of_bool) == [True, False]
        assert _value_from("[true, 123]", list_of_bool) is Undefined
        assert _value_from("[true, null]", list_of_bool) == [True, None]
        assert _value_from("{ true: true }", list_of_bool) is Undefined

    def coerces_non_null_lists_of_values():
        assert _value_from("true", non_null_list_of_bool) == [True]
        assert _value_from("123", non_null_list_of_bool) is Undefined
        assert _value_from("null", non_null_list_of_bool) is Undefined
        assert _value_from("[true, false]",
                           non_null_list_of_bool) == [True, False]
        assert _value_from("[true, 123]", non_null_list_of_bool) is Undefined
        assert _value_from("[true, null]",
                           non_null_list_of_bool) == [True, None]

    def coerces_lists_of_non_null_values():
        assert _value_from("true", list_of_non_null_bool) == [True]
        assert _value_from("123", list_of_non_null_bool) is Undefined
        assert _value_from("null", list_of_non_null_bool) is None
        assert _value_from("[true, false]",
                           list_of_non_null_bool) == [True, False]
        assert _value_from("[true, 123]", list_of_non_null_bool) is Undefined
        assert _value_from("[true, null]", list_of_non_null_bool) is Undefined

    def coerces_non_null_lists_of_non_null_values():
        assert _value_from("true", non_null_list_of_non_mull_bool) == [True]
        assert _value_from("123", non_null_list_of_non_mull_bool) is Undefined
        assert _value_from("null", non_null_list_of_non_mull_bool) is Undefined
        assert _value_from("[true, false]",
                           non_null_list_of_non_mull_bool) == [
                               True,
                               False,
                           ]
        assert _value_from("[true, 123]",
                           non_null_list_of_non_mull_bool) is Undefined
        assert _value_from("[true, null]",
                           non_null_list_of_non_mull_bool) is Undefined

    test_input_obj = GraphQLInputObjectType(
        "TestInput",
        {
            "int": GraphQLInputField(GraphQLInt, default_value=42),
            "bool": GraphQLInputField(GraphQLBoolean),
            "requiredBool": GraphQLInputField(non_null_bool),
        },
    )

    def coerces_input_objects_according_to_input_coercion_rules():
        assert _value_from("null", test_input_obj) is None
        assert _value_from("[]", test_input_obj) is Undefined
        assert _value_from("123", test_input_obj) is Undefined
        assert _value_from("{ int: 123, requiredBool: false }",
                           test_input_obj) == {
                               "int": 123,
                               "requiredBool": False,
                           }
        assert _value_from("{ bool: true, requiredBool: false }",
                           test_input_obj) == {
                               "int": 42,
                               "bool": True,
                               "requiredBool": False,
                           }
        assert (_value_from("{ int: true, requiredBool: true }",
                            test_input_obj) is Undefined)
        assert _value_from("{ requiredBool: null }",
                           test_input_obj) is Undefined
        assert _value_from("{ bool: true }", test_input_obj) is Undefined

    def accepts_variable_values_assuming_already_coerced():
        assert _value_from("$var", GraphQLBoolean, {}) is Undefined
        assert _value_from("$var", GraphQLBoolean, {"var": True}) is True
        assert _value_from("$var", GraphQLBoolean, {"var": None}) is None
        assert _value_from("$var", non_null_bool, {"var": None}) is Undefined

    def asserts_variables_are_provided_as_items_in_lists():
        assert _value_from("[ $foo ]", list_of_bool, {}) == [None]
        assert _value_from("[ $foo ]", list_of_non_null_bool, {}) is Undefined
        assert _value_from("[ $foo ]", list_of_non_null_bool,
                           {"foo": True}) == [True]
        # Note: variables are expected to have already been coerced, so we
        # do not expect the singleton wrapping behavior for variables.
        assert _value_from("$foo", list_of_non_null_bool,
                           {"foo": True}) is True
        assert _value_from("$foo", list_of_non_null_bool,
                           {"foo": [True]}) == [True]

    def omits_input_object_fields_for_unprovided_variables():
        assert _value_from("{ int: $foo, bool: $foo, requiredBool: true }",
                           test_input_obj, {}) == {
                               "int": 42,
                               "requiredBool": True
                           }
        assert _value_from("{ requiredBool: $foo }", test_input_obj,
                           {}) is Undefined
        assert _value_from("{ requiredBool: $foo }", test_input_obj,
                           {"foo": True}) == {
                               "int": 42,
                               "requiredBool": True,
                           }

    def transforms_names_using_out_name():
        # This is an extension of GraphQL.js.
        complex_input_obj = GraphQLInputObjectType(
            "Complex",
            {
                "realPart":
                GraphQLInputField(GraphQLFloat, out_name="real_part"),
                "imagPart":
                GraphQLInputField(
                    GraphQLFloat, default_value=0, out_name="imag_part"),
            },
        )
        assert _value_from("{ realPart: 1 }", complex_input_obj) == {
            "real_part": 1,
            "imag_part": 0,
        }

    def transforms_values_with_out_type():
        # This is an extension of GraphQL.js.
        complex_input_obj = GraphQLInputObjectType(
            "Complex",
            {
                "real": GraphQLInputField(GraphQLFloat),
                "imag": GraphQLInputField(GraphQLFloat),
            },
            out_type=lambda value: complex(value["real"], value["imag"]),
        )
        assert _value_from("{ real: 1, imag: 2 }", complex_input_obj) == 1 + 2j