mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Refactored arguments and fields logic
This commit is contained in:
		
							parent
							
								
									21dffa4aa8
								
							
						
					
					
						commit
						ec3f292593
					
				| 
						 | 
				
			
			@ -92,7 +92,7 @@ class FieldsClassTypeMeta(ClassTypeMeta):
 | 
			
		|||
 | 
			
		||||
    def extend_fields(cls, bases):
 | 
			
		||||
        new_fields = cls._meta.local_fields
 | 
			
		||||
        field_names = {f.name: f for f in new_fields}
 | 
			
		||||
        field_names = {f.attname: f for f in new_fields}
 | 
			
		||||
 | 
			
		||||
        for base in bases:
 | 
			
		||||
            if not isinstance(base, FieldsClassTypeMeta):
 | 
			
		||||
| 
						 | 
				
			
			@ -100,17 +100,17 @@ class FieldsClassTypeMeta(ClassTypeMeta):
 | 
			
		|||
 | 
			
		||||
            parent_fields = base._meta.local_fields
 | 
			
		||||
            for field in parent_fields:
 | 
			
		||||
                if field.name in field_names and field.type.__class__ != field_names[
 | 
			
		||||
                        field.name].type.__class__:
 | 
			
		||||
                if field.attname in field_names and field.type.__class__ != field_names[
 | 
			
		||||
                        field.attname].type.__class__:
 | 
			
		||||
                    raise Exception(
 | 
			
		||||
                        'Local field %r in class %r (%r) clashes '
 | 
			
		||||
                        'with field with similar name from '
 | 
			
		||||
                        'Interface %s (%r)' % (
 | 
			
		||||
                            field.name,
 | 
			
		||||
                            field.attname,
 | 
			
		||||
                            cls.__name__,
 | 
			
		||||
                            field.__class__,
 | 
			
		||||
                            base.__name__,
 | 
			
		||||
                            field_names[field.name].__class__)
 | 
			
		||||
                            field_names[field.attname].__class__)
 | 
			
		||||
                    )
 | 
			
		||||
                new_field = copy.copy(field)
 | 
			
		||||
                cls.add_to_class(field.attname, new_field)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,10 +34,11 @@ def test_field_type():
 | 
			
		|||
    assert schema.T(f).type == GraphQLString
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_field_name_automatic_camelcase():
 | 
			
		||||
def test_field_name():
 | 
			
		||||
    f = Field(GraphQLString)
 | 
			
		||||
    f.contribute_to_class(MyOt, 'field_name')
 | 
			
		||||
    assert f.name == 'fieldName'
 | 
			
		||||
    assert f.name is None
 | 
			
		||||
    assert f.attname == 'field_name'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_field_name_use_name_if_exists():
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,9 @@
 | 
			
		|||
from collections import OrderedDict
 | 
			
		||||
from functools import wraps
 | 
			
		||||
from itertools import chain
 | 
			
		||||
 | 
			
		||||
from graphql.core.type import GraphQLArgument
 | 
			
		||||
 | 
			
		||||
from ...utils import ProxySnakeDict, to_camel_case
 | 
			
		||||
from ...utils import ProxySnakeDict
 | 
			
		||||
from .base import ArgumentType, GroupNamedType, NamedType, OrderedType
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +13,7 @@ class Argument(NamedType, OrderedType):
 | 
			
		|||
                 name=None, _creation_counter=None):
 | 
			
		||||
        super(Argument, self).__init__(_creation_counter=_creation_counter)
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.attname = None
 | 
			
		||||
        self.type = type
 | 
			
		||||
        self.description = description
 | 
			
		||||
        self.default = default
 | 
			
		||||
