From 8b870b4361c590b8cb2ca4226ef30f926b40f0c7 Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 29 Sep 2015 11:16:57 -0400 Subject: [PATCH 1/3] Implement `ast_from_value` and tests. Also, move utils to their own files, as we are getting circular imports as introspection imports `ast_from_value`. --- graphql/core/execution/base.py | 2 +- graphql/core/execution/executor.py | 2 +- graphql/core/execution/values.py | 3 +- graphql/core/language/kinds.py | 53 ++++++++++ graphql/core/language/lexer.py | 12 +-- graphql/core/type/introspection.py | 5 +- graphql/core/utils/__init__.py | 0 graphql/core/utils/ast_from_value.py | 70 ++++++++++++++ graphql/core/utils/get_field_def.py | 26 +++++ graphql/core/utils/is_nullish.py | 2 + graphql/core/utils/is_valid_literal_value.py | 52 ++++++++++ graphql/core/utils/type_from_ast.py | 24 +++++ graphql/core/{utils.py => utils/type_info.py} | 96 +------------------ graphql/core/validation/__init__.py | 2 +- graphql/core/validation/rules.py | 3 +- tests/core_language/test_ast_from_value.py | 94 ++++++++++++++++++ 16 files changed, 341 insertions(+), 105 deletions(-) create mode 100644 graphql/core/language/kinds.py create mode 100644 graphql/core/utils/__init__.py create mode 100644 graphql/core/utils/ast_from_value.py create mode 100644 graphql/core/utils/get_field_def.py create mode 100644 graphql/core/utils/is_nullish.py create mode 100644 graphql/core/utils/is_valid_literal_value.py create mode 100644 graphql/core/utils/type_from_ast.py rename graphql/core/{utils.py => utils/type_info.py} (57%) create mode 100644 tests/core_language/test_ast_from_value.py diff --git a/graphql/core/execution/base.py b/graphql/core/execution/base.py index c91a22f1..ae75647a 100644 --- a/graphql/core/execution/base.py +++ b/graphql/core/execution/base.py @@ -15,7 +15,7 @@ TypeMetaFieldDef, TypeNameMetaFieldDef, ) -from ..utils import type_from_ast +from ..utils.type_from_ast import type_from_ast from .values import get_argument_values, get_variable_values Undefined = object() diff --git a/graphql/core/execution/executor.py b/graphql/core/execution/executor.py index f9140a60..ad5ddada 100644 --- a/graphql/core/execution/executor.py +++ b/graphql/core/execution/executor.py @@ -8,7 +8,7 @@ from ..language.source import Source from ..type import GraphQLEnumType, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, \ GraphQLScalarType, GraphQLUnionType -from ..utils import is_nullish +from ..utils.is_nullish import is_nullish from ..validation import validate from .base import ExecutionContext, ExecutionResult, ResolveInfo, Undefined, collect_fields, default_resolve_fn, \ get_argument_values, get_field_def, get_operation_root_type diff --git a/graphql/core/execution/values.py b/graphql/core/execution/values.py index 70d7d871..d8798c6e 100644 --- a/graphql/core/execution/values.py +++ b/graphql/core/execution/values.py @@ -11,7 +11,8 @@ GraphQLScalarType, is_input_type ) -from ..utils import is_nullish, type_from_ast +from ..utils.is_nullish import is_nullish +from ..utils.type_from_ast import type_from_ast __all__ = ['get_variable_values', 'get_argument_values'] diff --git a/graphql/core/language/kinds.py b/graphql/core/language/kinds.py new file mode 100644 index 00000000..80e13fee --- /dev/null +++ b/graphql/core/language/kinds.py @@ -0,0 +1,53 @@ +# Name + +NAME = 'Name' + +# Document + +DOCUMENT = 'Document' +OPERATION_DEFINITION = 'OperationDefinition' +VARIABLE_DEFINITION = 'VariableDefinition' +VARIABLE = 'Variable' +SELECTION_SET = 'SelectionSet' +FIELD = 'Field' +ARGUMENT = 'Argument' + +# Fragments + +FRAGMENT_SPREAD = 'FragmentSpread' +INLINE_FRAGMENT = 'InlineFragment' +FRAGMENT_DEFINITION = 'FragmentDefinition' + +# Values + +INT = 'IntValue' +FLOAT = 'FloatValue' +STRING = 'StringValue' +BOOLEAN = 'BooleanValue' +ENUM = 'EnumValue' +LIST = 'ListValue' +OBJECT = 'ObjectValue' +OBJECT_FIELD = 'ObjectField' + +# Directives + +DIRECTIVE = 'Directive' + +# Types + +NAMED_TYPE = 'NamedType' +LIST_TYPE = 'ListType' +NON_NULL_TYPE = 'NonNullType' + +# Type Definitions + +OBJECT_TYPE_DEFINITION = 'ObjectTypeDefinition' +FIELD_DEFINITION = 'FieldDefinition' +INPUT_VALUE_DEFINITION = 'InputValueDefinition' +INTERFACE_TYPE_DEFINITION = 'InterfaceTypeDefinition' +UNION_TYPE_DEFINITION = 'UnionTypeDefinition' +SCALAR_TYPE_DEFINITION = 'ScalarTypeDefinition' +ENUM_TYPE_DEFINITION = 'EnumTypeDefinition' +ENUM_VALUE_DEFINITION = 'EnumValueDefinition' +INPUT_OBJECT_TYPE_DEFINITION = 'InputObjectTypeDefinition' +TYPE_EXTENSION_DEFINITION = 'TypeExtensionDefinition' \ No newline at end of file diff --git a/graphql/core/language/lexer.py b/graphql/core/language/lexer.py index b8ad565b..3d34954f 100644 --- a/graphql/core/language/lexer.py +++ b/graphql/core/language/lexer.py @@ -143,7 +143,7 @@ def read_token(source, from_position): if code == 46: # . if char_code_at(body, position + 1) == 46 and \ - char_code_at(body, position + 2) == 46: + char_code_at(body, position + 2) == 46: return Token(TokenKind.SPREAD, position, position + 3) elif 65 <= code <= 90 or code == 95 or 97 <= code <= 122: # A-Z, _, a-z @@ -167,11 +167,11 @@ def position_after_whitespace(body, start_position): while position < body_length: code = char_code_at(body, position) if code in ( - 32, # space - 44, # comma - 160, # '\xa0' - 0x2028, # line separator - 0x2029, # paragraph separator + 32, # space + 44, # comma + 160, # '\xa0' + 0x2028, # line separator + 0x2029, # paragraph separator ) or (code > 8 and code < 14): # whitespace position += 1 elif code == 35: # #, skip comments diff --git a/graphql/core/type/introspection.py b/graphql/core/type/introspection.py index ab312c20..639d349a 100644 --- a/graphql/core/type/introspection.py +++ b/graphql/core/type/introspection.py @@ -1,4 +1,3 @@ -import json from .definition import ( GraphQLArgument, GraphQLEnumType, @@ -12,6 +11,8 @@ GraphQLScalarType, GraphQLUnionType, ) +from ..language.printer import print_ast +from ..utils.ast_from_value import ast_from_value from .scalars import GraphQLBoolean, GraphQLString __Schema = GraphQLObjectType( @@ -186,7 +187,7 @@ def input_fields(type, *_): type=GraphQLString, resolver=lambda input_val, *_: None if input_val.default_value is None - else json.dumps(input_val.default_value) + else print_ast(ast_from_value(input_val.default_value, input_val)) ) }) diff --git a/graphql/core/utils/__init__.py b/graphql/core/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/graphql/core/utils/ast_from_value.py b/graphql/core/utils/ast_from_value.py new file mode 100644 index 00000000..fa0791b1 --- /dev/null +++ b/graphql/core/utils/ast_from_value.py @@ -0,0 +1,70 @@ +import json +import re +import sys +from ..language import ast +from ..compat import str_type +from ..type.definition import ( + GraphQLEnumType, + GraphQLInputObjectType, + GraphQLList, + GraphQLNonNull, +) +from ..type.scalars import GraphQLFloat +from .is_nullish import is_nullish + + +def ast_from_value(value, type=None): + if isinstance(type, GraphQLNonNull): + return ast_from_value(value, type.of_type) + + if is_nullish(value): + return None + + if isinstance(value, list): + item_type = type.of_type if isinstance(type, GraphQLList) else None + return ast.ListValue([ast_from_value(item, item_type) for item in value]) + + elif isinstance(type, GraphQLList): + return ast_from_value(value, type.of_type) + + if isinstance(value, bool): + return ast.BooleanValue(value) + + if isinstance(value, (int, float)): + string_num = str(value) + int_value = int(value) + is_int_value = string_num.isdigit() + + if is_int_value or (int_value == value and value < sys.maxsize): + if type == GraphQLFloat: + return ast.FloatValue(str(float(value))) + + return ast.IntValue(str(int(value))) + + return ast.FloatValue(string_num) + + if isinstance(value, str_type): + if isinstance(type, GraphQLEnumType) and re.match(r'^[_a-zA-Z][_a-zA-Z0-9]*$', value): + return ast.EnumValue(value) + + return ast.StringValue(json.dumps(value)[1:-1]) + + assert isinstance(value, dict) + + fields = [] + is_graph_ql_input_object_type = isinstance(type, GraphQLInputObjectType) + + for field_name, field_value in value.items(): + field_type = None + if is_graph_ql_input_object_type: + field_def = type.get_fields().get(field_name) + field_type = field_def and field_def.type + + field_value = ast_from_value(field_value, field_type) + if field_value: + fields.append(ast.ObjectField( + ast.Name(field_name), + field_value + )) + + return ast.ObjectValue(fields) diff --git a/graphql/core/utils/get_field_def.py b/graphql/core/utils/get_field_def.py new file mode 100644 index 00000000..278f5fd5 --- /dev/null +++ b/graphql/core/utils/get_field_def.py @@ -0,0 +1,26 @@ +from ..type.definition import ( + GraphQLInterfaceType, + GraphQLObjectType, + GraphQLUnionType, +) +from ..type.introspection import SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef + + +def get_field_def(schema, parent_type, field_ast): + """Not exactly the same as the executor's definition of get_field_def, in this + statically evaluated environment we do not always have an Object type, + and need to handle Interface and Union types.""" + name = field_ast.name.value + if name == SchemaMetaFieldDef.name and schema.get_query_type() == parent_type: + return SchemaMetaFieldDef + elif name == TypeMetaFieldDef.name and schema.get_query_type() == parent_type: + return TypeMetaFieldDef + elif name == TypeNameMetaFieldDef.name and \ + isinstance(parent_type, ( + GraphQLObjectType, + GraphQLInterfaceType, + GraphQLUnionType, + )): + return TypeNameMetaFieldDef + elif isinstance(parent_type, (GraphQLObjectType, GraphQLInterfaceType)): + return parent_type.get_fields().get(name) diff --git a/graphql/core/utils/is_nullish.py b/graphql/core/utils/is_nullish.py new file mode 100644 index 00000000..3e3a03f9 --- /dev/null +++ b/graphql/core/utils/is_nullish.py @@ -0,0 +1,2 @@ +def is_nullish(value): + return value is None or value != value diff --git a/graphql/core/utils/is_valid_literal_value.py b/graphql/core/utils/is_valid_literal_value.py new file mode 100644 index 00000000..57f47b7e --- /dev/null +++ b/graphql/core/utils/is_valid_literal_value.py @@ -0,0 +1,52 @@ +from ..language import ast +from ..type.definition import ( + GraphQLEnumType, + GraphQLInputObjectType, + GraphQLList, + GraphQLNonNull, + GraphQLScalarType, +) +from .is_nullish import is_nullish + + +def is_valid_literal_value(type, value_ast): + if isinstance(type, GraphQLNonNull): + if not value_ast: + return False + + of_type = type.of_type + return is_valid_literal_value(of_type, value_ast) + + if not value_ast: + return True + + if isinstance(value_ast, ast.Variable): + return True + + if isinstance(type, GraphQLList): + item_type = type.of_type + if isinstance(value_ast, ast.ListValue): + return all(is_valid_literal_value(item_type, item_ast) for item_ast in value_ast.values) + + return is_valid_literal_value(item_type, value_ast) + + if isinstance(type, GraphQLInputObjectType): + if not isinstance(value_ast, ast.ObjectValue): + return False + + fields = type.get_fields() + field_asts = value_ast.fields + + if any(not fields.get(field_ast.name.value, None) for field_ast in field_asts): + return False + + field_ast_map = {field_ast.name.value: field_ast for field_ast in field_asts} + get_field_ast_value = lambda field_name: field_ast_map[ + field_name].value if field_name in field_ast_map else None + + return all(is_valid_literal_value(field.type, get_field_ast_value(field_name)) + for field_name, field in fields.items()) + + assert isinstance(type, (GraphQLScalarType, GraphQLEnumType)), 'Must be input type' + + return not is_nullish(type.parse_literal(value_ast)) diff --git a/graphql/core/utils/type_from_ast.py b/graphql/core/utils/type_from_ast.py new file mode 100644 index 00000000..e52c907e --- /dev/null +++ b/graphql/core/utils/type_from_ast.py @@ -0,0 +1,24 @@ +from ..language import ast +from ..type.definition import ( + GraphQLList, + GraphQLNonNull, +) + + +def type_from_ast(schema, input_type_ast): + if isinstance(input_type_ast, ast.ListType): + inner_type = type_from_ast(schema, input_type_ast.type) + if inner_type: + return GraphQLList(inner_type) + else: + return None + + if isinstance(input_type_ast, ast.NonNullType): + inner_type = type_from_ast(schema, input_type_ast.type) + if inner_type: + return GraphQLNonNull(inner_type) + else: + return None + + assert isinstance(input_type_ast, ast.NamedType), 'Must be a type name.' + return schema.get_type(input_type_ast.name.value) diff --git a/graphql/core/utils.py b/graphql/core/utils/type_info.py similarity index 57% rename from graphql/core/utils.py rename to graphql/core/utils/type_info.py index c6df6d33..3b9404f1 100644 --- a/graphql/core/utils.py +++ b/graphql/core/utils/type_info.py @@ -1,39 +1,14 @@ -from .language import ast -from .type.definition import ( - GraphQLEnumType, +from ..language import ast +from ..type.definition import ( GraphQLInputObjectType, - GraphQLInterfaceType, GraphQLList, - GraphQLNonNull, - GraphQLObjectType, - GraphQLScalarType, - GraphQLUnionType, get_named_type, get_nullable_type, is_composite_type, ) -from .type.introspection import SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef - -def type_from_ast(schema, input_type_ast): - if isinstance(input_type_ast, ast.ListType): - inner_type = type_from_ast(schema, input_type_ast.type) - if inner_type: - return GraphQLList(inner_type) - else: - return None - if isinstance(input_type_ast, ast.NonNullType): - inner_type = type_from_ast(schema, input_type_ast.type) - if inner_type: - return GraphQLNonNull(inner_type) - else: - return None - assert isinstance(input_type_ast, ast.NamedType), 'Must be a type name.' - return schema.get_type(input_type_ast.name.value) - - -def is_nullish(value): - return value is None or value != value +from .get_field_def import get_field_def +from .type_from_ast import type_from_ast def pop(lst): @@ -149,66 +124,3 @@ def leave(self, node): pop(self._input_type_stack) elif isinstance(node, (ast.ListType, ast.ObjectField)): pop(self._input_type_stack) - - -def get_field_def(schema, parent_type, field_ast): - """Not exactly the same as the executor's definition of get_field_def, in this - statically evaluated environment we do not always have an Object type, - and need to handle Interface and Union types.""" - name = field_ast.name.value - if name == SchemaMetaFieldDef.name and schema.get_query_type() == parent_type: - return SchemaMetaFieldDef - elif name == TypeMetaFieldDef.name and schema.get_query_type() == parent_type: - return TypeMetaFieldDef - elif name == TypeNameMetaFieldDef.name and \ - isinstance(parent_type, ( - GraphQLObjectType, - GraphQLInterfaceType, - GraphQLUnionType, - )): - return TypeNameMetaFieldDef - elif isinstance(parent_type, (GraphQLObjectType, GraphQLInterfaceType)): - return parent_type.get_fields().get(name) - - -def is_valid_literal_value(type, value_ast): - if isinstance(type, GraphQLNonNull): - if not value_ast: - return False - - of_type = type.of_type - return is_valid_literal_value(of_type, value_ast) - - if not value_ast: - return True - - if isinstance(value_ast, ast.Variable): - return True - - if isinstance(type, GraphQLList): - item_type = type.of_type - if isinstance(value_ast, ast.ListValue): - return all(is_valid_literal_value(item_type, item_ast) for item_ast in value_ast.values) - - return is_valid_literal_value(item_type, value_ast) - - if isinstance(type, GraphQLInputObjectType): - if not isinstance(value_ast, ast.ObjectValue): - return False - - fields = type.get_fields() - field_asts = value_ast.fields - - if any(not fields.get(field_ast.name.value, None) for field_ast in field_asts): - return False - - field_ast_map = {field_ast.name.value: field_ast for field_ast in field_asts} - get_field_ast_value = lambda field_name: field_ast_map[ - field_name].value if field_name in field_ast_map else None - - return all(is_valid_literal_value(field.type, get_field_ast_value(field_name)) - for field_name, field in fields.items()) - - assert isinstance(type, (GraphQLScalarType, GraphQLEnumType)), 'Must be input type' - - return not is_nullish(type.parse_literal(value_ast)) diff --git a/graphql/core/validation/__init__.py b/graphql/core/validation/__init__.py index c6d43b63..b2f5badd 100644 --- a/graphql/core/validation/__init__.py +++ b/graphql/core/validation/__init__.py @@ -3,7 +3,7 @@ from ..language.ast import FragmentDefinition, FragmentSpread from ..language.visitor import Visitor, visit from ..type import GraphQLSchema -from ..utils import TypeInfo +from ..utils.type_info import TypeInfo specified_rules = [ Rules.UniqueOperationNames, diff --git a/graphql/core/validation/rules.py b/graphql/core/validation/rules.py index dee5407a..03983b44 100644 --- a/graphql/core/validation/rules.py +++ b/graphql/core/validation/rules.py @@ -14,7 +14,8 @@ is_input_type, is_leaf_type, ) -from ..utils import is_valid_literal_value, type_from_ast +from ..utils.is_valid_literal_value import is_valid_literal_value +from ..utils.type_from_ast import type_from_ast from .utils import DefaultOrderedDict, PairSet diff --git a/tests/core_language/test_ast_from_value.py b/tests/core_language/test_ast_from_value.py new file mode 100644 index 00000000..d773015f --- /dev/null +++ b/tests/core_language/test_ast_from_value.py @@ -0,0 +1,94 @@ +from graphql.core.type.definition import GraphQLEnumType, GraphQLList, GraphQLInputObjectType, GraphQLInputObjectField +from graphql.core.type.scalars import GraphQLFloat +from graphql.core.utils.ast_from_value import ast_from_value +from graphql.core.language import ast + + +def test_converts_boolean_values_to_asts(): + assert ast_from_value(True) == ast.BooleanValue(True) + assert ast_from_value(False) == ast.BooleanValue(False) + + +def test_converts_numeric_values_to_asts(): + assert ast_from_value(123) == ast.IntValue('123') + assert ast_from_value(123.0) == ast.IntValue('123') + assert ast_from_value(123.5) == ast.FloatValue('123.5') + assert ast_from_value(1e4) == ast.IntValue('10000') + assert ast_from_value(1e40) == ast.FloatValue('1e+40') + + +def test_it_converts_numeric_values_to_float_asts(): + assert ast_from_value(123, GraphQLFloat) == ast.FloatValue('123.0') + assert ast_from_value(123.0, GraphQLFloat) == ast.FloatValue('123.0') + assert ast_from_value(123.5, GraphQLFloat) == ast.FloatValue('123.5') + assert ast_from_value(1e4, GraphQLFloat) == ast.FloatValue('10000.0') + assert ast_from_value(1e40, GraphQLFloat) == ast.FloatValue('1e+40') + + +def test_it_converts_string_values_to_asts(): + assert ast_from_value('hello') == ast.StringValue('hello') + assert ast_from_value('VALUE') == ast.StringValue('VALUE') + assert ast_from_value(u'VAL\nUE') == ast.StringValue('VAL\\nUE') + assert ast_from_value('VAL\nUE') == ast.StringValue('VAL\\nUE') + assert ast_from_value('123') == ast.StringValue('123') + + +my_enum = GraphQLEnumType( + 'MyEnum', { + 'HELLO': 1, + 'GOODBYE': 2 + } +) + + +def test_converts_string_values_to_enum_asts_if_possible(): + assert ast_from_value('hello', my_enum) == ast.EnumValue('hello') + assert ast_from_value('HELLO', my_enum) == ast.EnumValue('HELLO') + assert ast_from_value('VAL\nUE', my_enum) == ast.StringValue('VAL\\nUE') + assert ast_from_value('123', my_enum) == ast.StringValue('123') + + +def test_converts_array_values_to_list_asts(): + assert ast_from_value(['FOO', 'BAR']) == ast.ListValue( + values=[ + ast.StringValue('FOO'), + ast.StringValue('BAR') + ] + ) + + +def test_converts_list_singletons(): + assert ast_from_value('FOO', GraphQLList(my_enum)) == ast.EnumValue('FOO') + + +def test_converts_input_objects(): + assert ast_from_value({'foo': 3, 'bar': 'HELLO'}) == ast.ObjectValue( + fields=[ + ast.ObjectField( + name=ast.Name('foo'), + value=ast.IntValue('3') + ), + ast.ObjectField( + name=ast.Name('bar'), + value=ast.StringValue('HELLO') + ) + ] + ) + + input_obj = GraphQLInputObjectType('MyInputObj', { + 'foo': GraphQLInputObjectField(GraphQLFloat), + 'bar': GraphQLInputObjectField(my_enum) + }) + + assert ast_from_value({'foo': 3, 'bar': 'HELLO'}, input_obj) == ast.ObjectValue( + fields=[ + ast.ObjectField( + name=ast.Name('foo'), + value=ast.FloatValue('3.0') + ), + ast.ObjectField( + name=ast.Name('bar'), + value=ast.EnumValue('HELLO') + ) + ] + ) From 306beec0accc08383dd925e26bc376f5e95e0b89 Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 29 Sep 2015 11:21:36 -0400 Subject: [PATCH 2/3] Delete `kinds.py` we don't need it. --- graphql/core/language/kinds.py | 53 ---------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 graphql/core/language/kinds.py diff --git a/graphql/core/language/kinds.py b/graphql/core/language/kinds.py deleted file mode 100644 index 80e13fee..00000000 --- a/graphql/core/language/kinds.py +++ /dev/null @@ -1,53 +0,0 @@ -# Name - -NAME = 'Name' - -# Document - -DOCUMENT = 'Document' -OPERATION_DEFINITION = 'OperationDefinition' -VARIABLE_DEFINITION = 'VariableDefinition' -VARIABLE = 'Variable' -SELECTION_SET = 'SelectionSet' -FIELD = 'Field' -ARGUMENT = 'Argument' - -# Fragments - -FRAGMENT_SPREAD = 'FragmentSpread' -INLINE_FRAGMENT = 'InlineFragment' -FRAGMENT_DEFINITION = 'FragmentDefinition' - -# Values - -INT = 'IntValue' -FLOAT = 'FloatValue' -STRING = 'StringValue' -BOOLEAN = 'BooleanValue' -ENUM = 'EnumValue' -LIST = 'ListValue' -OBJECT = 'ObjectValue' -OBJECT_FIELD = 'ObjectField' - -# Directives - -DIRECTIVE = 'Directive' - -# Types - -NAMED_TYPE = 'NamedType' -LIST_TYPE = 'ListType' -NON_NULL_TYPE = 'NonNullType' - -# Type Definitions - -OBJECT_TYPE_DEFINITION = 'ObjectTypeDefinition' -FIELD_DEFINITION = 'FieldDefinition' -INPUT_VALUE_DEFINITION = 'InputValueDefinition' -INTERFACE_TYPE_DEFINITION = 'InterfaceTypeDefinition' -UNION_TYPE_DEFINITION = 'UnionTypeDefinition' -SCALAR_TYPE_DEFINITION = 'ScalarTypeDefinition' -ENUM_TYPE_DEFINITION = 'EnumTypeDefinition' -ENUM_VALUE_DEFINITION = 'EnumValueDefinition' -INPUT_OBJECT_TYPE_DEFINITION = 'InputObjectTypeDefinition' -TYPE_EXTENSION_DEFINITION = 'TypeExtensionDefinition' \ No newline at end of file From 212503e2f5af3f6b6fd37450451bd640724ed717 Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 29 Sep 2015 11:52:59 -0400 Subject: [PATCH 3/3] Move test_ast_from_value to core_utils test folder. --- tests/{core_language => core_utils}/test_ast_from_value.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{core_language => core_utils}/test_ast_from_value.py (100%) diff --git a/tests/core_language/test_ast_from_value.py b/tests/core_utils/test_ast_from_value.py similarity index 100% rename from tests/core_language/test_ast_from_value.py rename to tests/core_utils/test_ast_from_value.py