mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Added auto_camelcase to TypeMap/Schema
This commit is contained in:
parent
210a2aed49
commit
9f30aa2d45
|
@ -141,3 +141,45 @@ def test_inputobject():
|
||||||
foo_field = fields['fooBar']
|
foo_field = fields['fooBar']
|
||||||
assert isinstance(foo_field, GraphQLInputObjectField)
|
assert isinstance(foo_field, GraphQLInputObjectField)
|
||||||
assert foo_field.description == 'Field description'
|
assert foo_field.description == 'Field description'
|
||||||
|
|
||||||
|
|
||||||
|
def test_objecttype_camelcase():
|
||||||
|
class MyObjectType(ObjectType):
|
||||||
|
'''Description'''
|
||||||
|
foo_bar = String(bar_foo=String())
|
||||||
|
|
||||||
|
typemap = TypeMap([MyObjectType])
|
||||||
|
assert 'MyObjectType' in typemap
|
||||||
|
graphql_type = typemap['MyObjectType']
|
||||||
|
assert isinstance(graphql_type, GraphQLObjectType)
|
||||||
|
assert graphql_type.name == 'MyObjectType'
|
||||||
|
assert graphql_type.description == 'Description'
|
||||||
|
|
||||||
|
fields = graphql_type.fields
|
||||||
|
assert list(fields.keys()) == ['fooBar']
|
||||||
|
foo_field = fields['fooBar']
|
||||||
|
assert isinstance(foo_field, GraphQLField)
|
||||||
|
assert foo_field.args == {
|
||||||
|
'barFoo': GraphQLArgument(GraphQLString, out_name='bar_foo')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_objecttype_camelcase_disabled():
|
||||||
|
class MyObjectType(ObjectType):
|
||||||
|
'''Description'''
|
||||||
|
foo_bar = String(bar_foo=String())
|
||||||
|
|
||||||
|
typemap = TypeMap([MyObjectType], auto_camelcase=False)
|
||||||
|
assert 'MyObjectType' in typemap
|
||||||
|
graphql_type = typemap['MyObjectType']
|
||||||
|
assert isinstance(graphql_type, GraphQLObjectType)
|
||||||
|
assert graphql_type.name == 'MyObjectType'
|
||||||
|
assert graphql_type.description == 'Description'
|
||||||
|
|
||||||
|
fields = graphql_type.fields
|
||||||
|
assert list(fields.keys()) == ['foo_bar']
|
||||||
|
foo_field = fields['foo_bar']
|
||||||
|
assert isinstance(foo_field, GraphQLField)
|
||||||
|
assert foo_field.args == {
|
||||||
|
'bar_foo': GraphQLArgument(GraphQLString, out_name='bar_foo')
|
||||||
|
}
|
||||||
|
|
|
@ -41,45 +41,41 @@ def resolve_type(resolve_type_func, map, root, args, info):
|
||||||
class TypeMap(GraphQLTypeMap):
|
class TypeMap(GraphQLTypeMap):
|
||||||
|
|
||||||
def __init__(self, types, auto_camelcase=True):
|
def __init__(self, types, auto_camelcase=True):
|
||||||
if not auto_camelcase:
|
self.auto_camelcase = auto_camelcase
|
||||||
raise Exception("Disabling auto_camelcase is not *yet* supported, but will be soon!")
|
|
||||||
super(TypeMap, self).__init__(types)
|
super(TypeMap, self).__init__(types)
|
||||||
|
|
||||||
@classmethod
|
def reducer(self, map, type):
|
||||||
def reducer(cls, map, type):
|
|
||||||
if not type:
|
if not type:
|
||||||
return map
|
return map
|
||||||
if inspect.isfunction(type):
|
if inspect.isfunction(type):
|
||||||
type = type()
|
type = type()
|
||||||
if is_graphene_type(type):
|
if is_graphene_type(type):
|
||||||
return cls.graphene_reducer(map, type)
|
return self.graphene_reducer(map, type)
|
||||||
return super(TypeMap, cls).reducer(map, type)
|
return GraphQLTypeMap.reducer(map, type)
|
||||||
|
|
||||||
@classmethod
|
def graphene_reducer(self, map, type):
|
||||||
def graphene_reducer(cls, map, type):
|
|
||||||
if isinstance(type, (List, NonNull)):
|
if isinstance(type, (List, NonNull)):
|
||||||
return cls.reducer(map, type.of_type)
|
return self.reducer(map, type.of_type)
|
||||||
if type._meta.name in map:
|
if type._meta.name in map:
|
||||||
_type = map[type._meta.name]
|
_type = map[type._meta.name]
|
||||||
if is_graphene_type(_type):
|
if is_graphene_type(_type):
|
||||||
assert _type.graphene_type == type
|
assert _type.graphene_type == type
|
||||||
return map
|
return map
|
||||||
if issubclass(type, ObjectType):
|
if issubclass(type, ObjectType):
|
||||||
return cls.construct_objecttype(map, type)
|
return self.construct_objecttype(map, type)
|
||||||
if issubclass(type, InputObjectType):
|
if issubclass(type, InputObjectType):
|
||||||
return cls.construct_inputobjecttype(map, type)
|
return self.construct_inputobjecttype(map, type)
|
||||||
if issubclass(type, Interface):
|
if issubclass(type, Interface):
|
||||||
return cls.construct_interface(map, type)
|
return self.construct_interface(map, type)
|
||||||
if issubclass(type, Scalar):
|
if issubclass(type, Scalar):
|
||||||
return cls.construct_scalar(map, type)
|
return self.construct_scalar(map, type)
|
||||||
if issubclass(type, Enum):
|
if issubclass(type, Enum):
|
||||||
return cls.construct_enum(map, type)
|
return self.construct_enum(map, type)
|
||||||
if issubclass(type, Union):
|
if issubclass(type, Union):
|
||||||
return cls.construct_union(map, type)
|
return self.construct_union(map, type)
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_scalar(self, map, type):
|
||||||
def construct_scalar(cls, map, type):
|
|
||||||
from .definitions import GrapheneScalarType
|
from .definitions import GrapheneScalarType
|
||||||
_scalars = {
|
_scalars = {
|
||||||
String: GraphQLString,
|
String: GraphQLString,
|
||||||
|
@ -102,8 +98,7 @@ class TypeMap(GraphQLTypeMap):
|
||||||
)
|
)
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_enum(self, map, type):
|
||||||
def construct_enum(cls, map, type):
|
|
||||||
from .definitions import GrapheneEnumType
|
from .definitions import GrapheneEnumType
|
||||||
values = OrderedDict()
|
values = OrderedDict()
|
||||||
for name, value in type._meta.enum.__members__.items():
|
for name, value in type._meta.enum.__members__.items():
|
||||||
|
@ -121,8 +116,7 @@ class TypeMap(GraphQLTypeMap):
|
||||||
)
|
)
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_objecttype(self, map, type):
|
||||||
def construct_objecttype(cls, map, type):
|
|
||||||
from .definitions import GrapheneObjectType
|
from .definitions import GrapheneObjectType
|
||||||
map[type._meta.name] = GrapheneObjectType(
|
map[type._meta.name] = GrapheneObjectType(
|
||||||
graphene_type=type,
|
graphene_type=type,
|
||||||
|
@ -134,15 +128,14 @@ class TypeMap(GraphQLTypeMap):
|
||||||
)
|
)
|
||||||
interfaces = []
|
interfaces = []
|
||||||
for i in type._meta.interfaces:
|
for i in type._meta.interfaces:
|
||||||
map = cls.reducer(map, i)
|
map = self.reducer(map, i)
|
||||||
interfaces.append(map[i._meta.name])
|
interfaces.append(map[i._meta.name])
|
||||||
map[type._meta.name]._provided_interfaces = interfaces
|
map[type._meta.name]._provided_interfaces = interfaces
|
||||||
map[type._meta.name]._fields = cls.construct_fields_for_type(map, type)
|
map[type._meta.name]._fields = self.construct_fields_for_type(map, type)
|
||||||
# cls.reducer(map, map[type._meta.name])
|
# self.reducer(map, map[type._meta.name])
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_interface(self, map, type):
|
||||||
def construct_interface(cls, map, type):
|
|
||||||
from .definitions import GrapheneInterfaceType
|
from .definitions import GrapheneInterfaceType
|
||||||
_resolve_type = None
|
_resolve_type = None
|
||||||
if type.resolve_type:
|
if type.resolve_type:
|
||||||
|
@ -154,12 +147,11 @@ class TypeMap(GraphQLTypeMap):
|
||||||
fields=None,
|
fields=None,
|
||||||
resolve_type=_resolve_type,
|
resolve_type=_resolve_type,
|
||||||
)
|
)
|
||||||
map[type._meta.name]._fields = cls.construct_fields_for_type(map, type)
|
map[type._meta.name]._fields = self.construct_fields_for_type(map, type)
|
||||||
# cls.reducer(map, map[type._meta.name])
|
# self.reducer(map, map[type._meta.name])
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_inputobjecttype(self, map, type):
|
||||||
def construct_inputobjecttype(cls, map, type):
|
|
||||||
from .definitions import GrapheneInputObjectType
|
from .definitions import GrapheneInputObjectType
|
||||||
map[type._meta.name] = GrapheneInputObjectType(
|
map[type._meta.name] = GrapheneInputObjectType(
|
||||||
graphene_type=type,
|
graphene_type=type,
|
||||||
|
@ -167,18 +159,17 @@ class TypeMap(GraphQLTypeMap):
|
||||||
description=type._meta.description,
|
description=type._meta.description,
|
||||||
fields=None,
|
fields=None,
|
||||||
)
|
)
|
||||||
map[type._meta.name]._fields = cls.construct_fields_for_type(map, type, is_input_type=True)
|
map[type._meta.name]._fields = self.construct_fields_for_type(map, type, is_input_type=True)
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def construct_union(self, map, type):
|
||||||
def construct_union(cls, map, type):
|
|
||||||
from .definitions import GrapheneUnionType
|
from .definitions import GrapheneUnionType
|
||||||
_resolve_type = None
|
_resolve_type = None
|
||||||
if type.resolve_type:
|
if type.resolve_type:
|
||||||
_resolve_type = partial(resolve_type, type.resolve_type, map)
|
_resolve_type = partial(resolve_type, type.resolve_type, map)
|
||||||
types = []
|
types = []
|
||||||
for i in type._meta.types:
|
for i in type._meta.types:
|
||||||
map = cls.construct_objecttype(map, i)
|
map = self.construct_objecttype(map, i)
|
||||||
types.append(map[i._meta.name])
|
types.append(map[i._meta.name])
|
||||||
map[type._meta.name] = GrapheneUnionType(
|
map[type._meta.name] = GrapheneUnionType(
|
||||||
graphene_type=type,
|
graphene_type=type,
|
||||||
|
@ -189,24 +180,23 @@ class TypeMap(GraphQLTypeMap):
|
||||||
map[type._meta.name].types = types
|
map[type._meta.name].types = types
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@classmethod
|
def get_name(self, name):
|
||||||
def process_field_name(cls, name):
|
if self.auto_camelcase:
|
||||||
return to_camel_case(name)
|
return to_camel_case(name)
|
||||||
|
return name
|
||||||
|
|
||||||
@classmethod
|
def default_resolver(self, attname, root, *_):
|
||||||
def default_resolver(cls, attname, root, *_):
|
|
||||||
return getattr(root, attname, None)
|
return getattr(root, attname, None)
|
||||||
|
|
||||||
@classmethod
|
def construct_fields_for_type(self, map, type, is_input_type=False):
|
||||||
def construct_fields_for_type(cls, map, type, is_input_type=False):
|
|
||||||
fields = OrderedDict()
|
fields = OrderedDict()
|
||||||
for name, field in type._meta.fields.items():
|
for name, field in type._meta.fields.items():
|
||||||
if isinstance(field, Dynamic):
|
if isinstance(field, Dynamic):
|
||||||
field = field.get_type()
|
field = field.get_type()
|
||||||
if not field:
|
if not field:
|
||||||
continue
|
continue
|
||||||
map = cls.reducer(map, field.type)
|
map = self.reducer(map, field.type)
|
||||||
field_type = cls.get_field_type(map, field.type)
|
field_type = self.get_field_type(map, field.type)
|
||||||
if is_input_type:
|
if is_input_type:
|
||||||
_field = GraphQLInputObjectField(
|
_field = GraphQLInputObjectField(
|
||||||
field_type,
|
field_type,
|
||||||
|
@ -217,9 +207,9 @@ class TypeMap(GraphQLTypeMap):
|
||||||
else:
|
else:
|
||||||
args = OrderedDict()
|
args = OrderedDict()
|
||||||
for arg_name, arg in field.args.items():
|
for arg_name, arg in field.args.items():
|
||||||
map = cls.reducer(map, arg.type)
|
map = self.reducer(map, arg.type)
|
||||||
arg_type = cls.get_field_type(map, arg.type)
|
arg_type = self.get_field_type(map, arg.type)
|
||||||
processed_arg_name = arg.name or cls.process_field_name(arg_name)
|
processed_arg_name = arg.name or self.get_name(arg_name)
|
||||||
args[processed_arg_name] = GraphQLArgument(
|
args[processed_arg_name] = GraphQLArgument(
|
||||||
arg_type,
|
arg_type,
|
||||||
out_name=arg.name or arg_name,
|
out_name=arg.name or arg_name,
|
||||||
|
@ -229,16 +219,15 @@ class TypeMap(GraphQLTypeMap):
|
||||||
_field = GraphQLField(
|
_field = GraphQLField(
|
||||||
field_type,
|
field_type,
|
||||||
args=args,
|
args=args,
|
||||||
resolver=field.get_resolver(cls.get_resolver_for_type(type, name)),
|
resolver=field.get_resolver(self.get_resolver_for_type(type, name)),
|
||||||
deprecation_reason=field.deprecation_reason,
|
deprecation_reason=field.deprecation_reason,
|
||||||
description=field.description
|
description=field.description
|
||||||
)
|
)
|
||||||
field_name = field.name or cls.process_field_name(name)
|
field_name = field.name or self.get_name(name)
|
||||||
fields[field_name] = _field
|
fields[field_name] = _field
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@classmethod
|
def get_resolver_for_type(self, type, name):
|
||||||
def get_resolver_for_type(cls, type, name):
|
|
||||||
if not issubclass(type, ObjectType):
|
if not issubclass(type, ObjectType):
|
||||||
return
|
return
|
||||||
resolver = getattr(type, 'resolve_{}'.format(name), None)
|
resolver = getattr(type, 'resolve_{}'.format(name), None)
|
||||||
|
@ -259,14 +248,13 @@ class TypeMap(GraphQLTypeMap):
|
||||||
return resolver.__func__
|
return resolver.__func__
|
||||||
return resolver
|
return resolver
|
||||||
|
|
||||||
return partial(cls.default_resolver, name)
|
return partial(self.default_resolver, name)
|
||||||
|
|
||||||
@classmethod
|
def get_field_type(self, map, type):
|
||||||
def get_field_type(cls, map, type):
|
|
||||||
if isinstance(type, List):
|
if isinstance(type, List):
|
||||||
return GraphQLList(cls.get_field_type(map, type.of_type))
|
return GraphQLList(self.get_field_type(map, type.of_type))
|
||||||
if isinstance(type, NonNull):
|
if isinstance(type, NonNull):
|
||||||
return GraphQLNonNull(cls.get_field_type(map, type.of_type))
|
return GraphQLNonNull(self.get_field_type(map, type.of_type))
|
||||||
if inspect.isfunction(type):
|
if inspect.isfunction(type):
|
||||||
type = type()
|
type = type()
|
||||||
return map.get(type._meta.name)
|
return map.get(type._meta.name)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user