| 
						 | 
				
			
			@ -38,20 +38,21 @@ def to_arguments(*args, **kwargs):
 | 
			
		|||
    arguments = {}
 | 
			
		||||
    iter_arguments = chain(kwargs.items(), [(None, a) for a in args])
 | 
			
		||||
 | 
			
		||||
    for name, arg in iter_arguments:
 | 
			
		||||
    for attname, arg in iter_arguments:
 | 
			
		||||
        if isinstance(arg, Argument):
 | 
			
		||||
            argument = arg
 | 
			
		||||
        elif isinstance(arg, ArgumentType):
 | 
			
		||||
            argument = arg.as_argument()
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError('Unknown argument %s=%r' % (name, arg))
 | 
			
		||||
            raise ValueError('Unknown argument %s=%r' % (attname, arg))
 | 
			
		||||
 | 
			
		||||
        if name:
 | 
			
		||||
            argument.name = to_camel_case(name)
 | 
			
		||||
        assert argument.name, 'Argument in field must have a name'
 | 
			
		||||
        assert argument.name not in arguments, 'Found more than one Argument with same name {}'.format(
 | 
			
		||||
            argument.name)
 | 
			
		||||
        arguments[argument.name] = argument
 | 
			
		||||
        if attname:
 | 
			
		||||
            argument.attname = attname
 | 
			
		||||
 | 
			
		||||
        name = argument.name or argument.attname
 | 
			
		||||
        assert name, 'Argument in field must have a name'
 | 
			
		||||
        assert name not in arguments, 'Found more than one Argument with same name {}'.format(name)
 | 
			
		||||
        arguments[name] = argument
 | 
			
		||||
 | 
			
		||||
    return sorted(arguments.values())
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,8 @@ from functools import total_ordering, partial
 | 
			
		|||
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
from ...utils import to_camel_case
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseType(object):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +140,8 @@ class GroupNamedType(BaseType):
 | 
			
		|||
        self.types = types
 | 
			
		||||
 | 
			
		||||
    def get_named_type(self, schema, type):
 | 
			
		||||
        return type.name or type.attname, schema.T(type)
 | 
			
		||||
        name = type.name or to_camel_case(type.attname)
 | 
			
		||||
        return name, schema.T(type)
 | 
			
		||||
 | 
			
		||||
    def internal_type(self, schema):
 | 
			
		||||
        return OrderedDict(map(partial(self.get_named_type, schema), self.types))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@ from functools import wraps
 | 
			
		|||
import six
 | 
			
		||||
from graphql.core.type import GraphQLField, GraphQLInputObjectField
 | 
			
		||||
 | 
			
		||||
from ...utils import to_camel_case
 | 
			
		||||
from ..classtypes.base import FieldsClassType
 | 
			
		||||
from ..classtypes.inputobjecttype import InputObjectType
 | 
			
		||||
from ..classtypes.mutation import Mutation
 | 
			
		||||
| 
						 | 
				
			
			@ -37,8 +36,6 @@ class Field(NamedType, OrderedType):
 | 
			
		|||
        assert issubclass(
 | 
			
		||||
            cls, (FieldsClassType)), 'Field {} cannot be mounted in {}'.format(
 | 
			
		||||
            self, cls)
 | 
			
		||||
        if not self.name:
 | 
			
		||||
            self.name = to_camel_case(attname)
 | 
			
		||||
        self.attname = attname
 | 
			
		||||
        self.object_type = cls
 | 
			
		||||
        self.mount(cls)
 | 
			
		||||
| 
						 | 
				
			
			@ -134,8 +131,6 @@ class InputField(NamedType, OrderedType):
 | 
			
		|||
        assert issubclass(
 | 
			
		||||
            cls, (InputObjectType)), 'InputField {} cannot be mounted in {}'.format(
 | 
			
		||||
            self, cls)
 | 
			
		||||
        if not self.name:
 | 
			
		||||
            self.name = to_camel_case(attname)
 | 
			
		||||
        self.attname = attname
 | 
			
		||||
        self.object_type = cls
 | 
			
		||||
        self.mount(cls)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,8 +27,8 @@ def test_to_arguments():
 | 
			
		|||
        other_kwarg=String(),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    assert [a.name for a in arguments] == [
 | 
			
		||||
        'myArg', 'otherArg', 'myKwarg', 'otherKwarg']
 | 
			
		||||
    assert [a.name or a.attname for a in arguments] == [
 | 
			
		||||
        'myArg', 'otherArg', 'my_kwarg', 'other_kwarg']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_to_arguments_no_name():
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ def test_field_internal_type():
 | 
			
		|||
    schema = Schema(query=Query)
 | 
			
		||||
 | 
			
		||||
    type = schema.T(field)
 | 
			
		||||
    assert field.name == 'myField'
 | 
			
		||||
    assert field.name is None
 | 
			
		||||
    assert field.attname == 'my_field'
 | 
			
		||||
    assert isinstance(type, GraphQLField)
 | 
			
		||||
    assert type.description == 'My argument'
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +116,7 @@ def test_inputfield_internal_type():
 | 
			
		|||
    schema = Schema(query=MyObjectType)
 | 
			
		||||
 | 
			
		||||
    type = schema.T(field)
 | 
			
		||||
    assert field.name == 'myField'
 | 
			
		||||
    assert field.name is None
 | 
			
		||||
    assert field.attname == 'my_field'
 | 
			
		||||
    assert isinstance(type, GraphQLInputObjectField)
 | 
			
		||||
    assert type.description == 'My input field'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user