mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Merge remote-tracking branch 'graphql-python/0.4.0' into use-graphql-django-view
This commit is contained in:
		
						commit
						4e08819094
					
				| 
						 | 
					@ -28,9 +28,9 @@ Here is one example for get you started:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```python
 | 
					```python
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
    hello = graphene.StringField(description='A typical hello world')
 | 
					    hello = graphene.String(description='A typical hello world')
 | 
				
			||||||
    ping = graphene.StringField(description='Ping someone',
 | 
					    ping = graphene.String(description='Ping someone',
 | 
				
			||||||
                                to=graphene.Argument(graphene.String))
 | 
					                           to=graphene.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_hello(self, args, info):
 | 
					    def resolve_hello(self, args, info):
 | 
				
			||||||
        return 'World'
 | 
					        return 'World'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,9 +35,9 @@ Here is one example for get you started:
 | 
				
			||||||
.. code:: python
 | 
					.. code:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Query(graphene.ObjectType):
 | 
					    class Query(graphene.ObjectType):
 | 
				
			||||||
        hello = graphene.StringField(description='A typical hello world')
 | 
					        hello = graphene.String(description='A typical hello world')
 | 
				
			||||||
        ping = graphene.StringField(description='Ping someone',
 | 
					        ping = graphene.String(description='Ping someone',
 | 
				
			||||||
                                    to=graphene.Argument(graphene.String))
 | 
					                               to=graphene.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def resolve_hello(self, args, info):
 | 
					        def resolve_hello(self, args, info):
 | 
				
			||||||
            return 'World'
 | 
					            return 'World'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
autoflake ./ -r --remove-unused-variables --remove-all-unused-imports --in-place
 | 
					autoflake ./ -r --remove-unused-variables --remove-all-unused-imports --in-place
 | 
				
			||||||
 | 
					autopep8 ./ -r --in-place --experimental --aggressive --max-line-length 120
 | 
				
			||||||
isort -rc .
 | 
					isort -rc .
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,10 +12,10 @@ Episode = graphene.Enum('Episode', dict(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(graphene.Interface):
 | 
					class Character(graphene.Interface):
 | 
				
			||||||
    id = graphene.IDField()
 | 
					    id = graphene.ID()
 | 
				
			||||||
    name = graphene.StringField()
 | 
					    name = graphene.String()
 | 
				
			||||||
    friends = graphene.ListField('self')
 | 
					    friends = graphene.List('Character')
 | 
				
			||||||
    appears_in = graphene.ListField(Episode)
 | 
					    appears_in = graphene.List(Episode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_friends(self, args, *_):
 | 
					    def resolve_friends(self, args, *_):
 | 
				
			||||||
        # The character friends is a list of strings
 | 
					        # The character friends is a list of strings
 | 
				
			||||||
| 
						 | 
					@ -23,11 +23,11 @@ class Character(graphene.Interface):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
    home_planet = graphene.StringField()
 | 
					    home_planet = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Droid(Character):
 | 
					class Droid(Character):
 | 
				
			||||||
    primary_function = graphene.StringField()
 | 
					    primary_function = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
| 
						 | 
					@ -35,10 +35,10 @@ class Query(graphene.ObjectType):
 | 
				
			||||||
                          episode=graphene.Argument(Episode)
 | 
					                          episode=graphene.Argument(Episode)
 | 
				
			||||||
                          )
 | 
					                          )
 | 
				
			||||||
    human = graphene.Field(Human,
 | 
					    human = graphene.Field(Human,
 | 
				
			||||||
                           id=graphene.Argument(graphene.String)
 | 
					                           id=graphene.String()
 | 
				
			||||||
                           )
 | 
					                           )
 | 
				
			||||||
    droid = graphene.Field(Droid,
 | 
					    droid = graphene.Field(Droid,
 | 
				
			||||||
                           id=graphene.Argument(graphene.String)
 | 
					                           id=graphene.String()
 | 
				
			||||||
                           )
 | 
					                           )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @resolve_only_args
 | 
					    @resolve_only_args
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ schema = graphene.Schema(name='Starwars Django Relay Schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Ship(DjangoNode):
 | 
					class Ship(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = ShipModel
 | 
					        model = ShipModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,11 +22,13 @@ class Ship(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(DjangoObjectType):
 | 
					class Character(DjangoObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = CharacterModel
 | 
					        model = CharacterModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Faction(DjangoNode):
 | 
					class Faction(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = FactionModel
 | 
					        model = FactionModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,9 +38,10 @@ class Faction(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IntroduceShip(relay.ClientIDMutation):
 | 
					class IntroduceShip(relay.ClientIDMutation):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Input:
 | 
					    class Input:
 | 
				
			||||||
        ship_name = graphene.StringField(required=True)
 | 
					        ship_name = graphene.String(required=True)
 | 
				
			||||||
        faction_id = graphene.StringField(required=True)
 | 
					        faction_id = graphene.String(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ship = graphene.Field(Ship)
 | 
					    ship = graphene.Field(Ship)
 | 
				
			||||||
    faction = graphene.Field(Faction)
 | 
					    faction = graphene.Field(Faction)
 | 
				
			||||||
| 
						 | 
					@ -48,7 +52,7 @@ class IntroduceShip(relay.ClientIDMutation):
 | 
				
			||||||
        faction_id = input.get('faction_id')
 | 
					        faction_id = input.get('faction_id')
 | 
				
			||||||
        ship = create_ship(ship_name, faction_id)
 | 
					        ship = create_ship(ship_name, faction_id)
 | 
				
			||||||
        faction = get_faction(faction_id)
 | 
					        faction = get_faction(faction_id)
 | 
				
			||||||
        return IntroduceShip(ship=ship, faction=faction)
 | 
					        return IntroduceShip(ship=Ship(ship), faction=Faction(faction))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ schema = graphene.Schema(name='Starwars Relay Schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Ship(relay.Node):
 | 
					class Ship(relay.Node):
 | 
				
			||||||
    '''A ship in the Star Wars saga'''
 | 
					    '''A ship in the Star Wars saga'''
 | 
				
			||||||
    name = graphene.StringField(description='The name of the ship.')
 | 
					    name = graphene.String(description='The name of the ship.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_node(cls, id):
 | 
					    def get_node(cls, id):
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ class Ship(relay.Node):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Faction(relay.Node):
 | 
					class Faction(relay.Node):
 | 
				
			||||||
    '''A faction in the Star Wars saga'''
 | 
					    '''A faction in the Star Wars saga'''
 | 
				
			||||||
    name = graphene.StringField(description='The name of the faction.')
 | 
					    name = graphene.String(description='The name of the faction.')
 | 
				
			||||||
    ships = relay.ConnectionField(
 | 
					    ships = relay.ConnectionField(
 | 
				
			||||||
        Ship, description='The ships used by the faction.')
 | 
					        Ship, description='The ships used by the faction.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,8 +34,8 @@ class Faction(relay.Node):
 | 
				
			||||||
class IntroduceShip(relay.ClientIDMutation):
 | 
					class IntroduceShip(relay.ClientIDMutation):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Input:
 | 
					    class Input:
 | 
				
			||||||
        ship_name = graphene.StringField(required=True)
 | 
					        ship_name = graphene.String(required=True)
 | 
				
			||||||
        faction_id = graphene.StringField(required=True)
 | 
					        faction_id = graphene.String(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ship = graphene.Field(Ship)
 | 
					    ship = graphene.Field(Ship)
 | 
				
			||||||
    faction = graphene.Field(Faction)
 | 
					    faction = graphene.Field(Faction)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,5 @@
 | 
				
			||||||
from graphql.core.type import (
 | 
					from graphql.core.type import (
 | 
				
			||||||
    GraphQLEnumType as Enum,
 | 
					    GraphQLEnumType as Enum
 | 
				
			||||||
    GraphQLArgument as Argument,
 | 
					 | 
				
			||||||
    GraphQLString as String,
 | 
					 | 
				
			||||||
    GraphQLInt as Int,
 | 
					 | 
				
			||||||
    GraphQLID as ID
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene import signals
 | 
					from graphene import signals
 | 
				
			||||||
| 
						 | 
					@ -14,12 +10,24 @@ from graphene.core.schema import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.types import (
 | 
					from graphene.core.types import (
 | 
				
			||||||
    ObjectType,
 | 
					    ObjectType,
 | 
				
			||||||
 | 
					    InputObjectType,
 | 
				
			||||||
    Interface,
 | 
					    Interface,
 | 
				
			||||||
    Mutation,
 | 
					    Mutation,
 | 
				
			||||||
 | 
					    BaseType,
 | 
				
			||||||
 | 
					    LazyType,
 | 
				
			||||||
 | 
					    Argument,
 | 
				
			||||||
 | 
					    Field,
 | 
				
			||||||
 | 
					    InputField,
 | 
				
			||||||
 | 
					    String,
 | 
				
			||||||
 | 
					    Int,
 | 
				
			||||||
 | 
					    Boolean,
 | 
				
			||||||
 | 
					    ID,
 | 
				
			||||||
 | 
					    Float,
 | 
				
			||||||
 | 
					    List,
 | 
				
			||||||
 | 
					    NonNull
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.fields import (
 | 
					from graphene.core.fields import (
 | 
				
			||||||
    Field,
 | 
					 | 
				
			||||||
    StringField,
 | 
					    StringField,
 | 
				
			||||||
    IntField,
 | 
					    IntField,
 | 
				
			||||||
    BooleanField,
 | 
					    BooleanField,
 | 
				
			||||||
| 
						 | 
					@ -33,7 +41,31 @@ from graphene.decorators import (
 | 
				
			||||||
    resolve_only_args
 | 
					    resolve_only_args
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['Enum', 'Argument', 'String', 'Int', 'ID', 'signals', 'Schema',
 | 
					__all__ = [
 | 
				
			||||||
           'ObjectType', 'Interface', 'Mutation', 'Field', 'StringField',
 | 
					    'Enum',
 | 
				
			||||||
           'IntField', 'BooleanField', 'IDField', 'ListField', 'NonNullField',
 | 
					    'Argument',
 | 
				
			||||||
           'FloatField', 'resolve_only_args']
 | 
					    'String',
 | 
				
			||||||
 | 
					    'Int',
 | 
				
			||||||
 | 
					    'Boolean',
 | 
				
			||||||
 | 
					    'Float',
 | 
				
			||||||
 | 
					    'ID',
 | 
				
			||||||
 | 
					    'List',
 | 
				
			||||||
 | 
					    'NonNull',
 | 
				
			||||||
 | 
					    'signals',
 | 
				
			||||||
 | 
					    'Schema',
 | 
				
			||||||
 | 
					    'BaseType',
 | 
				
			||||||
 | 
					    'LazyType',
 | 
				
			||||||
 | 
					    'ObjectType',
 | 
				
			||||||
 | 
					    'InputObjectType',
 | 
				
			||||||
 | 
					    'Interface',
 | 
				
			||||||
 | 
					    'Mutation',
 | 
				
			||||||
 | 
					    'Field',
 | 
				
			||||||
 | 
					    'InputField',
 | 
				
			||||||
 | 
					    'StringField',
 | 
				
			||||||
 | 
					    'IntField',
 | 
				
			||||||
 | 
					    'BooleanField',
 | 
				
			||||||
 | 
					    'IDField',
 | 
				
			||||||
 | 
					    'ListField',
 | 
				
			||||||
 | 
					    'NonNullField',
 | 
				
			||||||
 | 
					    'FloatField',
 | 
				
			||||||
 | 
					    'resolve_only_args']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,7 @@ from singledispatch import singledispatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.contrib.django.fields import (ConnectionOrListField,
 | 
					from graphene.contrib.django.fields import (ConnectionOrListField,
 | 
				
			||||||
                                            DjangoModelField)
 | 
					                                            DjangoModelField)
 | 
				
			||||||
from graphene.core.fields import (BooleanField, FloatField, IDField, IntField,
 | 
					from graphene.core.types.scalars import ID, Boolean, Float, Int, String
 | 
				
			||||||
                                  StringField)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    UUIDField = models.UUIDField
 | 
					    UUIDField = models.UUIDField
 | 
				
			||||||
| 
						 | 
					@ -17,7 +16,8 @@ except AttributeError:
 | 
				
			||||||
@singledispatch
 | 
					@singledispatch
 | 
				
			||||||
def convert_django_field(field):
 | 
					def convert_django_field(field):
 | 
				
			||||||
    raise Exception(
 | 
					    raise Exception(
 | 
				
			||||||
        "Don't know how to convert the Django field %s (%s)" % (field, field.__class__))
 | 
					        "Don't know how to convert the Django field %s (%s)" %
 | 
				
			||||||
 | 
					        (field, field.__class__))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.DateField)
 | 
					@convert_django_field.register(models.DateField)
 | 
				
			||||||
| 
						 | 
					@ -28,12 +28,12 @@ def convert_django_field(field):
 | 
				
			||||||
@convert_django_field.register(models.URLField)
 | 
					@convert_django_field.register(models.URLField)
 | 
				
			||||||
@convert_django_field.register(UUIDField)
 | 
					@convert_django_field.register(UUIDField)
 | 
				
			||||||
def convert_field_to_string(field):
 | 
					def convert_field_to_string(field):
 | 
				
			||||||
    return StringField(description=field.help_text)
 | 
					    return String(description=field.help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.AutoField)
 | 
					@convert_django_field.register(models.AutoField)
 | 
				
			||||||
def convert_field_to_id(field):
 | 
					def convert_field_to_id(field):
 | 
				
			||||||
    return IDField(description=field.help_text)
 | 
					    return ID(description=field.help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.PositiveIntegerField)
 | 
					@convert_django_field.register(models.PositiveIntegerField)
 | 
				
			||||||
| 
						 | 
					@ -42,23 +42,23 @@ def convert_field_to_id(field):
 | 
				
			||||||
@convert_django_field.register(models.BigIntegerField)
 | 
					@convert_django_field.register(models.BigIntegerField)
 | 
				
			||||||
@convert_django_field.register(models.IntegerField)
 | 
					@convert_django_field.register(models.IntegerField)
 | 
				
			||||||
def convert_field_to_int(field):
 | 
					def convert_field_to_int(field):
 | 
				
			||||||
    return IntField(description=field.help_text)
 | 
					    return Int(description=field.help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.BooleanField)
 | 
					@convert_django_field.register(models.BooleanField)
 | 
				
			||||||
def convert_field_to_boolean(field):
 | 
					def convert_field_to_boolean(field):
 | 
				
			||||||
    return BooleanField(description=field.help_text, required=True)
 | 
					    return Boolean(description=field.help_text, required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.NullBooleanField)
 | 
					@convert_django_field.register(models.NullBooleanField)
 | 
				
			||||||
def convert_field_to_nullboolean(field):
 | 
					def convert_field_to_nullboolean(field):
 | 
				
			||||||
    return BooleanField(description=field.help_text)
 | 
					    return Boolean(description=field.help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.DecimalField)
 | 
					@convert_django_field.register(models.DecimalField)
 | 
				
			||||||
@convert_django_field.register(models.FloatField)
 | 
					@convert_django_field.register(models.FloatField)
 | 
				
			||||||
def convert_field_to_float(field):
 | 
					def convert_field_to_float(field):
 | 
				
			||||||
    return FloatField(description=field.help_text)
 | 
					    return Float(description=field.help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@convert_django_field.register(models.ManyToManyField)
 | 
					@convert_django_field.register(models.ManyToManyField)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
from graphene import relay
 | 
					from graphene import relay
 | 
				
			||||||
from graphene.contrib.django.utils import get_type_for_model, lazy_map
 | 
					from graphene.contrib.django.utils import get_type_for_model, lazy_map
 | 
				
			||||||
from graphene.core.fields import Field, LazyField, ListField
 | 
					from graphene.core.exceptions import SkipField
 | 
				
			||||||
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
 | 
					from graphene.core.types.base import FieldType
 | 
				
			||||||
 | 
					from graphene.core.types.definitions import List
 | 
				
			||||||
from graphene.relay.utils import is_node
 | 
					from graphene.relay.utils import is_node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,60 +11,54 @@ class DjangoConnectionField(relay.ConnectionField):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def wrap_resolved(self, value, instance, args, info):
 | 
					    def wrap_resolved(self, value, instance, args, info):
 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					        schema = info.schema.graphene_schema
 | 
				
			||||||
        return lazy_map(value, self.get_object_type(schema))
 | 
					        return lazy_map(value, self.type.get_object_type(schema))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LazyListField(ListField):
 | 
					class LazyListField(Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					    def get_type(self, schema):
 | 
				
			||||||
 | 
					        return List(self.type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					        schema = info.schema.graphene_schema
 | 
				
			||||||
        resolved = super(LazyListField, self).resolve(instance, args, info)
 | 
					        resolved = super(LazyListField, self).resolver(instance, args, info)
 | 
				
			||||||
        return lazy_map(resolved, self.get_object_type(schema))
 | 
					        return lazy_map(resolved, self.get_object_type(schema))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionOrListField(LazyField):
 | 
					class ConnectionOrListField(Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_field(self, schema):
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
        model_field = self.field_type
 | 
					        model_field = self.type
 | 
				
			||||||
        field_object_type = model_field.get_object_type(schema)
 | 
					        field_object_type = model_field.get_object_type(schema)
 | 
				
			||||||
        if is_node(field_object_type):
 | 
					        if is_node(field_object_type):
 | 
				
			||||||
            field = DjangoConnectionField(model_field)
 | 
					            field = DjangoConnectionField(model_field)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            field = LazyListField(model_field)
 | 
					            field = LazyListField(model_field)
 | 
				
			||||||
        field.contribute_to_class(self.object_type, self.name)
 | 
					        field.contribute_to_class(self.object_type, self.name)
 | 
				
			||||||
        return field
 | 
					        return field.internal_type(schema)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoModelField(Field):
 | 
					class DjangoModelField(FieldType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, model, *args, **kwargs):
 | 
					    def __init__(self, model, *args, **kwargs):
 | 
				
			||||||
        super(DjangoModelField, self).__init__(None, *args, **kwargs)
 | 
					 | 
				
			||||||
        self.model = model
 | 
					        self.model = model
 | 
				
			||||||
 | 
					        super(DjangoModelField, self).__init__(*args, **kwargs)
 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					 | 
				
			||||||
        resolved = super(DjangoModelField, self).resolve(instance, args, info)
 | 
					 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					 | 
				
			||||||
        _type = self.get_object_type(schema)
 | 
					 | 
				
			||||||
        assert _type, ("Field %s cannot be retrieved as the "
 | 
					 | 
				
			||||||
                       "ObjectType is not registered by the schema" % (
 | 
					 | 
				
			||||||
                           self.attname
 | 
					 | 
				
			||||||
                       ))
 | 
					 | 
				
			||||||
        return _type(resolved)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def internal_type(self, schema):
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
        _type = self.get_object_type(schema)
 | 
					        _type = self.get_object_type(schema)
 | 
				
			||||||
        if not _type and self.object_type._meta.only_fields:
 | 
					        if not _type and self.parent._meta.only_fields:
 | 
				
			||||||
            raise Exception(
 | 
					            raise Exception(
 | 
				
			||||||
                "Model %r is not accessible by the schema. "
 | 
					                "Model %r is not accessible by the schema. "
 | 
				
			||||||
                "You can either register the type manually "
 | 
					                "You can either register the type manually "
 | 
				
			||||||
                "using @schema.register. "
 | 
					                "using @schema.register. "
 | 
				
			||||||
                "Or disable the field %s in %s" % (
 | 
					                "Or disable the field in %s" % (
 | 
				
			||||||
                    self.model,
 | 
					                    self.model,
 | 
				
			||||||
                    self.attname,
 | 
					                    self.parent,
 | 
				
			||||||
                    self.object_type
 | 
					 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        return schema.T(_type) or Field.SKIP
 | 
					        if not _type:
 | 
				
			||||||
 | 
					            raise SkipField()
 | 
				
			||||||
 | 
					        return schema.T(_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_object_type(self, schema):
 | 
					    def get_object_type(self, schema):
 | 
				
			||||||
        return get_type_for_model(schema, self.model)
 | 
					        return get_type_for_model(schema, self.model)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ class DjangoOptions(Options):
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        if not self.model:
 | 
					        if not self.model:
 | 
				
			||||||
            raise Exception(
 | 
					            raise Exception(
 | 
				
			||||||
                'Django ObjectType %s must have a model in the Meta class attr' % cls)
 | 
					                'Django ObjectType %s must have a model in the Meta class attr' %
 | 
				
			||||||
 | 
					                cls)
 | 
				
			||||||
        elif not inspect.isclass(self.model) or not issubclass(self.model, models.Model):
 | 
					        elif not inspect.isclass(self.model) or not issubclass(self.model, models.Model):
 | 
				
			||||||
            raise Exception('Provided model in %s is not a Django model' % cls)
 | 
					            raise Exception('Provided model in %s is not a Django model' % cls)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from py.test import raises
 | 
					from py.test import raises
 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import graphene
 | 
					import graphene
 | 
				
			||||||
from graphene.contrib.django.converter import convert_django_field
 | 
					from graphene.contrib.django.converter import convert_django_field
 | 
				
			||||||
| 
						 | 
					@ -15,8 +14,9 @@ def assert_conversion(django_field, graphene_field, *args):
 | 
				
			||||||
    field = django_field(*args, help_text='Custom Help Text')
 | 
					    field = django_field(*args, help_text='Custom Help Text')
 | 
				
			||||||
    graphene_type = convert_django_field(field)
 | 
					    graphene_type = convert_django_field(field)
 | 
				
			||||||
    assert isinstance(graphene_type, graphene_field)
 | 
					    assert isinstance(graphene_type, graphene_field)
 | 
				
			||||||
    assert graphene_type.description == 'Custom Help Text'
 | 
					    field = graphene_type.as_field()
 | 
				
			||||||
    return graphene_type
 | 
					    assert field.description == 'Custom Help Text'
 | 
				
			||||||
 | 
					    return field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_unknown_django_field_raise_exception():
 | 
					def test_should_unknown_django_field_raise_exception():
 | 
				
			||||||
| 
						 | 
					@ -26,86 +26,86 @@ def test_should_unknown_django_field_raise_exception():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_date_convert_string():
 | 
					def test_should_date_convert_string():
 | 
				
			||||||
    assert_conversion(models.DateField, graphene.StringField)
 | 
					    assert_conversion(models.DateField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_char_convert_string():
 | 
					def test_should_char_convert_string():
 | 
				
			||||||
    assert_conversion(models.CharField, graphene.StringField)
 | 
					    assert_conversion(models.CharField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_text_convert_string():
 | 
					def test_should_text_convert_string():
 | 
				
			||||||
    assert_conversion(models.TextField, graphene.StringField)
 | 
					    assert_conversion(models.TextField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_email_convert_string():
 | 
					def test_should_email_convert_string():
 | 
				
			||||||
    assert_conversion(models.EmailField, graphene.StringField)
 | 
					    assert_conversion(models.EmailField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_slug_convert_string():
 | 
					def test_should_slug_convert_string():
 | 
				
			||||||
    assert_conversion(models.SlugField, graphene.StringField)
 | 
					    assert_conversion(models.SlugField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_url_convert_string():
 | 
					def test_should_url_convert_string():
 | 
				
			||||||
    assert_conversion(models.URLField, graphene.StringField)
 | 
					    assert_conversion(models.URLField, graphene.String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_auto_convert_id():
 | 
					def test_should_auto_convert_id():
 | 
				
			||||||
    assert_conversion(models.AutoField, graphene.IDField)
 | 
					    assert_conversion(models.AutoField, graphene.ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_positive_integer_convert_int():
 | 
					def test_should_positive_integer_convert_int():
 | 
				
			||||||
    assert_conversion(models.PositiveIntegerField, graphene.IntField)
 | 
					    assert_conversion(models.PositiveIntegerField, graphene.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_positive_small_convert_int():
 | 
					def test_should_positive_small_convert_int():
 | 
				
			||||||
    assert_conversion(models.PositiveSmallIntegerField, graphene.IntField)
 | 
					    assert_conversion(models.PositiveSmallIntegerField, graphene.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_small_integer_convert_int():
 | 
					def test_should_small_integer_convert_int():
 | 
				
			||||||
    assert_conversion(models.SmallIntegerField, graphene.IntField)
 | 
					    assert_conversion(models.SmallIntegerField, graphene.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_big_integer_convert_int():
 | 
					def test_should_big_integer_convert_int():
 | 
				
			||||||
    assert_conversion(models.BigIntegerField, graphene.IntField)
 | 
					    assert_conversion(models.BigIntegerField, graphene.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_integer_convert_int():
 | 
					def test_should_integer_convert_int():
 | 
				
			||||||
    assert_conversion(models.IntegerField, graphene.IntField)
 | 
					    assert_conversion(models.IntegerField, graphene.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_boolean_convert_boolean():
 | 
					def test_should_boolean_convert_boolean():
 | 
				
			||||||
    field = assert_conversion(models.BooleanField, graphene.BooleanField)
 | 
					    field = assert_conversion(models.BooleanField, graphene.Boolean)
 | 
				
			||||||
    assert field.required is True
 | 
					    assert field.required is True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_nullboolean_convert_boolean():
 | 
					def test_should_nullboolean_convert_boolean():
 | 
				
			||||||
    field = assert_conversion(models.NullBooleanField, graphene.BooleanField)
 | 
					    field = assert_conversion(models.NullBooleanField, graphene.Boolean)
 | 
				
			||||||
    assert field.required is False
 | 
					    assert field.required is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_float_convert_float():
 | 
					def test_should_float_convert_float():
 | 
				
			||||||
    assert_conversion(models.FloatField, graphene.FloatField)
 | 
					    assert_conversion(models.FloatField, graphene.Float)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_manytomany_convert_connectionorlist():
 | 
					def test_should_manytomany_convert_connectionorlist():
 | 
				
			||||||
    graphene_type = convert_django_field(Reporter._meta.local_many_to_many[0])
 | 
					    graphene_type = convert_django_field(Reporter._meta.local_many_to_many[0])
 | 
				
			||||||
    assert isinstance(graphene_type, ConnectionOrListField)
 | 
					    assert isinstance(graphene_type, ConnectionOrListField)
 | 
				
			||||||
    assert isinstance(graphene_type.field_type, DjangoModelField)
 | 
					    assert isinstance(graphene_type.type, DjangoModelField)
 | 
				
			||||||
    assert graphene_type.field_type.model == Reporter
 | 
					    assert graphene_type.type.model == Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_manytoone_convert_connectionorlist():
 | 
					def test_should_manytoone_convert_connectionorlist():
 | 
				
			||||||
    graphene_type = convert_django_field(Reporter.articles.related)
 | 
					    graphene_type = convert_django_field(Reporter.articles.related)
 | 
				
			||||||
    assert isinstance(graphene_type, ConnectionOrListField)
 | 
					    assert isinstance(graphene_type, ConnectionOrListField)
 | 
				
			||||||
    assert isinstance(graphene_type.field_type, DjangoModelField)
 | 
					    assert isinstance(graphene_type.type, DjangoModelField)
 | 
				
			||||||
    assert graphene_type.field_type.model == Article
 | 
					    assert graphene_type.type.model == Article
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_onetoone_convert_model():
 | 
					def test_should_onetoone_convert_model():
 | 
				
			||||||
    field = assert_conversion(models.OneToOneField, DjangoModelField, Article)
 | 
					    field = assert_conversion(models.OneToOneField, DjangoModelField, Article)
 | 
				
			||||||
    assert field.model == Article
 | 
					    assert field.type.model == Article
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_foreignkey_convert_model():
 | 
					def test_should_foreignkey_convert_model():
 | 
				
			||||||
    field = assert_conversion(models.ForeignKey, DjangoModelField, Article)
 | 
					    field = assert_conversion(models.ForeignKey, DjangoModelField, Article)
 | 
				
			||||||
    assert field.model == Article
 | 
					    assert field.type.model == Article
 | 
				
			||||||
| 
						 | 
					@ -1,40 +1,21 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
from py.test import raises
 | 
					from py.test import raises
 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import graphene
 | 
					import graphene
 | 
				
			||||||
from graphene import relay
 | 
					from graphene import relay
 | 
				
			||||||
from graphene.contrib.django import DjangoNode, DjangoObjectType
 | 
					from graphene.contrib.django import DjangoNode, DjangoObjectType
 | 
				
			||||||
from tests.utils import assert_equal_lists
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Article, Reporter
 | 
					from .models import Article, Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_raise_if_no_model():
 | 
					def test_should_query_only_fields():
 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					    with raises(Exception):
 | 
				
			||||||
        class Character1(DjangoObjectType):
 | 
					        class ReporterType(DjangoObjectType):
 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
    assert 'model in the Meta' in str(excinfo.value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_should_raise_if_model_is_invalid():
 | 
					 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					 | 
				
			||||||
        class Character2(DjangoObjectType):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            class Meta:
 | 
					 | 
				
			||||||
                model = 1
 | 
					 | 
				
			||||||
    assert 'not a Django model' in str(excinfo.value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_should_raise_if_model_is_invalid():
 | 
					 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					 | 
				
			||||||
        class ReporterTypeError(DjangoObjectType):
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            class Meta:
 | 
					            class Meta:
 | 
				
			||||||
                model = Reporter
 | 
					                model = Reporter
 | 
				
			||||||
                only_fields = ('articles', )
 | 
					                only_fields = ('articles', )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        schema = graphene.Schema(query=ReporterTypeError)
 | 
					        schema = graphene.Schema(query=ReporterType)
 | 
				
			||||||
        query = '''
 | 
					        query = '''
 | 
				
			||||||
            query ReporterQuery {
 | 
					            query ReporterQuery {
 | 
				
			||||||
              articles
 | 
					              articles
 | 
				
			||||||
| 
						 | 
					@ -44,24 +25,13 @@ def test_should_raise_if_model_is_invalid():
 | 
				
			||||||
        assert not result.errors
 | 
					        assert not result.errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_map_fields_correctly():
 | 
					def test_should_query_well():
 | 
				
			||||||
    class ReporterType2(DjangoObjectType):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class Meta:
 | 
					 | 
				
			||||||
            model = Reporter
 | 
					 | 
				
			||||||
    assert_equal_lists(
 | 
					 | 
				
			||||||
        ReporterType2._meta.fields_map.keys(),
 | 
					 | 
				
			||||||
        ['articles', 'first_name', 'last_name', 'email', 'pets', 'id']
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_should_map_fields():
 | 
					 | 
				
			||||||
    class ReporterType(DjangoObjectType):
 | 
					    class ReporterType(DjangoObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class Meta:
 | 
					        class Meta:
 | 
				
			||||||
            model = Reporter
 | 
					            model = Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Query2(graphene.ObjectType):
 | 
					    class Query(graphene.ObjectType):
 | 
				
			||||||
        reporter = graphene.Field(ReporterType)
 | 
					        reporter = graphene.Field(ReporterType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def resolve_reporter(self, *args, **kwargs):
 | 
					        def resolve_reporter(self, *args, **kwargs):
 | 
				
			||||||
| 
						 | 
					@ -83,53 +53,42 @@ def test_should_map_fields():
 | 
				
			||||||
            'email': ''
 | 
					            'email': ''
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Schema = graphene.Schema(query=Query2)
 | 
					    schema = graphene.Schema(query=Query)
 | 
				
			||||||
    result = Schema.execute(query)
 | 
					    result = schema.execute(query)
 | 
				
			||||||
    assert not result.errors
 | 
					    assert not result.errors
 | 
				
			||||||
    assert result.data == expected
 | 
					    assert result.data == expected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_should_map_only_few_fields():
 | 
					 | 
				
			||||||
    class Reporter2(DjangoObjectType):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class Meta:
 | 
					 | 
				
			||||||
            model = Reporter
 | 
					 | 
				
			||||||
            only_fields = ('id', 'email')
 | 
					 | 
				
			||||||
    assert_equal_lists(
 | 
					 | 
				
			||||||
        Reporter2._meta.fields_map.keys(),
 | 
					 | 
				
			||||||
        ['id', 'email']
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_should_node():
 | 
					def test_should_node():
 | 
				
			||||||
    class ReporterNodeType(DjangoNode):
 | 
					    class ReporterNode(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class Meta:
 | 
					        class Meta:
 | 
				
			||||||
            model = Reporter
 | 
					            model = Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @classmethod
 | 
					        @classmethod
 | 
				
			||||||
        def get_node(cls, id):
 | 
					        def get_node(cls, id):
 | 
				
			||||||
            return ReporterNodeType(Reporter(id=2, first_name='Cookie Monster'))
 | 
					            return ReporterNode(Reporter(id=2, first_name='Cookie Monster'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def resolve_articles(self, *args, **kwargs):
 | 
					        def resolve_articles(self, *args, **kwargs):
 | 
				
			||||||
            return [ArticleNodeType(Article(headline='Hi!'))]
 | 
					            return [ArticleNode(Article(headline='Hi!'))]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class ArticleNodeType(DjangoNode):
 | 
					    class ArticleNode(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class Meta:
 | 
					        class Meta:
 | 
				
			||||||
            model = Article
 | 
					            model = Article
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @classmethod
 | 
					        @classmethod
 | 
				
			||||||
        def get_node(cls, id):
 | 
					        def get_node(cls, id):
 | 
				
			||||||
            return ArticleNodeType(Article(id=1, headline='Article node'))
 | 
					            return ArticleNode(Article(id=1, headline='Article node'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Query1(graphene.ObjectType):
 | 
					    class Query(graphene.ObjectType):
 | 
				
			||||||
        node = relay.NodeField()
 | 
					        node = relay.NodeField()
 | 
				
			||||||
        reporter = graphene.Field(ReporterNodeType)
 | 
					        reporter = graphene.Field(ReporterNode)
 | 
				
			||||||
        article = graphene.Field(ArticleNodeType)
 | 
					        article = graphene.Field(ArticleNode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def resolve_reporter(self, *args, **kwargs):
 | 
					        def resolve_reporter(self, *args, **kwargs):
 | 
				
			||||||
            return ReporterNodeType(Reporter(id=1, first_name='ABA', last_name='X'))
 | 
					            return ReporterNode(
 | 
				
			||||||
 | 
					                Reporter(id=1, first_name='ABA', last_name='X'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    query = '''
 | 
					    query = '''
 | 
				
			||||||
        query ReporterQuery {
 | 
					        query ReporterQuery {
 | 
				
			||||||
| 
						 | 
					@ -146,12 +105,12 @@ def test_should_node():
 | 
				
			||||||
            lastName,
 | 
					            lastName,
 | 
				
			||||||
            email
 | 
					            email
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          myArticle: node(id:"QXJ0aWNsZU5vZGVUeXBlOjE=") {
 | 
					          myArticle: node(id:"QXJ0aWNsZU5vZGU6MQ==") {
 | 
				
			||||||
            id
 | 
					            id
 | 
				
			||||||
            ... on ReporterNodeType {
 | 
					            ... on ReporterNode {
 | 
				
			||||||
                firstName
 | 
					                firstName
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ... on ArticleNodeType {
 | 
					            ... on ArticleNode {
 | 
				
			||||||
                headline
 | 
					                headline
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
| 
						 | 
					@ -159,7 +118,7 @@ def test_should_node():
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    expected = {
 | 
					    expected = {
 | 
				
			||||||
        'reporter': {
 | 
					        'reporter': {
 | 
				
			||||||
            'id': 'UmVwb3J0ZXJOb2RlVHlwZTox',
 | 
					            'id': 'UmVwb3J0ZXJOb2RlOjE=',
 | 
				
			||||||
            'firstName': 'ABA',
 | 
					            'firstName': 'ABA',
 | 
				
			||||||
            'lastName': 'X',
 | 
					            'lastName': 'X',
 | 
				
			||||||
            'email': '',
 | 
					            'email': '',
 | 
				
			||||||
| 
						 | 
					@ -172,11 +131,11 @@ def test_should_node():
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        'myArticle': {
 | 
					        'myArticle': {
 | 
				
			||||||
            'id': 'QXJ0aWNsZU5vZGVUeXBlOjE=',
 | 
					            'id': 'QXJ0aWNsZU5vZGU6MQ==',
 | 
				
			||||||
            'headline': 'Article node'
 | 
					            'headline': 'Article node'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Schema = graphene.Schema(query=Query1)
 | 
					    schema = graphene.Schema(query=Query)
 | 
				
			||||||
    result = Schema.execute(query)
 | 
					    result = schema.execute(query)
 | 
				
			||||||
    assert not result.errors
 | 
					    assert not result.errors
 | 
				
			||||||
    assert result.data == expected
 | 
					    assert result.data == expected
 | 
				
			||||||
							
								
								
									
										45
									
								
								graphene/contrib/django/tests/test_schema.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								graphene/contrib/django/tests/test_schema.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					from py.test import raises
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphene.contrib.django import DjangoObjectType
 | 
				
			||||||
 | 
					from tests.utils import assert_equal_lists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .models import Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_should_raise_if_no_model():
 | 
				
			||||||
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
 | 
					        class Character1(DjangoObjectType):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    assert 'model in the Meta' in str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_should_raise_if_model_is_invalid():
 | 
				
			||||||
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
 | 
					        class Character2(DjangoObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = 1
 | 
				
			||||||
 | 
					    assert 'not a Django model' in str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_should_map_fields_correctly():
 | 
				
			||||||
 | 
					    class ReporterType2(DjangoObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Meta:
 | 
				
			||||||
 | 
					            model = Reporter
 | 
				
			||||||
 | 
					    assert_equal_lists(
 | 
				
			||||||
 | 
					        ReporterType2._meta.fields_map.keys(),
 | 
				
			||||||
 | 
					        ['articles', 'first_name', 'last_name', 'email', 'pets', 'id']
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_should_map_only_few_fields():
 | 
				
			||||||
 | 
					    class Reporter2(DjangoObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Meta:
 | 
				
			||||||
 | 
					            model = Reporter
 | 
				
			||||||
 | 
					            only_fields = ('id', 'email')
 | 
				
			||||||
 | 
					    assert_equal_lists(
 | 
				
			||||||
 | 
					        Reporter2._meta.fields_map.keys(),
 | 
				
			||||||
 | 
					        ['id', 'email']
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
| 
						 | 
					@ -2,13 +2,16 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene import Schema
 | 
					from graphene import Schema
 | 
				
			||||||
from graphene.contrib.django.types import DjangoInterface, DjangoNode
 | 
					from graphene.contrib.django.types import DjangoInterface, DjangoNode
 | 
				
			||||||
from graphene.core.fields import IntField
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
 | 
					from graphene.core.types.scalars import Int
 | 
				
			||||||
from graphene.relay.fields import GlobalIDField
 | 
					from graphene.relay.fields import GlobalIDField
 | 
				
			||||||
from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
 | 
					from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
 | 
				
			||||||
from tests.utils import assert_equal_lists
 | 
					from tests.utils import assert_equal_lists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Article, Reporter
 | 
					from .models import Article, Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(DjangoInterface):
 | 
					class Character(DjangoInterface):
 | 
				
			||||||
    '''Character description'''
 | 
					    '''Character description'''
 | 
				
			||||||
| 
						 | 
					@ -16,10 +19,11 @@ class Character(DjangoInterface):
 | 
				
			||||||
        model = Reporter
 | 
					        model = Reporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@schema.register
 | 
				
			||||||
class Human(DjangoNode):
 | 
					class Human(DjangoNode):
 | 
				
			||||||
    '''Human description'''
 | 
					    '''Human description'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub_date = IntField()
 | 
					    pub_date = Int()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_node(self, id):
 | 
					    def get_node(self, id):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
| 
						 | 
					@ -27,14 +31,12 @@ class Human(DjangoNode):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Article
 | 
					        model = Article
 | 
				
			||||||
 | 
					
 | 
				
			||||||
schema = Schema()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_django_interface():
 | 
					def test_django_interface():
 | 
				
			||||||
    assert DjangoNode._meta.is_interface is True
 | 
					    assert DjangoNode._meta.is_interface is True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_pseudo_interface():
 | 
					def test_pseudo_interface_registered():
 | 
				
			||||||
    object_type = schema.T(Character)
 | 
					    object_type = schema.T(Character)
 | 
				
			||||||
    assert Character._meta.is_interface is True
 | 
					    assert Character._meta.is_interface is True
 | 
				
			||||||
    assert isinstance(object_type, GraphQLInterfaceType)
 | 
					    assert isinstance(object_type, GraphQLInterfaceType)
 | 
				
			||||||
| 
						 | 
					@ -57,7 +59,8 @@ def test_node_idfield():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_node_replacedfield():
 | 
					def test_node_replacedfield():
 | 
				
			||||||
    idfield = Human._meta.fields_map['pub_date']
 | 
					    idfield = Human._meta.fields_map['pub_date']
 | 
				
			||||||
    assert isinstance(idfield, IntField)
 | 
					    assert isinstance(idfield, Field)
 | 
				
			||||||
 | 
					    assert schema.T(idfield).type == schema.T(Int())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_interface_resolve_type():
 | 
					def test_interface_resolve_type():
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ class Character(DjangoNode):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(DjangoNode):
 | 
					class Human(DjangoNode):
 | 
				
			||||||
    raises = graphene.StringField()
 | 
					    raises = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Article
 | 
					        model = Article
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ def format_response(response):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_get_no_query(settings, client):
 | 
					def test_client_get_no_query(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.get('/graphql')
 | 
					    response = client.get('/graphql')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
    assert json_response == {'errors': [
 | 
					    assert json_response == {'errors': [
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ def test_client_get_no_query(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_no_query(settings, client):
 | 
					def test_client_post_no_query(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post('/graphql', {})
 | 
					    response = client.post('/graphql', {})
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
    assert json_response == {'errors': [
 | 
					    assert json_response == {'errors': [
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ def test_client_post_no_query(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_malformed_json(settings, client):
 | 
					def test_client_post_malformed_json(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post('/graphql', 'MALFORMED', 'application/json')
 | 
					    response = client.post('/graphql', 'MALFORMED', 'application/json')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
    assert json_response == {'errors': [
 | 
					    assert json_response == {'errors': [
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ def test_client_post_malformed_json(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_empty_query_json(settings, client):
 | 
					def test_client_post_empty_query_json(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', json.dumps({'query': ''}), 'application/json')
 | 
					        '/graphql', json.dumps({'query': ''}), 'application/json')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ def test_client_post_empty_query_json(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_empty_query_graphql(settings, client):
 | 
					def test_client_post_empty_query_graphql(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', '', 'application/graphql')
 | 
					        '/graphql', '', 'application/graphql')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ def test_client_post_empty_query_graphql(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_bad_query_json(settings, client):
 | 
					def test_client_post_bad_query_json(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json')
 | 
					        '/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ def test_client_post_bad_query_json(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_bad_query_graphql(settings, client):
 | 
					def test_client_post_bad_query_graphql(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', '{ MALFORMED', 'application/graphql')
 | 
					        '/graphql', '{ MALFORMED', 'application/graphql')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ def test_client_post_bad_query_graphql(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_get_good_query(settings, client):
 | 
					def test_client_get_good_query(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.get('/graphql', {'query': '{ headline }'})
 | 
					    response = client.get('/graphql', {'query': '{ headline }'})
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
    expected_json = {
 | 
					    expected_json = {
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ def test_client_get_good_query(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_get_good_query_with_raise(settings, client):
 | 
					def test_client_get_good_query_with_raise(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.get('/graphql', {'query': '{ raises }'})
 | 
					    response = client.get('/graphql', {'query': '{ raises }'})
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
    assert json_response['errors'][0][
 | 
					    assert json_response['errors'][0][
 | 
				
			||||||
| 
						 | 
					@ -89,7 +89,7 @@ def test_client_get_good_query_with_raise(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_good_query_json(settings, client):
 | 
					def test_client_post_good_query_json(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', json.dumps({'query': '{ headline }'}), 'application/json')
 | 
					        '/graphql', json.dumps({'query': '{ headline }'}), 'application/json')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ def test_client_post_good_query_json(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_client_post_good_query_graphql(settings, client):
 | 
					def test_client_post_good_query_graphql(settings, client):
 | 
				
			||||||
    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					    settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
    response = client.post(
 | 
					    response = client.post(
 | 
				
			||||||
        '/graphql', '{ headline }', 'application/graphql')
 | 
					        '/graphql', '{ headline }', 'application/graphql')
 | 
				
			||||||
    json_response = format_response(response)
 | 
					    json_response = format_response(response)
 | 
				
			||||||
| 
						 | 
					@ -115,7 +115,7 @@ def test_client_post_good_query_graphql(settings, client):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# def test_client_get_bad_query(settings, client):
 | 
					# def test_client_get_bad_query(settings, client):
 | 
				
			||||||
#     settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
 | 
					#     settings.ROOT_URLCONF = 'graphene.contrib.django.tests.test_urls'
 | 
				
			||||||
#     response = client.get('/graphql')
 | 
					#     response = client.get('/graphql')
 | 
				
			||||||
#     json_response = format_response(response)
 | 
					#     json_response = format_response(response)
 | 
				
			||||||
#     assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
 | 
					#     assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
 | 
				
			||||||
| 
						 | 
					@ -46,11 +46,13 @@ class InstanceObjectType(BaseObjectType):
 | 
				
			||||||
        return getattr(self.instance, attr)
 | 
					        return getattr(self.instance, attr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoObjectType(six.with_metaclass(DjangoObjectTypeMeta, InstanceObjectType)):
 | 
					class DjangoObjectType(six.with_metaclass(
 | 
				
			||||||
 | 
					        DjangoObjectTypeMeta, InstanceObjectType)):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoInterface(six.with_metaclass(DjangoObjectTypeMeta, InstanceObjectType)):
 | 
					class DjangoInterface(six.with_metaclass(
 | 
				
			||||||
 | 
					        DjangoObjectTypeMeta, InstanceObjectType)):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								graphene/core/exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								graphene/core/exceptions.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					class SkipField(Exception):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
| 
						 | 
					@ -1,258 +1,49 @@
 | 
				
			||||||
import inspect
 | 
					import warnings
 | 
				
			||||||
from functools import total_ordering, wraps
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					from .types.base import FieldType
 | 
				
			||||||
 | 
					from .types.definitions import List, NonNull
 | 
				
			||||||
from graphene.core.scalars import GraphQLSkipField
 | 
					from .types.field import Field
 | 
				
			||||||
from graphene.core.types import BaseObjectType, InputObjectType
 | 
					from .types.scalars import ID, Boolean, Float, Int, String
 | 
				
			||||||
from graphene.utils import ProxySnakeDict, enum_to_graphql_enum, to_camel_case
 | 
					 | 
				
			||||||
from graphql.core.type import (GraphQLArgument, GraphQLBoolean, GraphQLField,
 | 
					 | 
				
			||||||
                               GraphQLFloat, GraphQLID,
 | 
					 | 
				
			||||||
                               GraphQLInputObjectField, GraphQLInt,
 | 
					 | 
				
			||||||
                               GraphQLList, GraphQLNonNull, GraphQLString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    from enum import Enum
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    class Enum(object):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Empty(object):
 | 
					class DeprecatedField(FieldType):
 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@total_ordering
 | 
					 | 
				
			||||||
class Field(object):
 | 
					 | 
				
			||||||
    SKIP = GraphQLSkipField
 | 
					 | 
				
			||||||
    creation_counter = 0
 | 
					 | 
				
			||||||
    required = False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, field_type, name=None, resolve=None, required=False, args=None, description='', default=None, **extra_args):
 | 
					 | 
				
			||||||
        self.field_type = field_type
 | 
					 | 
				
			||||||
        self.resolve_fn = resolve
 | 
					 | 
				
			||||||
        self.required = self.required or required
 | 
					 | 
				
			||||||
        self.args = args or {}
 | 
					 | 
				
			||||||
        self.extra_args = extra_args
 | 
					 | 
				
			||||||
        self._type = None
 | 
					 | 
				
			||||||
        self.name = name
 | 
					 | 
				
			||||||
        self.description = description or self.__doc__
 | 
					 | 
				
			||||||
        self.object_type = None
 | 
					 | 
				
			||||||
        self.default = default
 | 
					 | 
				
			||||||
        self.creation_counter = Field.creation_counter
 | 
					 | 
				
			||||||
        Field.creation_counter += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_default(self):
 | 
					 | 
				
			||||||
        return self.default
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def contribute_to_class(self, cls, name, add=True):
 | 
					 | 
				
			||||||
        if not self.name:
 | 
					 | 
				
			||||||
            self.name = to_camel_case(name)
 | 
					 | 
				
			||||||
        self.attname = name
 | 
					 | 
				
			||||||
        self.object_type = cls
 | 
					 | 
				
			||||||
        if isinstance(self.field_type, Field) and not self.field_type.object_type:
 | 
					 | 
				
			||||||
            self.field_type.contribute_to_class(cls, name, False)
 | 
					 | 
				
			||||||
        if add:
 | 
					 | 
				
			||||||
            cls._meta.add_field(self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					 | 
				
			||||||
        schema = info and getattr(info.schema, 'graphene_schema', None)
 | 
					 | 
				
			||||||
        resolve_fn = self.get_resolve_fn(schema)
 | 
					 | 
				
			||||||
        if resolve_fn:
 | 
					 | 
				
			||||||
            return resolve_fn(instance, ProxySnakeDict(args), info)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            return getattr(instance, self.attname, self.get_default())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_resolve_fn(self, schema):
 | 
					 | 
				
			||||||
        object_type = self.get_object_type(schema)
 | 
					 | 
				
			||||||
        if object_type and object_type._meta.is_mutation:
 | 
					 | 
				
			||||||
            return object_type.mutate
 | 
					 | 
				
			||||||
        elif self.resolve_fn:
 | 
					 | 
				
			||||||
            return self.resolve_fn
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            custom_resolve_fn_name = 'resolve_%s' % self.attname
 | 
					 | 
				
			||||||
            if hasattr(self.object_type, custom_resolve_fn_name):
 | 
					 | 
				
			||||||
                resolve_fn = getattr(self.object_type, custom_resolve_fn_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                @wraps(resolve_fn)
 | 
					 | 
				
			||||||
                def custom_resolve_fn(instance, args, info):
 | 
					 | 
				
			||||||
                    return resolve_fn(instance, args, info)
 | 
					 | 
				
			||||||
                return custom_resolve_fn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_object_type(self, schema):
 | 
					 | 
				
			||||||
        field_type = self.field_type
 | 
					 | 
				
			||||||
        if inspect.isfunction(field_type):
 | 
					 | 
				
			||||||
            field_type = field_type(self)
 | 
					 | 
				
			||||||
        _is_class = inspect.isclass(field_type)
 | 
					 | 
				
			||||||
        if isinstance(field_type, Field):
 | 
					 | 
				
			||||||
            return field_type.get_object_type(schema)
 | 
					 | 
				
			||||||
        if _is_class and issubclass(field_type, BaseObjectType):
 | 
					 | 
				
			||||||
            return field_type
 | 
					 | 
				
			||||||
        elif isinstance(field_type, six.string_types):
 | 
					 | 
				
			||||||
            if field_type == 'self':
 | 
					 | 
				
			||||||
                return self.object_type
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                return schema.get_type(field_type)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def type_wrapper(self, field_type):
 | 
					 | 
				
			||||||
        if self.required:
 | 
					 | 
				
			||||||
            field_type = GraphQLNonNull(field_type)
 | 
					 | 
				
			||||||
        return field_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def internal_type(self, schema):
 | 
					 | 
				
			||||||
        field_type = self.field_type
 | 
					 | 
				
			||||||
        _is_class = inspect.isclass(field_type)
 | 
					 | 
				
			||||||
        if isinstance(field_type, Field):
 | 
					 | 
				
			||||||
            field_type = self.field_type.internal_type(schema)
 | 
					 | 
				
			||||||
        elif _is_class and issubclass(field_type, Enum):
 | 
					 | 
				
			||||||
            field_type = enum_to_graphql_enum(field_type)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            object_type = self.get_object_type(schema)
 | 
					 | 
				
			||||||
            if object_type:
 | 
					 | 
				
			||||||
                field_type = schema.T(object_type)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        field_type = self.type_wrapper(field_type)
 | 
					 | 
				
			||||||
        return field_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def internal_field(self, schema):
 | 
					 | 
				
			||||||
        if not self.object_type:
 | 
					 | 
				
			||||||
            raise Exception(
 | 
					 | 
				
			||||||
                'Field could not be constructed in a non graphene.ObjectType or graphene.Interface')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        extra_args = self.extra_args.copy()
 | 
					 | 
				
			||||||
        for arg_name, arg_value in self.extra_args.items():
 | 
					 | 
				
			||||||
            if isinstance(arg_value, GraphQLArgument):
 | 
					 | 
				
			||||||
                self.args[arg_name] = arg_value
 | 
					 | 
				
			||||||
                del extra_args[arg_name]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if extra_args != {}:
 | 
					 | 
				
			||||||
            raise TypeError("Field %s.%s initiated with invalid args: %s" % (
 | 
					 | 
				
			||||||
                self.object_type,
 | 
					 | 
				
			||||||
                self.attname,
 | 
					 | 
				
			||||||
                ','.join(extra_args.keys())
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        args = self.args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        object_type = self.get_object_type(schema)
 | 
					 | 
				
			||||||
        if object_type and object_type._meta.is_mutation:
 | 
					 | 
				
			||||||
            assert not self.args, 'Arguments provided for mutations are defined in Input class in Mutation'
 | 
					 | 
				
			||||||
            args = object_type.get_input_type().fields_as_arguments(schema)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        internal_type = self.internal_type(schema)
 | 
					 | 
				
			||||||
        if not internal_type:
 | 
					 | 
				
			||||||
            raise Exception("Internal type for field %s is None" % self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        description = self.description
 | 
					 | 
				
			||||||
        resolve_fn = self.get_resolve_fn(schema)
 | 
					 | 
				
			||||||
        if resolve_fn:
 | 
					 | 
				
			||||||
            description = resolve_fn.__doc__ or description
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            @wraps(resolve_fn)
 | 
					 | 
				
			||||||
            def resolver(*args):
 | 
					 | 
				
			||||||
                return self.resolve(*args)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            resolver = self.resolve
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if issubclass(self.object_type, InputObjectType):
 | 
					 | 
				
			||||||
            return GraphQLInputObjectField(
 | 
					 | 
				
			||||||
                internal_type,
 | 
					 | 
				
			||||||
                description=description,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return GraphQLField(
 | 
					 | 
				
			||||||
            internal_type,
 | 
					 | 
				
			||||||
            description=description,
 | 
					 | 
				
			||||||
            args=args,
 | 
					 | 
				
			||||||
            resolver=resolver,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """ Return "object_type.name". """
 | 
					 | 
				
			||||||
        return '%s.%s' % (self.object_type.__name__, self.attname)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Displays the module, class and name of the field.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
 | 
					 | 
				
			||||||
        name = getattr(self, 'attname', None)
 | 
					 | 
				
			||||||
        if name is not None:
 | 
					 | 
				
			||||||
            return '<%s: %s>' % (path, name)
 | 
					 | 
				
			||||||
        return '<%s>' % path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __eq__(self, other):
 | 
					 | 
				
			||||||
        # Needed for @total_ordering
 | 
					 | 
				
			||||||
        if isinstance(other, Field):
 | 
					 | 
				
			||||||
            return self.creation_counter == other.creation_counter and \
 | 
					 | 
				
			||||||
                self.object_type == other.object_type
 | 
					 | 
				
			||||||
        return NotImplemented
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __lt__(self, other):
 | 
					 | 
				
			||||||
        # This is needed because bisect does not take a comparison function.
 | 
					 | 
				
			||||||
        if isinstance(other, Field):
 | 
					 | 
				
			||||||
            return self.creation_counter < other.creation_counter
 | 
					 | 
				
			||||||
        return NotImplemented
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __hash__(self):
 | 
					 | 
				
			||||||
        return hash((self.creation_counter, self.object_type))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __copy__(self):
 | 
					 | 
				
			||||||
        # We need to avoid hitting __reduce__, so define this
 | 
					 | 
				
			||||||
        # slightly weird copy construct.
 | 
					 | 
				
			||||||
        obj = Empty()
 | 
					 | 
				
			||||||
        obj.__class__ = self.__class__
 | 
					 | 
				
			||||||
        obj.__dict__ = self.__dict__.copy()
 | 
					 | 
				
			||||||
        if self.field_type == 'self':
 | 
					 | 
				
			||||||
            obj.field_type = self.object_type
 | 
					 | 
				
			||||||
        return obj
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class LazyField(Field):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def inner_field(self, schema):
 | 
					 | 
				
			||||||
        return self.get_field(schema)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def internal_type(self, schema):
 | 
					 | 
				
			||||||
        return self.inner_field(schema).internal_type(schema)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def internal_field(self, schema):
 | 
					 | 
				
			||||||
        return self.inner_field(schema).internal_field(schema)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class TypeField(Field):
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(TypeField, self).__init__(self.field_type, *args, **kwargs)
 | 
					        cls = self.__class__
 | 
				
			||||||
 | 
					        warnings.warn("Using {} is not longer supported".format(
 | 
				
			||||||
 | 
					            cls.__name__), FutureWarning)
 | 
				
			||||||
 | 
					        if 'resolve' in kwargs:
 | 
				
			||||||
 | 
					            kwargs['resolver'] = kwargs.pop('resolve')
 | 
				
			||||||
 | 
					        return super(DeprecatedField, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StringField(TypeField):
 | 
					class StringField(DeprecatedField, String):
 | 
				
			||||||
    field_type = GraphQLString
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IntField(TypeField):
 | 
					class IntField(DeprecatedField, Int):
 | 
				
			||||||
    field_type = GraphQLInt
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BooleanField(TypeField):
 | 
					class BooleanField(DeprecatedField, Boolean):
 | 
				
			||||||
    field_type = GraphQLBoolean
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IDField(TypeField):
 | 
					class IDField(DeprecatedField, ID):
 | 
				
			||||||
    field_type = GraphQLID
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FloatField(TypeField):
 | 
					class FloatField(DeprecatedField, Float):
 | 
				
			||||||
    field_type = GraphQLFloat
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ListField(Field):
 | 
					class ListField(DeprecatedField, List):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
    def type_wrapper(self, field_type):
 | 
					 | 
				
			||||||
        return GraphQLList(field_type)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NonNullField(Field):
 | 
					class NonNullField(DeprecatedField, NonNull):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def type_wrapper(self, field_type):
 | 
					
 | 
				
			||||||
        return GraphQLNonNull(field_type)
 | 
					__all__ = ['Field', 'StringField', 'IntField', 'BooleanField',
 | 
				
			||||||
 | 
					           'IDField', 'FloatField', 'ListField', 'NonNullField']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,9 @@ class Options(object):
 | 
				
			||||||
            # Any leftover attributes must be invalid.
 | 
					            # Any leftover attributes must be invalid.
 | 
				
			||||||
            if meta_attrs != {}:
 | 
					            if meta_attrs != {}:
 | 
				
			||||||
                raise TypeError(
 | 
					                raise TypeError(
 | 
				
			||||||
                    "'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
 | 
					                    "'class Meta' got invalid attribute(s): %s" %
 | 
				
			||||||
 | 
					                    ','.join(
 | 
				
			||||||
 | 
					                        meta_attrs.keys()))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.proxy = False
 | 
					            self.proxy = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
 | 
					import inspect
 | 
				
			||||||
from collections import OrderedDict
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene import signals
 | 
					from graphene import signals
 | 
				
			||||||
 | 
					from graphene.core.types.base import BaseType
 | 
				
			||||||
 | 
					from graphene.core.types.objecttype import BaseObjectType
 | 
				
			||||||
from graphql.core.execution.executor import Executor
 | 
					from graphql.core.execution.executor import Executor
 | 
				
			||||||
from graphql.core.execution.middlewares.sync import \
 | 
					from graphql.core.execution.middlewares.sync import \
 | 
				
			||||||
    SynchronousExecutionMiddleware
 | 
					    SynchronousExecutionMiddleware
 | 
				
			||||||
| 
						 | 
					@ -16,10 +19,10 @@ class GraphQLSchema(_GraphQLSchema):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Schema(object):
 | 
					class Schema(object):
 | 
				
			||||||
    _query = None
 | 
					 | 
				
			||||||
    _executor = None
 | 
					    _executor = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, query=None, mutation=None, name='Schema', executor=None):
 | 
					    def __init__(self, query=None, mutation=None,
 | 
				
			||||||
 | 
					                 name='Schema', executor=None):
 | 
				
			||||||
        self._types_names = {}
 | 
					        self._types_names = {}
 | 
				
			||||||
        self._types = {}
 | 
					        self._types = {}
 | 
				
			||||||
        self.mutation = mutation
 | 
					        self.mutation = mutation
 | 
				
			||||||
| 
						 | 
					@ -34,32 +37,24 @@ class Schema(object):
 | 
				
			||||||
    def T(self, object_type):
 | 
					    def T(self, object_type):
 | 
				
			||||||
        if not object_type:
 | 
					        if not object_type:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					        if inspect.isclass(object_type) and issubclass(
 | 
				
			||||||
 | 
					                object_type, BaseType) or isinstance(
 | 
				
			||||||
 | 
					                object_type, BaseType):
 | 
				
			||||||
            if object_type not in self._types:
 | 
					            if object_type not in self._types:
 | 
				
			||||||
                internal_type = object_type.internal_type(self)
 | 
					                internal_type = object_type.internal_type(self)
 | 
				
			||||||
                self._types[object_type] = internal_type
 | 
					                self._types[object_type] = internal_type
 | 
				
			||||||
            self._types_names[internal_type.name] = object_type
 | 
					                is_objecttype = inspect.isclass(
 | 
				
			||||||
 | 
					                    object_type) and issubclass(object_type, BaseObjectType)
 | 
				
			||||||
 | 
					                if is_objecttype:
 | 
				
			||||||
 | 
					                    self.register(object_type)
 | 
				
			||||||
            return self._types[object_type]
 | 
					            return self._types[object_type]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
    @property
 | 
					            return object_type
 | 
				
			||||||
    def query(self):
 | 
					 | 
				
			||||||
        return self._query
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @query.setter
 | 
					 | 
				
			||||||
    def query(self, query):
 | 
					 | 
				
			||||||
        self._query = query
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def mutation(self):
 | 
					 | 
				
			||||||
        return self._mutation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @mutation.setter
 | 
					 | 
				
			||||||
    def mutation(self, mutation):
 | 
					 | 
				
			||||||
        self._mutation = mutation
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def executor(self):
 | 
					    def executor(self):
 | 
				
			||||||
        if not self._executor:
 | 
					        if not self._executor:
 | 
				
			||||||
            self.executor = Executor(
 | 
					            self._executor = Executor(
 | 
				
			||||||
                [SynchronousExecutionMiddleware()], map_type=OrderedDict)
 | 
					                [SynchronousExecutionMiddleware()], map_type=OrderedDict)
 | 
				
			||||||
        return self._executor
 | 
					        return self._executor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,25 +64,45 @@ class Schema(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def schema(self):
 | 
					    def schema(self):
 | 
				
			||||||
        if not self._query:
 | 
					        if not self.query:
 | 
				
			||||||
            raise Exception('You have to define a base query type')
 | 
					            raise Exception('You have to define a base query type')
 | 
				
			||||||
        return GraphQLSchema(self, query=self.T(self._query), mutation=self.T(self._mutation))
 | 
					        return GraphQLSchema(
 | 
				
			||||||
 | 
					            self, query=self.T(self.query),
 | 
				
			||||||
 | 
					            mutation=self.T(self.mutation))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def register(self, object_type):
 | 
					    def register(self, object_type):
 | 
				
			||||||
 | 
					        type_name = object_type._meta.type_name
 | 
				
			||||||
 | 
					        registered_object_type = self._types_names.get(type_name, None)
 | 
				
			||||||
 | 
					        if registered_object_type:
 | 
				
			||||||
 | 
					            assert registered_object_type == object_type, 'Type {} already registered with other object type'.format(
 | 
				
			||||||
 | 
					                type_name)
 | 
				
			||||||
        self._types_names[object_type._meta.type_name] = object_type
 | 
					        self._types_names[object_type._meta.type_name] = object_type
 | 
				
			||||||
        return object_type
 | 
					        return object_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def objecttype(self, type):
 | 
				
			||||||
 | 
					        name = getattr(type, 'name', None)
 | 
				
			||||||
 | 
					        if name:
 | 
				
			||||||
 | 
					            objecttype = self._types_names.get(name, None)
 | 
				
			||||||
 | 
					            if objecttype and inspect.isclass(
 | 
				
			||||||
 | 
					                    objecttype) and issubclass(objecttype, BaseObjectType):
 | 
				
			||||||
 | 
					                return objecttype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setup(self):
 | 
				
			||||||
 | 
					        assert self.query, 'The base query type is not set'
 | 
				
			||||||
 | 
					        self.T(self.query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_type(self, type_name):
 | 
					    def get_type(self, type_name):
 | 
				
			||||||
        self.schema._build_type_map()
 | 
					        self.setup()
 | 
				
			||||||
        if type_name not in self._types_names:
 | 
					        if type_name not in self._types_names:
 | 
				
			||||||
            raise Exception('Type %s not found in %r' % (type_name, self))
 | 
					            raise KeyError('Type %r not found in %r' % (type_name, self))
 | 
				
			||||||
        return self._types_names[type_name]
 | 
					        return self._types_names[type_name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def types(self):
 | 
					    def types(self):
 | 
				
			||||||
        return self._types_names
 | 
					        return self._types_names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def execute(self, request='', root=None, vars=None, operation_name=None, **kwargs):
 | 
					    def execute(self, request='', root=None, vars=None,
 | 
				
			||||||
 | 
					                operation_name=None, **kwargs):
 | 
				
			||||||
        root = root or object()
 | 
					        root = root or object()
 | 
				
			||||||
        return self.executor.execute(
 | 
					        return self.executor.execute(
 | 
				
			||||||
            self.schema,
 | 
					            self.schema,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,3 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
import graphene
 | 
					import graphene
 | 
				
			||||||
from graphene.core.schema import Schema
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,15 +5,15 @@ my_id = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
    base = graphene.StringField()
 | 
					    base = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ChangeNumber(graphene.Mutation):
 | 
					class ChangeNumber(graphene.Mutation):
 | 
				
			||||||
    '''Result mutation'''
 | 
					    '''Result mutation'''
 | 
				
			||||||
    class Input:
 | 
					    class Input:
 | 
				
			||||||
        to = graphene.IntField()
 | 
					        to = graphene.Int()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    result = graphene.StringField()
 | 
					    result = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def mutate(cls, instance, args, info):
 | 
					    def mutate(cls, instance, args, info):
 | 
				
			||||||
| 
						 | 
					@ -31,9 +30,7 @@ schema = Schema(query=Query, mutation=MyResultMutation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_mutation_input():
 | 
					def test_mutation_input():
 | 
				
			||||||
    assert ChangeNumber.input_type
 | 
					    assert list(schema.T(ChangeNumber.arguments).keys()) == ['to']
 | 
				
			||||||
    assert ChangeNumber.input_type._meta.type_name == 'ChangeNumberInput'
 | 
					 | 
				
			||||||
    assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['to']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_execute_mutations():
 | 
					def test_execute_mutations():
 | 
				
			||||||
							
								
								
									
										178
									
								
								graphene/core/tests/test_old_fields.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								graphene/core/tests/test_old_fields.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,178 @@
 | 
				
			||||||
 | 
					from py.test import raises
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphene.core.fields import (BooleanField, Field, FloatField, IDField,
 | 
				
			||||||
 | 
					                                  IntField, NonNullField, StringField)
 | 
				
			||||||
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					from graphene.core.types import ObjectType
 | 
				
			||||||
 | 
					from graphql.core.type import (GraphQLBoolean, GraphQLField, GraphQLFloat,
 | 
				
			||||||
 | 
					                               GraphQLID, GraphQLInt, GraphQLNonNull,
 | 
				
			||||||
 | 
					                               GraphQLString)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MyOt(ObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_customdoc(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        '''Resolver documentation'''
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return "ObjectType"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_no_contributed_raises_error():
 | 
				
			||||||
 | 
					    f = Field(GraphQLString)
 | 
				
			||||||
 | 
					    with raises(Exception):
 | 
				
			||||||
 | 
					        schema.T(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_type():
 | 
				
			||||||
 | 
					    f = Field(GraphQLString)
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert isinstance(schema.T(f), GraphQLField)
 | 
				
			||||||
 | 
					    assert schema.T(f).type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_name_automatic_camelcase():
 | 
				
			||||||
 | 
					    f = Field(GraphQLString)
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert f.name == 'fieldName'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_name_use_name_if_exists():
 | 
				
			||||||
 | 
					    f = Field(GraphQLString, name='my_custom_name')
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert f.name == 'my_custom_name'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_stringfield_type():
 | 
				
			||||||
 | 
					    f = StringField()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert schema.T(f) == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_idfield_type():
 | 
				
			||||||
 | 
					    f = IDField()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert schema.T(f) == GraphQLID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_booleanfield_type():
 | 
				
			||||||
 | 
					    f = BooleanField()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert schema.T(f) == GraphQLBoolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_intfield_type():
 | 
				
			||||||
 | 
					    f = IntField()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert schema.T(f) == GraphQLInt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_floatfield_type():
 | 
				
			||||||
 | 
					    f = FloatField()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert schema.T(f) == GraphQLFloat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nonnullfield_type():
 | 
				
			||||||
 | 
					    f = NonNullField(StringField())
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert isinstance(schema.T(f), GraphQLNonNull)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_stringfield_type_required():
 | 
				
			||||||
 | 
					    f = StringField(required=True).as_field()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert isinstance(schema.T(f), GraphQLField)
 | 
				
			||||||
 | 
					    assert isinstance(schema.T(f).type, GraphQLNonNull)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_resolve():
 | 
				
			||||||
 | 
					    f = StringField(required=True, resolve=lambda *args: 'RESOLVED').as_field()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    field_type = schema.T(f)
 | 
				
			||||||
 | 
					    assert 'RESOLVED' == field_type.resolver(MyOt, None, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_resolve_type_custom():
 | 
				
			||||||
 | 
					    class MyCustomType(ObjectType):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    f = Field('MyCustomType')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class OtherType(ObjectType):
 | 
				
			||||||
 | 
					        field_name = f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s = Schema()
 | 
				
			||||||
 | 
					    s.query = OtherType
 | 
				
			||||||
 | 
					    s.register(MyCustomType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert s.T(f).type == s.T(MyCustomType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_orders():
 | 
				
			||||||
 | 
					    f1 = Field(None)
 | 
				
			||||||
 | 
					    f2 = Field(None)
 | 
				
			||||||
 | 
					    assert f1 < f2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_orders_wrong_type():
 | 
				
			||||||
 | 
					    field = Field(None)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        assert not field < 1
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        # Fix exception raising in Python3+
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_eq():
 | 
				
			||||||
 | 
					    f1 = Field(None)
 | 
				
			||||||
 | 
					    f2 = Field(None)
 | 
				
			||||||
 | 
					    assert f1 != f2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_eq_wrong_type():
 | 
				
			||||||
 | 
					    field = Field(None)
 | 
				
			||||||
 | 
					    assert field != 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_hash():
 | 
				
			||||||
 | 
					    f1 = Field(None)
 | 
				
			||||||
 | 
					    f2 = Field(None)
 | 
				
			||||||
 | 
					    assert hash(f1) != hash(f2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_none_type_raises_error():
 | 
				
			||||||
 | 
					    s = Schema()
 | 
				
			||||||
 | 
					    f = Field(None)
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
 | 
					        s.T(f)
 | 
				
			||||||
 | 
					    assert str(
 | 
				
			||||||
 | 
					        excinfo.value) == "Internal type for field MyOt.field_name is None"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_str():
 | 
				
			||||||
 | 
					    f = StringField().as_field()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert str(f) == "MyOt.field_name"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_repr():
 | 
				
			||||||
 | 
					    f = StringField().as_field()
 | 
				
			||||||
 | 
					    assert repr(f) == "<graphene.core.types.field.Field>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_repr_contributed():
 | 
				
			||||||
 | 
					    f = StringField().as_field()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'field_name')
 | 
				
			||||||
 | 
					    assert repr(f) == "<graphene.core.types.field.Field: field_name>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_resolve_objecttype_cos():
 | 
				
			||||||
 | 
					    f = StringField().as_field()
 | 
				
			||||||
 | 
					    f.contribute_to_class(MyOt, 'customdoc')
 | 
				
			||||||
 | 
					    field = schema.T(f)
 | 
				
			||||||
 | 
					    assert field.description == 'Resolver documentation'
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,6 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
from py.test import raises
 | 
					from py.test import raises
 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.fields import StringField
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
from graphene.core.options import Options
 | 
					from graphene.core.options import Options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +20,7 @@ def test_field_added_in_meta():
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    opt.contribute_to_class(ObjectType, '_meta')
 | 
					    opt.contribute_to_class(ObjectType, '_meta')
 | 
				
			||||||
    f = StringField()
 | 
					    f = Field(None)
 | 
				
			||||||
    f.attname = 'string_field'
 | 
					    f.attname = 'string_field'
 | 
				
			||||||
    opt.add_field(f)
 | 
					    opt.add_field(f)
 | 
				
			||||||
    assert f in opt.fields
 | 
					    assert f in opt.fields
 | 
				
			||||||
| 
						 | 
					@ -1,23 +1,22 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.fields import Field, ListField, StringField
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
from graphene.core.schema import Schema
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
from graphene.core.types import Interface, ObjectType
 | 
					from graphene.core.types import Interface, List, ObjectType, String
 | 
				
			||||||
from graphql.core import graphql
 | 
					from graphql.core import graphql
 | 
				
			||||||
from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType,
 | 
					from graphql.core.type import GraphQLSchema
 | 
				
			||||||
                               GraphQLSchema)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(Interface):
 | 
					class Character(Interface):
 | 
				
			||||||
    name = StringField()
 | 
					    name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pet(ObjectType):
 | 
					class Pet(ObjectType):
 | 
				
			||||||
    type = StringField(resolve=lambda *_: 'Dog')
 | 
					    type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
    friends = ListField(Character)
 | 
					    friends = List(Character)
 | 
				
			||||||
    pet = Field(Pet)
 | 
					    pet = Field(Pet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_name(self, *args):
 | 
					    def resolve_name(self, *args):
 | 
				
			||||||
| 
						 | 
					@ -28,8 +27,6 @@ class Human(Character):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_pet(self, *args):
 | 
					    def resolve_pet(self, *args):
 | 
				
			||||||
        return Pet(object())
 | 
					        return Pet(object())
 | 
				
			||||||
    # def resolve_friends(self, *args, **kwargs):
 | 
					 | 
				
			||||||
    #     return 'HEY YOU!'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
schema = Schema()
 | 
					schema = Schema()
 | 
				
			||||||
| 
						 | 
					@ -38,8 +35,8 @@ Human_type = schema.T(Human)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_type():
 | 
					def test_type():
 | 
				
			||||||
    assert Human._meta.fields_map['name'].resolve(
 | 
					    assert Human._meta.fields_map['name'].resolver(
 | 
				
			||||||
        Human(object()), None, None) == 'Peter'
 | 
					        Human(object()), {}, None) == 'Peter'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_query():
 | 
					def test_query():
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,24 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
from py.test import raises
 | 
					from py.test import raises
 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene import Interface, ObjectType, Schema
 | 
					from graphene import Interface, List, ObjectType, Schema, String
 | 
				
			||||||
from graphene.core.fields import Field, ListField, StringField
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
 | 
					from graphene.core.types.base import LazyType
 | 
				
			||||||
from graphql.core import graphql
 | 
					from graphql.core import graphql
 | 
				
			||||||
from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType,
 | 
					 | 
				
			||||||
                               GraphQLSchema)
 | 
					 | 
				
			||||||
from tests.utils import assert_equal_lists
 | 
					from tests.utils import assert_equal_lists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
schema = Schema(name='My own schema')
 | 
					schema = Schema(name='My own schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(Interface):
 | 
					class Character(Interface):
 | 
				
			||||||
    name = StringField()
 | 
					    name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pet(ObjectType):
 | 
					class Pet(ObjectType):
 | 
				
			||||||
    type = StringField(resolve=lambda *_: 'Dog')
 | 
					    type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
    friends = ListField(Character)
 | 
					    friends = List(Character)
 | 
				
			||||||
    pet = Field(Pet)
 | 
					    pet = Field(Pet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_name(self, *args):
 | 
					    def resolve_name(self, *args):
 | 
				
			||||||
| 
						 | 
					@ -95,9 +92,9 @@ def test_query_schema_execute():
 | 
				
			||||||
def test_schema_get_type_map():
 | 
					def test_schema_get_type_map():
 | 
				
			||||||
    assert_equal_lists(
 | 
					    assert_equal_lists(
 | 
				
			||||||
        schema.schema.get_type_map().keys(),
 | 
					        schema.schema.get_type_map().keys(),
 | 
				
			||||||
        ['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive',
 | 
					        ['__Field', 'String', 'Pet', 'Character', '__InputValue',
 | 
				
			||||||
            '__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean']
 | 
					         '__Directive', '__TypeKind', '__Schema', '__Type', 'Human',
 | 
				
			||||||
    )
 | 
					         '__EnumValue', 'Boolean'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_schema_no_query():
 | 
					def test_schema_no_query():
 | 
				
			||||||
| 
						 | 
					@ -112,19 +109,19 @@ def test_schema_register():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schema.register
 | 
					    @schema.register
 | 
				
			||||||
    class MyType(ObjectType):
 | 
					    class MyType(ObjectType):
 | 
				
			||||||
        type = StringField(resolve=lambda *_: 'Dog')
 | 
					        type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    schema.query = MyType
 | 
					    schema.query = MyType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert schema.get_type('MyType') == MyType
 | 
					    assert schema.get_type('MyType') == MyType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_schema_register():
 | 
					def test_schema_register_no_query_type():
 | 
				
			||||||
    schema = Schema(name='My own schema')
 | 
					    schema = Schema(name='My own schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @schema.register
 | 
					    @schema.register
 | 
				
			||||||
    class MyType(ObjectType):
 | 
					    class MyType(ObjectType):
 | 
				
			||||||
        type = StringField(resolve=lambda *_: 'Dog')
 | 
					        type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
        schema.get_type('MyType')
 | 
					        schema.get_type('MyType')
 | 
				
			||||||
| 
						 | 
					@ -135,9 +132,23 @@ def test_schema_introspect():
 | 
				
			||||||
    schema = Schema(name='My own schema')
 | 
					    schema = Schema(name='My own schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class MyType(ObjectType):
 | 
					    class MyType(ObjectType):
 | 
				
			||||||
        type = StringField(resolve=lambda *_: 'Dog')
 | 
					        type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    schema.query = MyType
 | 
					    schema.query = MyType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    introspection = schema.introspect()
 | 
					    introspection = schema.introspect()
 | 
				
			||||||
    assert '__schema' in introspection
 | 
					    assert '__schema' in introspection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_lazytype():
 | 
				
			||||||
 | 
					    schema = Schema(name='My own schema')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    t = LazyType('MyType')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @schema.register
 | 
				
			||||||
 | 
					    class MyType(ObjectType):
 | 
				
			||||||
 | 
					        type = String(resolver=lambda *_: 'Dog')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schema.query = MyType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert schema.T(t) == schema.T(MyType)
 | 
				
			||||||
							
								
								
									
										30
									
								
								graphene/core/types/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								graphene/core/types/__init__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					from .base import BaseType, LazyType, OrderedType
 | 
				
			||||||
 | 
					from .argument import Argument, ArgumentsGroup, to_arguments
 | 
				
			||||||
 | 
					from .definitions import List, NonNull
 | 
				
			||||||
 | 
					from .objecttype import ObjectTypeMeta, BaseObjectType, Interface, ObjectType, Mutation, InputObjectType
 | 
				
			||||||
 | 
					from .scalars import String, ID, Boolean, Int, Float, Scalar
 | 
				
			||||||
 | 
					from .field import Field, InputField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = [
 | 
				
			||||||
 | 
					    'BaseType',
 | 
				
			||||||
 | 
					    'LazyType',
 | 
				
			||||||
 | 
					    'OrderedType',
 | 
				
			||||||
 | 
					    'Argument',
 | 
				
			||||||
 | 
					    'ArgumentsGroup',
 | 
				
			||||||
 | 
					    'to_arguments',
 | 
				
			||||||
 | 
					    'List',
 | 
				
			||||||
 | 
					    'NonNull',
 | 
				
			||||||
 | 
					    'Field',
 | 
				
			||||||
 | 
					    'InputField',
 | 
				
			||||||
 | 
					    'Interface',
 | 
				
			||||||
 | 
					    'BaseObjectType',
 | 
				
			||||||
 | 
					    'ObjectTypeMeta',
 | 
				
			||||||
 | 
					    'ObjectType',
 | 
				
			||||||
 | 
					    'Mutation',
 | 
				
			||||||
 | 
					    'InputObjectType',
 | 
				
			||||||
 | 
					    'String',
 | 
				
			||||||
 | 
					    'ID',
 | 
				
			||||||
 | 
					    'Boolean',
 | 
				
			||||||
 | 
					    'Int',
 | 
				
			||||||
 | 
					    'Float',
 | 
				
			||||||
 | 
					    'Scalar']
 | 
				
			||||||
							
								
								
									
										71
									
								
								graphene/core/types/argument.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								graphene/core/types/argument.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,71 @@
 | 
				
			||||||
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					from itertools import chain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql.core.type import GraphQLArgument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ...utils import to_camel_case
 | 
				
			||||||
 | 
					from .base import ArgumentType, BaseType, OrderedType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Argument(OrderedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, type, description=None, default=None,
 | 
				
			||||||
 | 
					                 name=None, _creation_counter=None):
 | 
				
			||||||
 | 
					        super(Argument, self).__init__(_creation_counter=_creation_counter)
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        self.type = type
 | 
				
			||||||
 | 
					        self.description = description
 | 
				
			||||||
 | 
					        self.default = default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        return GraphQLArgument(
 | 
				
			||||||
 | 
					            schema.T(self.type),
 | 
				
			||||||
 | 
					            self.default, self.description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArgumentsGroup(BaseType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        arguments = to_arguments(*args, **kwargs)
 | 
				
			||||||
 | 
					        self.arguments = OrderedDict([(arg.name, arg) for arg in arguments])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        return OrderedDict([(arg.name, schema.T(arg))
 | 
				
			||||||
 | 
					                            for arg in self.arguments.values()])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __len__(self):
 | 
				
			||||||
 | 
					        return len(self.arguments)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __iter__(self):
 | 
				
			||||||
 | 
					        return iter(self.arguments)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __contains__(self, *args):
 | 
				
			||||||
 | 
					        return self.arguments.__contains__(*args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __getitem__(self, *args):
 | 
				
			||||||
 | 
					        return self.arguments.__getitem__(*args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def to_arguments(*args, **kwargs):
 | 
				
			||||||
 | 
					    arguments = {}
 | 
				
			||||||
 | 
					    iter_arguments = chain(kwargs.items(), [(None, a) for a in args])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for name, 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))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return sorted(arguments.values())
 | 
				
			||||||
							
								
								
									
										127
									
								
								graphene/core/types/base.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								graphene/core/types/base.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,127 @@
 | 
				
			||||||
 | 
					from functools import total_ordering
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseType(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def internal_type(cls, schema):
 | 
				
			||||||
 | 
					        return getattr(cls, 'T', None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MountType(BaseType):
 | 
				
			||||||
 | 
					    parent = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mount(self, cls):
 | 
				
			||||||
 | 
					        self.parent = cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LazyType(MountType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, type):
 | 
				
			||||||
 | 
					        self.type = type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def is_self(self):
 | 
				
			||||||
 | 
					        return self.type == 'self'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        type = None
 | 
				
			||||||
 | 
					        if callable(self.type):
 | 
				
			||||||
 | 
					            type = self.type(self.parent)
 | 
				
			||||||
 | 
					        elif isinstance(self.type, six.string_types):
 | 
				
			||||||
 | 
					            if self.is_self:
 | 
				
			||||||
 | 
					                type = self.parent
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                type = schema.get_type(self.type)
 | 
				
			||||||
 | 
					        assert type, 'Type in %s %r cannot be none' % (self.type, self.parent)
 | 
				
			||||||
 | 
					        return schema.T(type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@total_ordering
 | 
				
			||||||
 | 
					class OrderedType(MountType):
 | 
				
			||||||
 | 
					    creation_counter = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, _creation_counter=None):
 | 
				
			||||||
 | 
					        self.creation_counter = _creation_counter or self.gen_counter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def gen_counter():
 | 
				
			||||||
 | 
					        counter = OrderedType.creation_counter
 | 
				
			||||||
 | 
					        OrderedType.creation_counter += 1
 | 
				
			||||||
 | 
					        return counter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __eq__(self, other):
 | 
				
			||||||
 | 
					        # Needed for @total_ordering
 | 
				
			||||||
 | 
					        if isinstance(self, type(other)):
 | 
				
			||||||
 | 
					            return self.creation_counter == other.creation_counter
 | 
				
			||||||
 | 
					        return NotImplemented
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __lt__(self, other):
 | 
				
			||||||
 | 
					        # This is needed because bisect does not take a comparison function.
 | 
				
			||||||
 | 
					        if isinstance(other, OrderedType):
 | 
				
			||||||
 | 
					            return self.creation_counter < other.creation_counter
 | 
				
			||||||
 | 
					        return NotImplemented
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __gt__(self, other):
 | 
				
			||||||
 | 
					        # This is needed because bisect does not take a comparison function.
 | 
				
			||||||
 | 
					        if isinstance(other, OrderedType):
 | 
				
			||||||
 | 
					            return self.creation_counter > other.creation_counter
 | 
				
			||||||
 | 
					        return NotImplemented
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __hash__(self):
 | 
				
			||||||
 | 
					        return hash((self.creation_counter))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MirroredType(OrderedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        _creation_counter = kwargs.pop('_creation_counter', None)
 | 
				
			||||||
 | 
					        super(MirroredType, self).__init__(_creation_counter=_creation_counter)
 | 
				
			||||||
 | 
					        self.args = args
 | 
				
			||||||
 | 
					        self.kwargs = kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def List(self):  # noqa
 | 
				
			||||||
 | 
					        from .definitions import List
 | 
				
			||||||
 | 
					        return List(self, *self.args, **self.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def NonNull(self):  # noqa
 | 
				
			||||||
 | 
					        from .definitions import NonNull
 | 
				
			||||||
 | 
					        return NonNull(self, *self.args, **self.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArgumentType(MirroredType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def as_argument(self):
 | 
				
			||||||
 | 
					        from .argument import Argument
 | 
				
			||||||
 | 
					        return Argument(
 | 
				
			||||||
 | 
					            self, _creation_counter=self.creation_counter, *self.args, **self.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FieldType(MirroredType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def contribute_to_class(self, cls, name):
 | 
				
			||||||
 | 
					        from ..types import BaseObjectType, InputObjectType
 | 
				
			||||||
 | 
					        if issubclass(cls, InputObjectType):
 | 
				
			||||||
 | 
					            inputfield = self.as_inputfield()
 | 
				
			||||||
 | 
					            return inputfield.contribute_to_class(cls, name)
 | 
				
			||||||
 | 
					        elif issubclass(cls, BaseObjectType):
 | 
				
			||||||
 | 
					            field = self.as_field()
 | 
				
			||||||
 | 
					            return field.contribute_to_class(cls, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def as_field(self):
 | 
				
			||||||
 | 
					        from .field import Field
 | 
				
			||||||
 | 
					        return Field(self, _creation_counter=self.creation_counter,
 | 
				
			||||||
 | 
					                     *self.args, **self.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def as_inputfield(self):
 | 
				
			||||||
 | 
					        from .field import InputField
 | 
				
			||||||
 | 
					        return InputField(
 | 
				
			||||||
 | 
					            self, _creation_counter=self.creation_counter, *self.args, **self.kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MountedType(FieldType, ArgumentType):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
							
								
								
									
										30
									
								
								graphene/core/types/definitions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								graphene/core/types/definitions.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql.core.type import GraphQLList, GraphQLNonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base import LazyType, MountedType, MountType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OfType(MountedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, of_type, *args, **kwargs):
 | 
				
			||||||
 | 
					        if isinstance(of_type, six.string_types):
 | 
				
			||||||
 | 
					            of_type = LazyType(of_type)
 | 
				
			||||||
 | 
					        self.of_type = of_type
 | 
				
			||||||
 | 
					        super(OfType, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        return self.T(schema.T(self.of_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mount(self, cls):
 | 
				
			||||||
 | 
					        self.parent = cls
 | 
				
			||||||
 | 
					        if isinstance(self.of_type, MountType):
 | 
				
			||||||
 | 
					            self.of_type.mount(cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class List(OfType):
 | 
				
			||||||
 | 
					    T = GraphQLList
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NonNull(OfType):
 | 
				
			||||||
 | 
					    T = GraphQLNonNull
 | 
				
			||||||
							
								
								
									
										151
									
								
								graphene/core/types/field.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								graphene/core/types/field.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,151 @@
 | 
				
			||||||
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					from functools import wraps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql.core.type import GraphQLField, GraphQLInputObjectField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ...utils import ProxySnakeDict, to_camel_case
 | 
				
			||||||
 | 
					from ..types import BaseObjectType, InputObjectType
 | 
				
			||||||
 | 
					from .argument import ArgumentsGroup
 | 
				
			||||||
 | 
					from .base import LazyType, MountType, OrderedType
 | 
				
			||||||
 | 
					from .definitions import NonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def make_args_snake_case(resolver):
 | 
				
			||||||
 | 
					    @wraps(resolver)
 | 
				
			||||||
 | 
					    def wrapped_resolver(instance, args, info):
 | 
				
			||||||
 | 
					        return resolver(instance, ProxySnakeDict(args), info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return wrapped_resolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Empty(object):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Field(OrderedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(
 | 
				
			||||||
 | 
					            self, type, description=None, args=None, name=None, resolver=None,
 | 
				
			||||||
 | 
					            required=False, default=None, *args_list, **kwargs):
 | 
				
			||||||
 | 
					        _creation_counter = kwargs.pop('_creation_counter', None)
 | 
				
			||||||
 | 
					        super(Field, self).__init__(_creation_counter=_creation_counter)
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        if isinstance(type, six.string_types):
 | 
				
			||||||
 | 
					            type = LazyType(type)
 | 
				
			||||||
 | 
					        self.required = required
 | 
				
			||||||
 | 
					        self.type = type
 | 
				
			||||||
 | 
					        self.description = description
 | 
				
			||||||
 | 
					        args = OrderedDict(args or {}, **kwargs)
 | 
				
			||||||
 | 
					        self.arguments = ArgumentsGroup(*args_list, **args)
 | 
				
			||||||
 | 
					        self.object_type = None
 | 
				
			||||||
 | 
					        self.resolver_fn = resolver
 | 
				
			||||||
 | 
					        self.default = default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def contribute_to_class(self, cls, attname):
 | 
				
			||||||
 | 
					        assert issubclass(
 | 
				
			||||||
 | 
					            cls, BaseObjectType), '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)
 | 
				
			||||||
 | 
					        if isinstance(self.type, MountType):
 | 
				
			||||||
 | 
					            self.type.mount(cls)
 | 
				
			||||||
 | 
					        cls._meta.add_field(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def resolver(self):
 | 
				
			||||||
 | 
					        return self.resolver_fn or self.get_resolver_fn()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @resolver.setter
 | 
				
			||||||
 | 
					    def resolver(self, value):
 | 
				
			||||||
 | 
					        self.resolver_fn = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_resolver_fn(self):
 | 
				
			||||||
 | 
					        resolve_fn_name = 'resolve_%s' % self.attname
 | 
				
			||||||
 | 
					        if hasattr(self.object_type, resolve_fn_name):
 | 
				
			||||||
 | 
					            return getattr(self.object_type, resolve_fn_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def default_getter(instance, args, info):
 | 
				
			||||||
 | 
					            return getattr(instance, self.attname, self.default)
 | 
				
			||||||
 | 
					        return default_getter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_type(self, schema):
 | 
				
			||||||
 | 
					        if self.required:
 | 
				
			||||||
 | 
					            return NonNull(self.type)
 | 
				
			||||||
 | 
					        return self.type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        resolver = self.resolver
 | 
				
			||||||
 | 
					        description = self.description
 | 
				
			||||||
 | 
					        arguments = self.arguments
 | 
				
			||||||
 | 
					        if not description and resolver:
 | 
				
			||||||
 | 
					            description = resolver.__doc__
 | 
				
			||||||
 | 
					        type = schema.T(self.get_type(schema))
 | 
				
			||||||
 | 
					        type_objecttype = schema.objecttype(type)
 | 
				
			||||||
 | 
					        if type_objecttype and type_objecttype._meta.is_mutation:
 | 
				
			||||||
 | 
					            assert len(arguments) == 0
 | 
				
			||||||
 | 
					            arguments = type_objecttype.get_arguments()
 | 
				
			||||||
 | 
					            resolver = getattr(type_objecttype, 'mutate')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resolver = make_args_snake_case(resolver)
 | 
				
			||||||
 | 
					        assert type, 'Internal type for field %s is None' % str(self)
 | 
				
			||||||
 | 
					        return GraphQLField(type, args=schema.T(arguments), resolver=resolver,
 | 
				
			||||||
 | 
					                            description=description,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Displays the module, class and name of the field.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
 | 
				
			||||||
 | 
					        name = getattr(self, 'attname', None)
 | 
				
			||||||
 | 
					        if name is not None:
 | 
				
			||||||
 | 
					            return '<%s: %s>' % (path, name)
 | 
				
			||||||
 | 
					        return '<%s>' % path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        """ Return "object_type.field_name". """
 | 
				
			||||||
 | 
					        return '%s.%s' % (self.object_type.__name__, self.attname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __eq__(self, other):
 | 
				
			||||||
 | 
					        eq = super(Field, self).__eq__(other)
 | 
				
			||||||
 | 
					        if isinstance(self, type(other)):
 | 
				
			||||||
 | 
					            return eq and self.object_type == other.object_type
 | 
				
			||||||
 | 
					        return NotImplemented
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __hash__(self):
 | 
				
			||||||
 | 
					        return hash((self.creation_counter, self.object_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InputField(OrderedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, type, description=None, default=None,
 | 
				
			||||||
 | 
					                 name=None, _creation_counter=None, required=False):
 | 
				
			||||||
 | 
					        super(InputField, self).__init__(_creation_counter=_creation_counter)
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        if required:
 | 
				
			||||||
 | 
					            type = NonNull(type)
 | 
				
			||||||
 | 
					        self.type = type
 | 
				
			||||||
 | 
					        self.description = description
 | 
				
			||||||
 | 
					        self.default = default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def contribute_to_class(self, cls, attname):
 | 
				
			||||||
 | 
					        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)
 | 
				
			||||||
 | 
					        if isinstance(self.type, MountType):
 | 
				
			||||||
 | 
					            self.type.mount(cls)
 | 
				
			||||||
 | 
					        cls._meta.add_field(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def internal_type(self, schema):
 | 
				
			||||||
 | 
					        return GraphQLInputObjectField(
 | 
				
			||||||
 | 
					            schema.T(self.type),
 | 
				
			||||||
 | 
					            default_value=self.default, description=self.description)
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,11 @@ from functools import partial
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene import signals
 | 
					from graphene import signals
 | 
				
			||||||
 | 
					from graphene.core.exceptions import SkipField
 | 
				
			||||||
from graphene.core.options import Options
 | 
					from graphene.core.options import Options
 | 
				
			||||||
 | 
					from graphene.core.types.argument import ArgumentsGroup
 | 
				
			||||||
 | 
					from graphene.core.types.base import BaseType
 | 
				
			||||||
 | 
					from graphene.core.types.definitions import List, NonNull
 | 
				
			||||||
from graphql.core.type import (GraphQLArgument, GraphQLInputObjectType,
 | 
					from graphql.core.type import (GraphQLArgument, GraphQLInputObjectType,
 | 
				
			||||||
                               GraphQLInterfaceType, GraphQLObjectType)
 | 
					                               GraphQLInterfaceType, GraphQLObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,10 +54,6 @@ class ObjectTypeMeta(type):
 | 
				
			||||||
        assert not (
 | 
					        assert not (
 | 
				
			||||||
            new_class._meta.is_interface and new_class._meta.is_mutation)
 | 
					            new_class._meta.is_interface and new_class._meta.is_mutation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        input_class = None
 | 
					 | 
				
			||||||
        if new_class._meta.is_mutation:
 | 
					 | 
				
			||||||
            input_class = attrs.pop('Input', None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Add all attributes to the class.
 | 
					        # Add all attributes to the class.
 | 
				
			||||||
        for obj_name, obj in attrs.items():
 | 
					        for obj_name, obj in attrs.items():
 | 
				
			||||||
            new_class.add_to_class(obj_name, obj)
 | 
					            new_class.add_to_class(obj_name, obj)
 | 
				
			||||||
| 
						 | 
					@ -62,13 +62,6 @@ class ObjectTypeMeta(type):
 | 
				
			||||||
            assert hasattr(
 | 
					            assert hasattr(
 | 
				
			||||||
                new_class, 'mutate'), "All mutations must implement mutate method"
 | 
					                new_class, 'mutate'), "All mutations must implement mutate method"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if input_class:
 | 
					 | 
				
			||||||
            items = dict(input_class.__dict__)
 | 
					 | 
				
			||||||
            items.pop('__dict__', None)
 | 
					 | 
				
			||||||
            input_type = type('{}Input'.format(
 | 
					 | 
				
			||||||
                new_class._meta.type_name), (ObjectType, ), items)
 | 
					 | 
				
			||||||
            new_class.add_to_class('input_type', input_type)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        new_class.add_extra_fields()
 | 
					        new_class.add_extra_fields()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new_fields = new_class._meta.local_fields
 | 
					        new_fields = new_class._meta.local_fields
 | 
				
			||||||
| 
						 | 
					@ -87,7 +80,8 @@ class ObjectTypeMeta(type):
 | 
				
			||||||
            # on the base classes (we cannot handle shadowed fields at the
 | 
					            # on the base classes (we cannot handle shadowed fields at the
 | 
				
			||||||
            # moment).
 | 
					            # moment).
 | 
				
			||||||
            for field in parent_fields:
 | 
					            for field in parent_fields:
 | 
				
			||||||
                if field.name in field_names and field.__class__ != field_names[field.name].__class__:
 | 
					                if field.name in field_names and field.type.__class__ != field_names[
 | 
				
			||||||
 | 
					                        field.name].type.__class__:
 | 
				
			||||||
                    raise Exception(
 | 
					                    raise Exception(
 | 
				
			||||||
                        'Local field %r in class %r (%r) clashes '
 | 
					                        'Local field %r in class %r (%r) clashes '
 | 
				
			||||||
                        'with field with similar name from '
 | 
					                        'with field with similar name from '
 | 
				
			||||||
| 
						 | 
					@ -106,6 +100,9 @@ class ObjectTypeMeta(type):
 | 
				
			||||||
                new_class._meta.interfaces.append(base)
 | 
					                new_class._meta.interfaces.append(base)
 | 
				
			||||||
            # new_class._meta.parents.extend(base._meta.parents)
 | 
					            # new_class._meta.parents.extend(base._meta.parents)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        setattr(new_class, 'NonNull', NonNull(new_class))
 | 
				
			||||||
 | 
					        setattr(new_class, 'List', List(new_class))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new_class._prepare()
 | 
					        new_class._prepare()
 | 
				
			||||||
        return new_class
 | 
					        return new_class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,13 +116,14 @@ class ObjectTypeMeta(type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_to_class(cls, name, value):
 | 
					    def add_to_class(cls, name, value):
 | 
				
			||||||
        # We should call the contribute_to_class method only if it's bound
 | 
					        # We should call the contribute_to_class method only if it's bound
 | 
				
			||||||
        if not inspect.isclass(value) and hasattr(value, 'contribute_to_class'):
 | 
					        if not inspect.isclass(value) and hasattr(
 | 
				
			||||||
 | 
					                value, 'contribute_to_class'):
 | 
				
			||||||
            value.contribute_to_class(cls, name)
 | 
					            value.contribute_to_class(cls, name)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            setattr(cls, name, value)
 | 
					            setattr(cls, name, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseObjectType(object):
 | 
					class BaseObjectType(BaseType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __new__(cls, *args, **kwargs):
 | 
					    def __new__(cls, *args, **kwargs):
 | 
				
			||||||
        if cls._meta.is_interface:
 | 
					        if cls._meta.is_interface:
 | 
				
			||||||
| 
						 | 
					@ -165,13 +163,15 @@ class BaseObjectType(object):
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
            if kwargs:
 | 
					            if kwargs:
 | 
				
			||||||
                raise TypeError(
 | 
					                raise TypeError(
 | 
				
			||||||
                    "'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
 | 
					                    "'%s' is an invalid keyword argument for this function" %
 | 
				
			||||||
 | 
					                    list(kwargs)[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        signals.post_init.send(self.__class__, instance=self)
 | 
					        signals.post_init.send(self.__class__, instance=self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def fields_as_arguments(cls, schema):
 | 
					    def fields_as_arguments(cls, schema):
 | 
				
			||||||
        return OrderedDict([(f.attname, GraphQLArgument(f.internal_type(schema)))
 | 
					        return OrderedDict(
 | 
				
			||||||
 | 
					            [(f.attname, GraphQLArgument(f.internal_type(schema)))
 | 
				
			||||||
             for f in cls._meta.fields])
 | 
					             for f in cls._meta.fields])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -185,23 +185,32 @@ class BaseObjectType(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def internal_type(cls, schema):
 | 
					    def internal_type(cls, schema):
 | 
				
			||||||
        fields = lambda: OrderedDict([(f.name, f.internal_field(schema))
 | 
					 | 
				
			||||||
                                      for f in cls._meta.fields])
 | 
					 | 
				
			||||||
        if cls._meta.is_interface:
 | 
					        if cls._meta.is_interface:
 | 
				
			||||||
            return GraphQLInterfaceType(
 | 
					            return GraphQLInterfaceType(
 | 
				
			||||||
                cls._meta.type_name,
 | 
					                cls._meta.type_name,
 | 
				
			||||||
                description=cls._meta.description,
 | 
					                description=cls._meta.description,
 | 
				
			||||||
                resolve_type=partial(cls.resolve_type, schema),
 | 
					                resolve_type=partial(cls.resolve_type, schema),
 | 
				
			||||||
                fields=fields
 | 
					                fields=partial(cls.get_fields, schema)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        return GraphQLObjectType(
 | 
					        return GraphQLObjectType(
 | 
				
			||||||
            cls._meta.type_name,
 | 
					            cls._meta.type_name,
 | 
				
			||||||
            description=cls._meta.description,
 | 
					            description=cls._meta.description,
 | 
				
			||||||
            interfaces=[schema.T(i) for i in cls._meta.interfaces],
 | 
					            interfaces=[schema.T(i) for i in cls._meta.interfaces],
 | 
				
			||||||
            fields=fields,
 | 
					            fields=partial(cls.get_fields, schema),
 | 
				
			||||||
            is_type_of=getattr(cls, 'is_type_of', None)
 | 
					            is_type_of=getattr(cls, 'is_type_of', None)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def get_fields(cls, schema):
 | 
				
			||||||
 | 
					        fields = []
 | 
				
			||||||
 | 
					        for field in cls._meta.fields:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                fields.append((field.name, schema.T(field)))
 | 
				
			||||||
 | 
					            except SkipField:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return OrderedDict(fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
					class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
| 
						 | 
					@ -212,20 +221,33 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
					class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def _construct_arguments(cls, items):
 | 
				
			||||||
 | 
					        return ArgumentsGroup(**items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_input_type(cls):
 | 
					    def _prepare_class(cls):
 | 
				
			||||||
        return getattr(cls, 'input_type', None)
 | 
					        input_class = getattr(cls, 'Input', None)
 | 
				
			||||||
 | 
					        if input_class:
 | 
				
			||||||
 | 
					            items = dict(vars(input_class))
 | 
				
			||||||
 | 
					            items.pop('__dict__', None)
 | 
				
			||||||
 | 
					            items.pop('__doc__', None)
 | 
				
			||||||
 | 
					            items.pop('__module__', None)
 | 
				
			||||||
 | 
					            items.pop('__weakref__', None)
 | 
				
			||||||
 | 
					            cls.add_to_class('arguments', cls._construct_arguments(items))
 | 
				
			||||||
 | 
					            delattr(cls, 'Input')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def get_arguments(cls):
 | 
				
			||||||
 | 
					        return cls.arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InputObjectType(ObjectType):
 | 
					class InputObjectType(ObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def internal_type(cls, schema):
 | 
					    def internal_type(cls, schema):
 | 
				
			||||||
        fields = lambda: OrderedDict([(f.name, f.internal_field(schema))
 | 
					 | 
				
			||||||
                                      for f in cls._meta.fields])
 | 
					 | 
				
			||||||
        return GraphQLInputObjectType(
 | 
					        return GraphQLInputObjectType(
 | 
				
			||||||
            cls._meta.type_name,
 | 
					            cls._meta.type_name,
 | 
				
			||||||
            description=cls._meta.description,
 | 
					            description=cls._meta.description,
 | 
				
			||||||
            fields=fields,
 | 
					            fields=partial(cls.get_fields, schema),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
							
								
								
									
										41
									
								
								graphene/core/types/scalars.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								graphene/core/types/scalars.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					from graphql.core.type import (GraphQLBoolean, GraphQLFloat, GraphQLID,
 | 
				
			||||||
 | 
					                               GraphQLInt, GraphQLScalarType, GraphQLString)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .base import MountedType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class String(MountedType):
 | 
				
			||||||
 | 
					    T = GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Int(MountedType):
 | 
				
			||||||
 | 
					    T = GraphQLInt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Boolean(MountedType):
 | 
				
			||||||
 | 
					    T = GraphQLBoolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ID(MountedType):
 | 
				
			||||||
 | 
					    T = GraphQLID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Float(MountedType):
 | 
				
			||||||
 | 
					    T = GraphQLFloat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Scalar(MountedType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def internal_type(cls, schema):
 | 
				
			||||||
 | 
					        serialize = getattr(cls, 'serialize')
 | 
				
			||||||
 | 
					        parse_literal = getattr(cls, 'parse_literal')
 | 
				
			||||||
 | 
					        parse_value = getattr(cls, 'parse_value')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return GraphQLScalarType(
 | 
				
			||||||
 | 
					            name=cls.__name__,
 | 
				
			||||||
 | 
					            description=cls.__doc__,
 | 
				
			||||||
 | 
					            serialize=serialize,
 | 
				
			||||||
 | 
					            parse_value=parse_value,
 | 
				
			||||||
 | 
					            parse_literal=parse_literal
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
							
								
								
									
										0
									
								
								graphene/core/types/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								graphene/core/types/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										47
									
								
								graphene/core/types/tests/test_argument.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								graphene/core/types/tests/test_argument.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					from pytest import raises
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					from graphene.core.types import ObjectType
 | 
				
			||||||
 | 
					from graphql.core.type import GraphQLArgument
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..argument import Argument, to_arguments
 | 
				
			||||||
 | 
					from ..scalars import String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_argument_internal_type():
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    schema = Schema(query=MyObjectType)
 | 
				
			||||||
 | 
					    a = Argument(MyObjectType, description='My argument', default='3')
 | 
				
			||||||
 | 
					    type = schema.T(a)
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLArgument)
 | 
				
			||||||
 | 
					    assert type.description == 'My argument'
 | 
				
			||||||
 | 
					    assert type.default_value == '3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments():
 | 
				
			||||||
 | 
					    arguments = to_arguments(
 | 
				
			||||||
 | 
					        Argument(String, name='myArg'),
 | 
				
			||||||
 | 
					        String(name='otherArg'),
 | 
				
			||||||
 | 
					        my_kwarg=String(),
 | 
				
			||||||
 | 
					        other_kwarg=String(),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert [a.name for a in arguments] == [
 | 
				
			||||||
 | 
					        'myArg', 'otherArg', 'myKwarg', 'otherKwarg']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments_no_name():
 | 
				
			||||||
 | 
					    with raises(AssertionError) as excinfo:
 | 
				
			||||||
 | 
					        to_arguments(
 | 
				
			||||||
 | 
					            String(),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    assert 'must have a name' in str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_to_arguments_wrong_type():
 | 
				
			||||||
 | 
					    with raises(ValueError) as excinfo:
 | 
				
			||||||
 | 
					        to_arguments(
 | 
				
			||||||
 | 
					            p=3
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    assert 'Unknown argument p=3' == str(excinfo.value)
 | 
				
			||||||
							
								
								
									
										94
									
								
								graphene/core/types/tests/test_base.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								graphene/core/types/tests/test_base.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					from mock import patch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphene.core.types import InputObjectType, ObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..argument import Argument
 | 
				
			||||||
 | 
					from ..base import MountedType, OrderedType
 | 
				
			||||||
 | 
					from ..field import Field, InputField
 | 
				
			||||||
 | 
					from ..definitions import List, NonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_orderedtype_equal():
 | 
				
			||||||
 | 
					    a = OrderedType()
 | 
				
			||||||
 | 
					    assert a == a
 | 
				
			||||||
 | 
					    assert hash(a) == hash(a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_orderedtype_different():
 | 
				
			||||||
 | 
					    a = OrderedType()
 | 
				
			||||||
 | 
					    b = OrderedType()
 | 
				
			||||||
 | 
					    assert a != b
 | 
				
			||||||
 | 
					    assert hash(a) != hash(b)
 | 
				
			||||||
 | 
					    assert a < b
 | 
				
			||||||
 | 
					    assert b > a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@patch('graphene.core.types.field.Field')
 | 
				
			||||||
 | 
					def test_type_as_field_called(Field):
 | 
				
			||||||
 | 
					    resolver = lambda x: x
 | 
				
			||||||
 | 
					    a = MountedType(2, description='A', resolver=resolver)
 | 
				
			||||||
 | 
					    a.as_field()
 | 
				
			||||||
 | 
					    Field.assert_called_with(
 | 
				
			||||||
 | 
					        a,
 | 
				
			||||||
 | 
					        2,
 | 
				
			||||||
 | 
					        _creation_counter=a.creation_counter,
 | 
				
			||||||
 | 
					        description='A',
 | 
				
			||||||
 | 
					        resolver=resolver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@patch('graphene.core.types.argument.Argument')
 | 
				
			||||||
 | 
					def test_type_as_argument_called(Argument):
 | 
				
			||||||
 | 
					    a = MountedType(2, description='A')
 | 
				
			||||||
 | 
					    a.as_argument()
 | 
				
			||||||
 | 
					    Argument.assert_called_with(
 | 
				
			||||||
 | 
					        a, 2, _creation_counter=a.creation_counter, description='A')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_as_field():
 | 
				
			||||||
 | 
					    resolver = lambda x: x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        t = MountedType(description='A', resolver=resolver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fields_map = MyObjectType._meta.fields_map
 | 
				
			||||||
 | 
					    field = fields_map.get('t')
 | 
				
			||||||
 | 
					    assert isinstance(field, Field)
 | 
				
			||||||
 | 
					    assert field.description == 'A'
 | 
				
			||||||
 | 
					    assert field.object_type == MyObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_as_inputfield():
 | 
				
			||||||
 | 
					    class MyObjectType(InputObjectType):
 | 
				
			||||||
 | 
					        t = MountedType(description='A')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fields_map = MyObjectType._meta.fields_map
 | 
				
			||||||
 | 
					    field = fields_map.get('t')
 | 
				
			||||||
 | 
					    assert isinstance(field, InputField)
 | 
				
			||||||
 | 
					    assert field.description == 'A'
 | 
				
			||||||
 | 
					    assert field.object_type == MyObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_as_argument():
 | 
				
			||||||
 | 
					    a = MountedType(description='A')
 | 
				
			||||||
 | 
					    argument = a.as_argument()
 | 
				
			||||||
 | 
					    assert isinstance(argument, Argument)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_as_list():
 | 
				
			||||||
 | 
					    m = MountedType(2, 3, my_c='A')
 | 
				
			||||||
 | 
					    a = m.List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert isinstance(a, List)
 | 
				
			||||||
 | 
					    assert a.of_type == m
 | 
				
			||||||
 | 
					    assert a.args == (2, 3)
 | 
				
			||||||
 | 
					    assert a.kwargs == {'my_c': 'A'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_as_nonnull():
 | 
				
			||||||
 | 
					    m = MountedType(2, 3, my_c='A')
 | 
				
			||||||
 | 
					    a = m.NonNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert isinstance(a, NonNull)
 | 
				
			||||||
 | 
					    assert a.of_type == m
 | 
				
			||||||
 | 
					    assert a.args == (2, 3)
 | 
				
			||||||
 | 
					    assert a.kwargs == {'my_c': 'A'}
 | 
				
			||||||
							
								
								
									
										26
									
								
								graphene/core/types/tests/test_definitions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								graphene/core/types/tests/test_definitions.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					from graphql.core.type import GraphQLList, GraphQLNonNull, GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..definitions import List, NonNull
 | 
				
			||||||
 | 
					from ..scalars import String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_list_scalar():
 | 
				
			||||||
 | 
					    type = schema.T(List(String()))
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLList)
 | 
				
			||||||
 | 
					    assert type.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nonnull_scalar():
 | 
				
			||||||
 | 
					    type = schema.T(NonNull(String()))
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert type.of_type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_nested_scalars():
 | 
				
			||||||
 | 
					    type = schema.T(NonNull(List(String())))
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert isinstance(type.of_type, GraphQLList)
 | 
				
			||||||
 | 
					    assert type.of_type.of_type == GraphQLString
 | 
				
			||||||
							
								
								
									
										114
									
								
								graphene/core/types/tests/test_field.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								graphene/core/types/tests/test_field.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,114 @@
 | 
				
			||||||
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					from graphene.core.types import InputObjectType, ObjectType
 | 
				
			||||||
 | 
					from graphql.core.type import (GraphQLField, GraphQLInputObjectField,
 | 
				
			||||||
 | 
					                               GraphQLString)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..base import LazyType
 | 
				
			||||||
 | 
					from ..definitions import List
 | 
				
			||||||
 | 
					from ..field import Field, InputField
 | 
				
			||||||
 | 
					from ..scalars import String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_internal_type():
 | 
				
			||||||
 | 
					    resolver = lambda *args: 'RESOLVED'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    field = Field(String, description='My argument', resolver=resolver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Query(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					    schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    type = schema.T(field)
 | 
				
			||||||
 | 
					    assert field.name == 'myField'
 | 
				
			||||||
 | 
					    assert field.attname == 'my_field'
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLField)
 | 
				
			||||||
 | 
					    assert type.description == 'My argument'
 | 
				
			||||||
 | 
					    assert type.resolver(None, {}, None) == 'RESOLVED'
 | 
				
			||||||
 | 
					    assert type.type == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_objectype_resolver():
 | 
				
			||||||
 | 
					    field = Field(String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Query(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def resolve_my_field(self, *args, **kwargs):
 | 
				
			||||||
 | 
					            '''Custom description'''
 | 
				
			||||||
 | 
					            return 'RESOLVED'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    type = schema.T(field)
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLField)
 | 
				
			||||||
 | 
					    assert type.description == 'Custom description'
 | 
				
			||||||
 | 
					    assert type.resolver(Query(), {}, None) == 'RESOLVED'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_custom_name():
 | 
				
			||||||
 | 
					    field = Field(None, name='my_customName')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert field.name == 'my_customName'
 | 
				
			||||||
 | 
					    assert field.attname == 'my_field'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_self():
 | 
				
			||||||
 | 
					    field = Field('self', name='my_customName')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schema = Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert schema.T(field).type == schema.T(MyObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_mounted():
 | 
				
			||||||
 | 
					    field = Field(List('MyObjectType'), name='my_customName')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert field.parent == MyObjectType
 | 
				
			||||||
 | 
					    assert field.type.parent == MyObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_string_reference():
 | 
				
			||||||
 | 
					    field = Field('MyObjectType', name='my_customName')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(ObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schema = Schema(query=MyObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert isinstance(field.type, LazyType)
 | 
				
			||||||
 | 
					    assert schema.T(field.type) == schema.T(MyObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_field_custom_arguments():
 | 
				
			||||||
 | 
					    field = Field(None, name='my_customName', p=String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    args = field.arguments
 | 
				
			||||||
 | 
					    assert 'p' in args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_inputfield_internal_type():
 | 
				
			||||||
 | 
					    field = InputField(String, description='My input field', default='3')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyObjectType(InputObjectType):
 | 
				
			||||||
 | 
					        my_field = field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Query(ObjectType):
 | 
				
			||||||
 | 
					        input_ot = Field(MyObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    schema = Schema(query=MyObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    type = schema.T(field)
 | 
				
			||||||
 | 
					    assert field.name == 'myField'
 | 
				
			||||||
 | 
					    assert field.attname == 'my_field'
 | 
				
			||||||
 | 
					    assert isinstance(type, GraphQLInputObjectField)
 | 
				
			||||||
 | 
					    assert type.description == 'My input field'
 | 
				
			||||||
 | 
					    assert type.default_value == '3'
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,7 @@
 | 
				
			||||||
from py.test import raises
 | 
					from py.test import raises
 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.fields import IntField, StringField
 | 
					 | 
				
			||||||
from graphene.core.schema import Schema
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
from graphene.core.types import Interface
 | 
					from graphene.core.types import Int, Interface, String
 | 
				
			||||||
from graphql.core.execution.middlewares.utils import (resolver_has_tag,
 | 
					from graphql.core.execution.middlewares.utils import (resolver_has_tag,
 | 
				
			||||||
                                                      tag_resolver)
 | 
					                                                      tag_resolver)
 | 
				
			||||||
from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
 | 
					from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
 | 
				
			||||||
| 
						 | 
					@ -11,7 +9,7 @@ from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Character(Interface):
 | 
					class Character(Interface):
 | 
				
			||||||
    '''Character description'''
 | 
					    '''Character description'''
 | 
				
			||||||
    name = StringField()
 | 
					    name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        type_name = 'core_Character'
 | 
					        type_name = 'core_Character'
 | 
				
			||||||
| 
						 | 
					@ -19,7 +17,7 @@ class Character(Interface):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
    '''Human description'''
 | 
					    '''Human description'''
 | 
				
			||||||
    friends = StringField()
 | 
					    friends = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        type_name = 'core_Human'
 | 
					        type_name = 'core_Human'
 | 
				
			||||||
| 
						 | 
					@ -66,9 +64,6 @@ def test_object_type():
 | 
				
			||||||
    assert isinstance(object_type, GraphQLObjectType)
 | 
					    assert isinstance(object_type, GraphQLObjectType)
 | 
				
			||||||
    assert object_type.description == 'Human description'
 | 
					    assert object_type.description == 'Human description'
 | 
				
			||||||
    assert list(object_type.get_fields().keys()) == ['name', 'friends']
 | 
					    assert list(object_type.get_fields().keys()) == ['name', 'friends']
 | 
				
			||||||
    # assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
 | 
					 | 
				
			||||||
    # schema), 'friends':
 | 
					 | 
				
			||||||
    # Human._meta.fields_map['friends'].internal_field(schema)}
 | 
					 | 
				
			||||||
    assert object_type.get_interfaces() == [schema.T(Character)]
 | 
					    assert object_type.get_interfaces() == [schema.T(Character)]
 | 
				
			||||||
    assert Human._meta.fields_map['name'].object_type == Human
 | 
					    assert Human._meta.fields_map['name'].object_type == Human
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,7 +92,7 @@ def test_object_type_container_too_many_args():
 | 
				
			||||||
def test_field_clashes():
 | 
					def test_field_clashes():
 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
        class Droid(Character):
 | 
					        class Droid(Character):
 | 
				
			||||||
            name = IntField()
 | 
					            name = Int()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert 'clashes' in str(excinfo.value)
 | 
					    assert 'clashes' in str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,12 +103,26 @@ def test_fields_inherited_should_be_different():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_field_mantain_resolver_tags():
 | 
					def test_field_mantain_resolver_tags():
 | 
				
			||||||
    class Droid(Character):
 | 
					    class Droid(Character):
 | 
				
			||||||
        name = StringField()
 | 
					        name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def resolve_name(self, *args):
 | 
					        def resolve_name(self, *args):
 | 
				
			||||||
            return 'My Droid'
 | 
					            return 'My Droid'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tag_resolver(resolve_name, 'test')
 | 
					        tag_resolver(resolve_name, 'test')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    field = Droid._meta.fields_map['name'].internal_field(schema)
 | 
					    field = schema.T(Droid._meta.fields_map['name'])
 | 
				
			||||||
    assert resolver_has_tag(field.resolver, 'test')
 | 
					    assert resolver_has_tag(field.resolver, 'test')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_has_nonnull():
 | 
				
			||||||
 | 
					    class Droid(Character):
 | 
				
			||||||
 | 
					        name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert Droid.NonNull.of_type == Droid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_type_has_list():
 | 
				
			||||||
 | 
					    class Droid(Character):
 | 
				
			||||||
 | 
					        name = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert Droid.List.of_type == Droid
 | 
				
			||||||
							
								
								
									
										53
									
								
								graphene/core/types/tests/test_scalars.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								graphene/core/types/tests/test_scalars.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
 | 
					from graphql.core.type import (GraphQLBoolean, GraphQLFloat, GraphQLID,
 | 
				
			||||||
 | 
					                               GraphQLInt, GraphQLScalarType, GraphQLString)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..scalars import ID, Boolean, Float, Int, Scalar, String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_string_scalar():
 | 
				
			||||||
 | 
					    assert schema.T(String()) == GraphQLString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_int_scalar():
 | 
				
			||||||
 | 
					    assert schema.T(Int()) == GraphQLInt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_boolean_scalar():
 | 
				
			||||||
 | 
					    assert schema.T(Boolean()) == GraphQLBoolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_id_scalar():
 | 
				
			||||||
 | 
					    assert schema.T(ID()) == GraphQLID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_float_scalar():
 | 
				
			||||||
 | 
					    assert schema.T(Float()) == GraphQLFloat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_custom_scalar():
 | 
				
			||||||
 | 
					    import datetime
 | 
				
			||||||
 | 
					    from graphql.core.language import ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class DateTimeScalar(Scalar):
 | 
				
			||||||
 | 
					        '''DateTimeScalar Documentation'''
 | 
				
			||||||
 | 
					        @staticmethod
 | 
				
			||||||
 | 
					        def serialize(dt):
 | 
				
			||||||
 | 
					            return dt.isoformat()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @staticmethod
 | 
				
			||||||
 | 
					        def parse_literal(node):
 | 
				
			||||||
 | 
					            if isinstance(node, ast.StringValue):
 | 
				
			||||||
 | 
					                return datetime.datetime.strptime(
 | 
				
			||||||
 | 
					                    node.value, "%Y-%m-%dT%H:%M:%S.%f")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @staticmethod
 | 
				
			||||||
 | 
					        def parse_value(value):
 | 
				
			||||||
 | 
					            return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scalar_type = schema.T(DateTimeScalar)
 | 
				
			||||||
 | 
					    assert isinstance(scalar_type, GraphQLScalarType)
 | 
				
			||||||
 | 
					    assert scalar_type.name == 'DateTimeScalar'
 | 
				
			||||||
 | 
					    assert scalar_type.description == 'DateTimeScalar Documentation'
 | 
				
			||||||
| 
						 | 
					@ -1,40 +1,49 @@
 | 
				
			||||||
from collections import Iterable
 | 
					from collections import Iterable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from graphene.core.fields import Field, IDField
 | 
					from graphene.core.fields import Field
 | 
				
			||||||
from graphql.core.type import GraphQLArgument, GraphQLID, GraphQLNonNull
 | 
					from graphene.core.types.scalars import ID, Int, String
 | 
				
			||||||
from graphql_relay.connection.arrayconnection import connection_from_list
 | 
					from graphql_relay.connection.arrayconnection import connection_from_list
 | 
				
			||||||
from graphql_relay.connection.connection import connection_args
 | 
					 | 
				
			||||||
from graphql_relay.node.node import from_global_id
 | 
					from graphql_relay.node.node import from_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionField(Field):
 | 
					class ConnectionField(Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, field_type, resolve=None, description='',
 | 
					    def __init__(self, field_type, resolver=None, description='',
 | 
				
			||||||
                 connection_type=None, edge_type=None, **kwargs):
 | 
					                 connection_type=None, edge_type=None, **kwargs):
 | 
				
			||||||
        super(ConnectionField, self).__init__(field_type, resolve=resolve,
 | 
					        super(
 | 
				
			||||||
                                              args=connection_args,
 | 
					            ConnectionField,
 | 
				
			||||||
                                              description=description, **kwargs)
 | 
					            self).__init__(
 | 
				
			||||||
 | 
					            field_type,
 | 
				
			||||||
 | 
					            resolver=resolver,
 | 
				
			||||||
 | 
					            before=String(),
 | 
				
			||||||
 | 
					            after=String(),
 | 
				
			||||||
 | 
					            first=Int(),
 | 
				
			||||||
 | 
					            last=Int(),
 | 
				
			||||||
 | 
					            description=description,
 | 
				
			||||||
 | 
					            **kwargs)
 | 
				
			||||||
        self.connection_type = connection_type
 | 
					        self.connection_type = connection_type
 | 
				
			||||||
        self.edge_type = edge_type
 | 
					        self.edge_type = edge_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def wrap_resolved(self, value, instance, args, info):
 | 
					    def wrap_resolved(self, value, instance, args, info):
 | 
				
			||||||
        return value
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        from graphene.relay.types import PageInfo
 | 
					        from graphene.relay.types import PageInfo
 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					        schema = info.schema.graphene_schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resolved = super(ConnectionField, self).resolve(instance, args, info)
 | 
					        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
				
			||||||
        if resolved:
 | 
					        if resolved:
 | 
				
			||||||
            resolved = self.wrap_resolved(resolved, instance, args, info)
 | 
					            resolved = self.wrap_resolved(resolved, instance, args, info)
 | 
				
			||||||
            assert isinstance(
 | 
					            assert isinstance(
 | 
				
			||||||
                resolved, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
					                resolved, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            node = self.get_object_type(schema)
 | 
					            type = schema.T(self.type)
 | 
				
			||||||
 | 
					            node = schema.objecttype(type)
 | 
				
			||||||
            connection_type = self.get_connection_type(node)
 | 
					            connection_type = self.get_connection_type(node)
 | 
				
			||||||
            edge_type = self.get_edge_type(node)
 | 
					            edge_type = self.get_edge_type(node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            connection = connection_from_list(resolved, args, connection_type=connection_type,
 | 
					            connection = connection_from_list(
 | 
				
			||||||
 | 
					                resolved, args, connection_type=connection_type,
 | 
				
			||||||
                edge_type=edge_type, pageinfo_type=PageInfo)
 | 
					                edge_type=edge_type, pageinfo_type=PageInfo)
 | 
				
			||||||
            connection.set_connection_data(resolved)
 | 
					            connection.set_connection_data(resolved)
 | 
				
			||||||
            return connection
 | 
					            return connection
 | 
				
			||||||
| 
						 | 
					@ -47,25 +56,24 @@ class ConnectionField(Field):
 | 
				
			||||||
    def get_edge_type(self, node):
 | 
					    def get_edge_type(self, node):
 | 
				
			||||||
        return self.edge_type or node.get_edge_type()
 | 
					        return self.edge_type or node.get_edge_type()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def internal_type(self, schema):
 | 
					    def get_type(self, schema):
 | 
				
			||||||
        from graphene.relay.utils import is_node
 | 
					        from graphene.relay.utils import is_node
 | 
				
			||||||
        node = self.get_object_type(schema)
 | 
					        type = schema.T(self.type)
 | 
				
			||||||
 | 
					        node = schema.objecttype(type)
 | 
				
			||||||
        assert is_node(node), 'Only nodes have connections.'
 | 
					        assert is_node(node), 'Only nodes have connections.'
 | 
				
			||||||
        schema.register(node)
 | 
					        schema.register(node)
 | 
				
			||||||
        connection_type = self.get_connection_type(node)
 | 
					        connection_type = self.get_connection_type(node)
 | 
				
			||||||
        return schema.T(connection_type)
 | 
					        return connection_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NodeField(Field):
 | 
					class NodeField(Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, object_type=None, *args, **kwargs):
 | 
					    def __init__(self, object_type=None, *args, **kwargs):
 | 
				
			||||||
        from graphene.relay.types import Node
 | 
					        from graphene.relay.types import Node
 | 
				
			||||||
        super(NodeField, self).__init__(object_type or Node, *args, **kwargs)
 | 
					        id = kwargs.pop('id', None) or ID(description='The ID of an object')
 | 
				
			||||||
 | 
					        super(NodeField, self).__init__(
 | 
				
			||||||
 | 
					            object_type or Node, id=id, *args, **kwargs)
 | 
				
			||||||
        self.field_object_type = object_type
 | 
					        self.field_object_type = object_type
 | 
				
			||||||
        self.args['id'] = GraphQLArgument(
 | 
					 | 
				
			||||||
            GraphQLNonNull(GraphQLID),
 | 
					 | 
				
			||||||
            description='The ID of an object'
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def id_fetcher(self, global_id, info):
 | 
					    def id_fetcher(self, global_id, info):
 | 
				
			||||||
        from graphene.relay.utils import is_node
 | 
					        from graphene.relay.utils import is_node
 | 
				
			||||||
| 
						 | 
					@ -79,20 +87,23 @@ class NodeField(Field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return object_type.get_node(_id)
 | 
					        return object_type.get_node(_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        global_id = args.get('id')
 | 
					        global_id = args.get('id')
 | 
				
			||||||
        return self.id_fetcher(global_id, info)
 | 
					        return self.id_fetcher(global_id, info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GlobalIDField(IDField):
 | 
					class GlobalIDField(Field):
 | 
				
			||||||
    '''The ID of an object'''
 | 
					    '''The ID of an object'''
 | 
				
			||||||
    required = True
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def contribute_to_class(self, cls, name, add=True):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(GlobalIDField, self).__init__(ID(), *args, **kwargs)
 | 
				
			||||||
 | 
					        self.required = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def contribute_to_class(self, cls, name):
 | 
				
			||||||
        from graphene.relay.utils import is_node, is_node_type
 | 
					        from graphene.relay.utils import is_node, is_node_type
 | 
				
			||||||
        in_node = is_node(cls) or is_node_type(cls)
 | 
					        in_node = is_node(cls) or is_node_type(cls)
 | 
				
			||||||
        assert in_node, 'GlobalIDField could only be inside a Node, but got %r' % cls
 | 
					        assert in_node, 'GlobalIDField could only be inside a Node, but got %r' % cls
 | 
				
			||||||
        super(GlobalIDField, self).contribute_to_class(cls, name, add)
 | 
					        super(GlobalIDField, self).contribute_to_class(cls, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve(self, instance, args, info):
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        return self.object_type.to_global_id(instance, args, info)
 | 
					        return instance.to_global_id()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								graphene/relay/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								graphene/relay/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -1,22 +1,21 @@
 | 
				
			||||||
import graphene
 | 
					import graphene
 | 
				
			||||||
from graphene import relay
 | 
					from graphene import relay
 | 
				
			||||||
from graphene.core.schema import Schema
 | 
					from graphene.core.schema import Schema
 | 
				
			||||||
from graphene.core.types import InputObjectType
 | 
					 | 
				
			||||||
from graphql.core.type import GraphQLInputObjectField
 | 
					from graphql.core.type import GraphQLInputObjectField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
my_id = 0
 | 
					my_id = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
    base = graphene.StringField()
 | 
					    base = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ChangeNumber(relay.ClientIDMutation):
 | 
					class ChangeNumber(relay.ClientIDMutation):
 | 
				
			||||||
    '''Result mutation'''
 | 
					    '''Result mutation'''
 | 
				
			||||||
    class Input:
 | 
					    class Input:
 | 
				
			||||||
        to = graphene.IntField()
 | 
					        to = graphene.Int()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    result = graphene.StringField()
 | 
					    result = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def mutate_and_get_payload(cls, input, info):
 | 
					    def mutate_and_get_payload(cls, input, info):
 | 
				
			||||||
| 
						 | 
					@ -32,19 +31,18 @@ class MyResultMutation(graphene.ObjectType):
 | 
				
			||||||
schema = Schema(query=Query, mutation=MyResultMutation)
 | 
					schema = Schema(query=Query, mutation=MyResultMutation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_mutation_input():
 | 
					def test_mutation_arguments():
 | 
				
			||||||
    assert ChangeNumber.input_type
 | 
					    assert ChangeNumber.arguments
 | 
				
			||||||
    assert ChangeNumber.input_type._meta.type_name == 'ChangeNumberInput'
 | 
					    assert list(ChangeNumber.arguments) == ['input']
 | 
				
			||||||
    assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['input']
 | 
					    assert 'input' in ChangeNumber.arguments
 | 
				
			||||||
    _input = ChangeNumber.input_type._meta.fields_map['input']
 | 
					    inner_type = ChangeNumber.input_type
 | 
				
			||||||
    inner_type = _input.get_object_type(schema)
 | 
					 | 
				
			||||||
    client_mutation_id_field = inner_type._meta.fields_map[
 | 
					    client_mutation_id_field = inner_type._meta.fields_map[
 | 
				
			||||||
        'client_mutation_id']
 | 
					        'client_mutation_id']
 | 
				
			||||||
    assert issubclass(inner_type, InputObjectType)
 | 
					    assert issubclass(inner_type, graphene.InputObjectType)
 | 
				
			||||||
    assert isinstance(client_mutation_id_field, graphene.StringField)
 | 
					    assert isinstance(client_mutation_id_field.type, graphene.NonNull)
 | 
				
			||||||
 | 
					    assert isinstance(client_mutation_id_field.type.of_type, graphene.String)
 | 
				
			||||||
    assert client_mutation_id_field.object_type == inner_type
 | 
					    assert client_mutation_id_field.object_type == inner_type
 | 
				
			||||||
    assert isinstance(client_mutation_id_field.internal_field(
 | 
					    assert isinstance(schema.T(client_mutation_id_field), GraphQLInputObjectField)
 | 
				
			||||||
        schema), GraphQLInputObjectField)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_execute_mutations():
 | 
					def test_execute_mutations():
 | 
				
			||||||
| 
						 | 
					@ -6,22 +6,22 @@ schema = graphene.Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MyConnection(relay.Connection):
 | 
					class MyConnection(relay.Connection):
 | 
				
			||||||
    my_custom_field = graphene.StringField(
 | 
					    my_custom_field = graphene.String(
 | 
				
			||||||
        resolve=lambda instance, *_: 'Custom')
 | 
					        resolver=lambda instance, *_: 'Custom')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MyNode(relay.Node):
 | 
					class MyNode(relay.Node):
 | 
				
			||||||
    name = graphene.StringField()
 | 
					    name = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_node(cls, id):
 | 
					    def get_node(cls, id):
 | 
				
			||||||
        return MyNode(name='mo')
 | 
					        return MyNode(id=id, name='mo')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Query(graphene.ObjectType):
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
    my_node = relay.NodeField(MyNode)
 | 
					    my_node = relay.NodeField(MyNode)
 | 
				
			||||||
    all_my_nodes = relay.ConnectionField(
 | 
					    all_my_nodes = relay.ConnectionField(
 | 
				
			||||||
        MyNode, connection_type=MyConnection, customArg=graphene.Argument(graphene.String))
 | 
					        MyNode, connection_type=MyConnection, customArg=graphene.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolve_all_my_nodes(self, args, info):
 | 
					    def resolve_all_my_nodes(self, args, info):
 | 
				
			||||||
        custom_arg = args.get('customArg')
 | 
					        custom_arg = args.get('customArg')
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ def test_nodefield_query():
 | 
				
			||||||
    query = '''
 | 
					    query = '''
 | 
				
			||||||
    query RebelsShipsQuery {
 | 
					    query RebelsShipsQuery {
 | 
				
			||||||
      myNode(id:"TXlOb2RlOjE=") {
 | 
					      myNode(id:"TXlOb2RlOjE=") {
 | 
				
			||||||
 | 
					        id
 | 
				
			||||||
        name
 | 
					        name
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      allMyNodes (customArg:"1") {
 | 
					      allMyNodes (customArg:"1") {
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,7 @@ def test_nodefield_query():
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    expected = {
 | 
					    expected = {
 | 
				
			||||||
        'myNode': {
 | 
					        'myNode': {
 | 
				
			||||||
 | 
					            'id': 'TXlOb2RlOjE=',
 | 
				
			||||||
            'name': 'mo'
 | 
					            'name': 'mo'
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        'allMyNodes': {
 | 
					        'allMyNodes': {
 | 
				
			||||||
| 
						 | 
					@ -73,5 +75,6 @@ def test_nodefield_query():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_nodeidfield():
 | 
					def test_nodeidfield():
 | 
				
			||||||
    id_field = MyNode._meta.fields_map['id']
 | 
					    id_field = MyNode._meta.fields_map['id']
 | 
				
			||||||
    assert isinstance(id_field.internal_field(schema).type, GraphQLNonNull)
 | 
					    id_field_type = schema.T(id_field)
 | 
				
			||||||
    assert id_field.internal_field(schema).type.of_type == GraphQLID
 | 
					    assert isinstance(id_field_type.type, GraphQLNonNull)
 | 
				
			||||||
 | 
					    assert id_field_type.type.of_type == GraphQLID
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ schema = graphene.Schema()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OtherNode(relay.Node):
 | 
					class OtherNode(relay.Node):
 | 
				
			||||||
    name = graphene.StringField()
 | 
					    name = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_node(cls, id):
 | 
					    def get_node(cls, id):
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ class OtherNode(relay.Node):
 | 
				
			||||||
def test_field_no_contributed_raises_error():
 | 
					def test_field_no_contributed_raises_error():
 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					    with raises(Exception) as excinfo:
 | 
				
			||||||
        class Part(relay.Node):
 | 
					        class Part(relay.Node):
 | 
				
			||||||
            x = graphene.StringField()
 | 
					            x = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert 'get_node' in str(excinfo.value)
 | 
					    assert 'get_node' in str(excinfo.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,19 +1,23 @@
 | 
				
			||||||
from graphene.core.fields import BooleanField, Field, ListField, StringField
 | 
					from graphene.core.types import (Boolean, Field, InputObjectType, Interface,
 | 
				
			||||||
from graphene.core.types import (InputObjectType, Interface, Mutation,
 | 
					                                 List, Mutation, ObjectType, String)
 | 
				
			||||||
                                 ObjectType)
 | 
					from graphene.core.types.argument import ArgumentsGroup
 | 
				
			||||||
 | 
					from graphene.core.types.base import LazyType
 | 
				
			||||||
 | 
					from graphene.core.types.definitions import NonNull
 | 
				
			||||||
from graphene.relay.fields import GlobalIDField
 | 
					from graphene.relay.fields import GlobalIDField
 | 
				
			||||||
from graphene.utils import memoize
 | 
					from graphene.utils import memoize
 | 
				
			||||||
from graphql_relay.node.node import to_global_id
 | 
					from graphql_relay.node.node import to_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PageInfo(ObjectType):
 | 
					class PageInfo(ObjectType):
 | 
				
			||||||
    has_next_page = BooleanField(
 | 
					    has_next_page = Boolean(
 | 
				
			||||||
        required=True, description='When paginating forwards, are there more items?')
 | 
					        required=True,
 | 
				
			||||||
    has_previous_page = BooleanField(
 | 
					        description='When paginating forwards, are there more items?')
 | 
				
			||||||
        required=True, description='When paginating backwards, are there more items?')
 | 
					    has_previous_page = Boolean(
 | 
				
			||||||
    start_cursor = StringField(
 | 
					        required=True,
 | 
				
			||||||
 | 
					        description='When paginating backwards, are there more items?')
 | 
				
			||||||
 | 
					    start_cursor = String(
 | 
				
			||||||
        description='When paginating backwards, the cursor to continue.')
 | 
					        description='When paginating backwards, the cursor to continue.')
 | 
				
			||||||
    end_cursor = StringField(
 | 
					    end_cursor = String(
 | 
				
			||||||
        description='When paginating forwards, the cursor to continue.')
 | 
					        description='When paginating forwards, the cursor to continue.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +26,9 @@ class Edge(ObjectType):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        type_name = 'DefaultEdge'
 | 
					        type_name = 'DefaultEdge'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    node = Field(lambda field: field.object_type.node_type,
 | 
					    node = Field(LazyType(lambda object_type: object_type.node_type),
 | 
				
			||||||
                 description='The item at the end of the edge')
 | 
					                 description='The item at the end of the edge')
 | 
				
			||||||
    cursor = StringField(
 | 
					    cursor = String(
 | 
				
			||||||
        required=True, description='A cursor for use in pagination')
 | 
					        required=True, description='A cursor for use in pagination')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -32,7 +36,10 @@ class Edge(ObjectType):
 | 
				
			||||||
    def for_node(cls, node):
 | 
					    def for_node(cls, node):
 | 
				
			||||||
        from graphene.relay.utils import is_node
 | 
					        from graphene.relay.utils import is_node
 | 
				
			||||||
        assert is_node(node), 'ObjectTypes in a edge have to be Nodes'
 | 
					        assert is_node(node), 'ObjectTypes in a edge have to be Nodes'
 | 
				
			||||||
        return type('%s%s' % (node._meta.type_name, cls._meta.type_name), (cls, ), {'node_type': node})
 | 
					        return type(
 | 
				
			||||||
 | 
					            '%s%s' % (node._meta.type_name, cls._meta.type_name),
 | 
				
			||||||
 | 
					            (cls,),
 | 
				
			||||||
 | 
					            {'node_type': node})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Connection(ObjectType):
 | 
					class Connection(ObjectType):
 | 
				
			||||||
| 
						 | 
					@ -42,7 +49,7 @@ class Connection(ObjectType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    page_info = Field(PageInfo, required=True,
 | 
					    page_info = Field(PageInfo, required=True,
 | 
				
			||||||
                      description='The Information to aid in pagination')
 | 
					                      description='The Information to aid in pagination')
 | 
				
			||||||
    edges = ListField(lambda field: field.object_type.edge_type,
 | 
					    edges = List(LazyType(lambda object_type: object_type.edge_type),
 | 
				
			||||||
                 description='Information to aid in pagination.')
 | 
					                 description='Information to aid in pagination.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _connection_data = None
 | 
					    _connection_data = None
 | 
				
			||||||
| 
						 | 
					@ -53,7 +60,10 @@ class Connection(ObjectType):
 | 
				
			||||||
        from graphene.relay.utils import is_node
 | 
					        from graphene.relay.utils import is_node
 | 
				
			||||||
        edge_type = edge_type or Edge
 | 
					        edge_type = edge_type or Edge
 | 
				
			||||||
        assert is_node(node), 'ObjectTypes in a connection have to be Nodes'
 | 
					        assert is_node(node), 'ObjectTypes in a connection have to be Nodes'
 | 
				
			||||||
        return type('%s%s' % (node._meta.type_name, cls._meta.type_name), (cls, ), {'edge_type': edge_type.for_node(node)})
 | 
					        return type(
 | 
				
			||||||
 | 
					            '%s%s' % (node._meta.type_name, cls._meta.type_name),
 | 
				
			||||||
 | 
					            (cls,),
 | 
				
			||||||
 | 
					            {'edge_type': edge_type.for_node(node)})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_connection_data(self, data):
 | 
					    def set_connection_data(self, data):
 | 
				
			||||||
        self._connection_data = data
 | 
					        self._connection_data = data
 | 
				
			||||||
| 
						 | 
					@ -71,10 +81,9 @@ class BaseNode(object):
 | 
				
			||||||
            assert hasattr(
 | 
					            assert hasattr(
 | 
				
			||||||
                cls, 'get_node'), 'get_node classmethod not found in %s Node' % cls
 | 
					                cls, 'get_node'), 'get_node classmethod not found in %s Node' % cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    def to_global_id(self):
 | 
				
			||||||
    def to_global_id(cls, instance, args, info):
 | 
					        type_name = self._meta.type_name
 | 
				
			||||||
        type_name = cls._meta.type_name
 | 
					        return to_global_id(type_name, self.id)
 | 
				
			||||||
        return to_global_id(type_name, instance.id)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    connection_type = Connection
 | 
					    connection_type = Connection
 | 
				
			||||||
    edge_type = Edge
 | 
					    edge_type = Edge
 | 
				
			||||||
| 
						 | 
					@ -90,31 +99,24 @@ class BaseNode(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Node(BaseNode, Interface):
 | 
					class Node(BaseNode, Interface):
 | 
				
			||||||
    '''An object with an ID'''
 | 
					    '''An object with an ID'''
 | 
				
			||||||
    id = GlobalIDField()
 | 
					    id = GlobalIDField(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MutationInputType(InputObjectType):
 | 
					class MutationInputType(InputObjectType):
 | 
				
			||||||
    client_mutation_id = StringField(required=True)
 | 
					    client_mutation_id = String(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClientIDMutation(Mutation):
 | 
					class ClientIDMutation(Mutation):
 | 
				
			||||||
    client_mutation_id = StringField(required=True)
 | 
					    client_mutation_id = String(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def _prepare_class(cls):
 | 
					    def _construct_arguments(cls, items):
 | 
				
			||||||
        input_type = getattr(cls, 'input_type', None)
 | 
					 | 
				
			||||||
        if input_type:
 | 
					 | 
				
			||||||
        assert hasattr(
 | 
					        assert hasattr(
 | 
				
			||||||
            cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
 | 
					            cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
 | 
				
			||||||
            new_input_inner_type = type('{}InnerInput'.format(
 | 
					        new_input_type = type('{}Input'.format(
 | 
				
			||||||
                cls._meta.type_name), (MutationInputType, input_type, ), {})
 | 
					            cls._meta.type_name), (MutationInputType, ), items)
 | 
				
			||||||
            items = {
 | 
					        cls.add_to_class('input_type', new_input_type)
 | 
				
			||||||
                'input': Field(new_input_inner_type)
 | 
					        return ArgumentsGroup(input=NonNull(new_input_type))
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert issubclass(new_input_inner_type, InputObjectType)
 | 
					 | 
				
			||||||
            input_type = type('{}Input'.format(
 | 
					 | 
				
			||||||
                cls._meta.type_name), (ObjectType, ), items)
 | 
					 | 
				
			||||||
            setattr(cls, 'input_type', input_type)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def mutate(cls, instance, args, info):
 | 
					    def mutate(cls, instance, args, info):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,8 @@ from graphene.relay.types import BaseNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_node(object_type):
 | 
					def is_node(object_type):
 | 
				
			||||||
    return object_type and issubclass(object_type, BaseNode) and not is_node_type(object_type)
 | 
					    return object_type and issubclass(
 | 
				
			||||||
 | 
					        object_type, BaseNode) and not is_node_type(object_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_node_type(object_type):
 | 
					def is_node_type(object_type):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,10 @@ def test_proxy_snake_dict():
 | 
				
			||||||
    assert p.get('three_or_for') == 3
 | 
					    assert p.get('three_or_for') == 3
 | 
				
			||||||
    assert 'inside' in p
 | 
					    assert 'inside' in p
 | 
				
			||||||
    assert 'other_camel_case' in p['inside']
 | 
					    assert 'other_camel_case' in p['inside']
 | 
				
			||||||
    assert sorted(p.items()) == sorted(list([('inside', ProxySnakeDict({'other_camel_case': 3})),
 | 
					    assert sorted(
 | 
				
			||||||
 | 
					        p.items()) == sorted(
 | 
				
			||||||
 | 
					        list(
 | 
				
			||||||
 | 
					            [('inside', ProxySnakeDict({'other_camel_case': 3})),
 | 
				
			||||||
             ('none', None),
 | 
					             ('none', None),
 | 
				
			||||||
             ('three_or_for', 3),
 | 
					             ('three_or_for', 3),
 | 
				
			||||||
             ('two', 2),
 | 
					             ('two', 2),
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,6 @@
 | 
				
			||||||
[flake8]
 | 
					[flake8]
 | 
				
			||||||
exclude = tests/*,setup.py
 | 
					exclude = setup.py
 | 
				
			||||||
max-line-length = 160
 | 
					max-line-length = 120
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[coverage:run]
 | 
				
			||||||
 | 
					omit = core/ntypes/tests/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -62,6 +62,7 @@ setup(
 | 
				
			||||||
    tests_require=[
 | 
					    tests_require=[
 | 
				
			||||||
        'pytest>=2.7.2',
 | 
					        'pytest>=2.7.2',
 | 
				
			||||||
        'pytest-django',
 | 
					        'pytest-django',
 | 
				
			||||||
 | 
					        'mock',
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    extras_require={
 | 
					    extras_require={
 | 
				
			||||||
        'django': [
 | 
					        'django': [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,166 +0,0 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
from py.test import raises
 | 
					 | 
				
			||||||
from pytest import raises
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from graphene.core.fields import Field, NonNullField, StringField
 | 
					 | 
				
			||||||
from graphene.core.options import Options
 | 
					 | 
				
			||||||
from graphene.core.schema import Schema
 | 
					 | 
				
			||||||
from graphene.core.types import ObjectType
 | 
					 | 
				
			||||||
from graphql.core.type import (GraphQLBoolean, GraphQLField, GraphQLID,
 | 
					 | 
				
			||||||
                               GraphQLInt, GraphQLNonNull, GraphQLString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ObjectType(object):
 | 
					 | 
				
			||||||
    _meta = Options()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def resolve_customdoc(self, *args, **kwargs):
 | 
					 | 
				
			||||||
        '''Resolver documentation'''
 | 
					 | 
				
			||||||
        return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        return "ObjectType"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ot = ObjectType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
schema = Schema()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_no_contributed_raises_error():
 | 
					 | 
				
			||||||
    f = Field(GraphQLString)
 | 
					 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					 | 
				
			||||||
        f.internal_field(schema)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_type():
 | 
					 | 
				
			||||||
    f = Field(GraphQLString)
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert isinstance(f.internal_field(schema), GraphQLField)
 | 
					 | 
				
			||||||
    assert f.internal_type(schema) == GraphQLString
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_name_automatic_camelcase():
 | 
					 | 
				
			||||||
    f = Field(GraphQLString)
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert f.name == 'fieldName'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_name_use_name_if_exists():
 | 
					 | 
				
			||||||
    f = Field(GraphQLString, name='my_custom_name')
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert f.name == 'my_custom_name'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_stringfield_type():
 | 
					 | 
				
			||||||
    f = StringField()
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert f.internal_type(schema) == GraphQLString
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_nonnullfield_type():
 | 
					 | 
				
			||||||
    f = NonNullField(StringField())
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert isinstance(f.internal_type(schema), GraphQLNonNull)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_stringfield_type_required():
 | 
					 | 
				
			||||||
    f = StringField(required=True)
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert isinstance(f.internal_field(schema), GraphQLField)
 | 
					 | 
				
			||||||
    assert isinstance(f.internal_type(schema), GraphQLNonNull)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_resolve():
 | 
					 | 
				
			||||||
    f = StringField(required=True, resolve=lambda *args: 'RESOLVED')
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    field_type = f.internal_field(schema)
 | 
					 | 
				
			||||||
    assert 'RESOLVED' == field_type.resolver(ot, None, None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_resolve_type_custom():
 | 
					 | 
				
			||||||
    class MyCustomType(ObjectType):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class OtherType(ObjectType):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    s = Schema()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f = Field('MyCustomType')
 | 
					 | 
				
			||||||
    f.contribute_to_class(OtherType, 'field_name')
 | 
					 | 
				
			||||||
    field_type = f.get_object_type(s)
 | 
					 | 
				
			||||||
    assert field_type == MyCustomType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_resolve_type_custom():
 | 
					 | 
				
			||||||
    s = Schema()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    f = Field('self')
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    field_type = f.get_object_type(s)
 | 
					 | 
				
			||||||
    assert field_type == ot
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_orders():
 | 
					 | 
				
			||||||
    f1 = Field(None)
 | 
					 | 
				
			||||||
    f2 = Field(None)
 | 
					 | 
				
			||||||
    assert f1 < f2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_orders_wrong_type():
 | 
					 | 
				
			||||||
    field = Field(None)
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        assert not field < 1
 | 
					 | 
				
			||||||
    except TypeError:
 | 
					 | 
				
			||||||
        # Fix exception raising in Python3+
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_eq():
 | 
					 | 
				
			||||||
    f1 = Field(None)
 | 
					 | 
				
			||||||
    f2 = Field(None)
 | 
					 | 
				
			||||||
    assert f1 != f2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_eq_wrong_type():
 | 
					 | 
				
			||||||
    field = Field(None)
 | 
					 | 
				
			||||||
    assert field != 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_hash():
 | 
					 | 
				
			||||||
    f1 = Field(None)
 | 
					 | 
				
			||||||
    f2 = Field(None)
 | 
					 | 
				
			||||||
    assert hash(f1) != hash(f2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_none_type_raises_error():
 | 
					 | 
				
			||||||
    s = Schema()
 | 
					 | 
				
			||||||
    f = Field(None)
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    with raises(Exception) as excinfo:
 | 
					 | 
				
			||||||
        f.internal_field(s)
 | 
					 | 
				
			||||||
    assert str(
 | 
					 | 
				
			||||||
        excinfo.value) == "Internal type for field ObjectType.field_name is None"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_str():
 | 
					 | 
				
			||||||
    f = StringField()
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert str(f) == "ObjectType.field_name"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_repr():
 | 
					 | 
				
			||||||
    f = StringField()
 | 
					 | 
				
			||||||
    assert repr(f) == "<graphene.core.fields.StringField>"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_repr_contributed():
 | 
					 | 
				
			||||||
    f = StringField()
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'field_name')
 | 
					 | 
				
			||||||
    assert repr(f) == "<graphene.core.fields.StringField: field_name>"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_field_resolve_objecttype_cos():
 | 
					 | 
				
			||||||
    f = StringField()
 | 
					 | 
				
			||||||
    f.contribute_to_class(ot, 'customdoc')
 | 
					 | 
				
			||||||
    field = f.internal_field(schema)
 | 
					 | 
				
			||||||
    assert field.description == 'Resolver documentation'
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,16 +0,0 @@
 | 
				
			||||||
from graphene.core.scalars import GraphQLSkipField
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_skipfield_serialize():
 | 
					 | 
				
			||||||
    f = GraphQLSkipField
 | 
					 | 
				
			||||||
    assert f.serialize('a') is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_skipfield_parse_value():
 | 
					 | 
				
			||||||
    f = GraphQLSkipField
 | 
					 | 
				
			||||||
    assert f.parse_value('a') is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_skipfield_parse_literal():
 | 
					 | 
				
			||||||
    f = GraphQLSkipField
 | 
					 | 
				
			||||||
    assert f.parse_literal('a') is None
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ SECRET_KEY = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSTALLED_APPS = [
 | 
					INSTALLED_APPS = [
 | 
				
			||||||
    'examples.starwars_django',
 | 
					    'examples.starwars_django',
 | 
				
			||||||
    'tests.contrib_django',
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DATABASES = {
 | 
					DATABASES = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user