From d46e9578631ce2b324086e2238566e2920b66f40 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 31 Oct 2015 13:46:43 -0700 Subject: [PATCH] Improved syntax. Added autolinter. Added automatic flake8 checker in tests. Fixed #17 --- .travis.yml | 2 +- bin/autolinter | 4 ++ examples/starwars/schema.py | 4 +- examples/starwars/tests/test_query.py | 5 ++- examples/starwars_django/data.py | 2 +- examples/starwars_django/models.py | 1 + examples/starwars_django/schema.py | 27 +++++------- .../starwars_django/tests/test_connections.py | 4 +- .../starwars_django/tests/test_mutation.py | 3 +- .../tests/test_objectidentification.py | 4 +- examples/starwars_relay/data.py | 2 +- examples/starwars_relay/schema.py | 11 ++--- .../starwars_relay/tests/test_connections.py | 2 +- .../starwars_relay/tests/test_mutation.py | 2 +- .../tests/test_objectidentification.py | 2 +- graphene/contrib/django/converter.py | 31 ++++++------- graphene/contrib/django/fields.py | 13 +++--- graphene/contrib/django/options.py | 3 +- graphene/contrib/django/types.py | 8 ++-- graphene/contrib/django/utils.py | 2 +- graphene/contrib/django/views.py | 6 +-- graphene/core/fields.py | 29 ++++++------ graphene/core/options.py | 3 +- graphene/core/schema.py | 20 ++++----- graphene/core/types.py | 29 ++++++------ graphene/relay/__init__.py | 2 +- graphene/relay/fields.py | 24 +++------- graphene/relay/types.py | 44 ++++++++++++------- graphene/utils/lazymap.py | 1 + graphene/utils/misc.py | 4 +- setup.py | 2 +- tests/contrib_django/data.py | 2 +- tests/contrib_django/models.py | 1 + tests/contrib_django/test_converter.py | 21 ++++----- tests/contrib_django/test_schema.py | 12 +++-- tests/contrib_django/test_types.py | 31 ++++--------- tests/contrib_django/test_urls.py | 11 ++--- tests/contrib_django/test_views.py | 44 +++++++------------ tests/core/test_fields.py | 22 +++------- tests/core/test_mutations.py | 2 +- tests/core/test_options.py | 12 ++--- tests/core/test_query.py | 27 ++++-------- tests/core/test_scalars.py | 4 +- tests/core/test_schema.py | 31 +++++-------- tests/core/test_types.py | 25 ++++------- tests/relay/test_relay.py | 2 +- tests/relay/test_relay_mutations.py | 13 +++--- tests/relay/test_relayfields.py | 12 +++-- tests/utils/test_misc.py | 6 ++- tests/utils/test_proxy_snake_dict.py | 4 +- tests/utils/test_str_converter.py | 2 +- tox.ini | 11 ++++- 52 files changed, 254 insertions(+), 337 deletions(-) create mode 100755 bin/autolinter diff --git a/.travis.yml b/.travis.yml index 38d505e9..6e25621b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,6 @@ install: - python setup.py develop script: - py.test --cov=graphene -# - flake8 +- flake8 after_success: - coveralls diff --git a/bin/autolinter b/bin/autolinter new file mode 100755 index 00000000..47d2201c --- /dev/null +++ b/bin/autolinter @@ -0,0 +1,4 @@ +#!/bin/bash + +autoflake ./ -r --remove-unused-variables --remove-all-unused-imports --in-place +isort -rc . diff --git a/examples/starwars/schema.py b/examples/starwars/schema.py index 6e87c4d7..e6f113a8 100644 --- a/examples/starwars/schema.py +++ b/examples/starwars/schema.py @@ -1,8 +1,8 @@ -from graphql.core.type import GraphQLEnumValue import graphene from graphene import resolve_only_args +from graphql.core.type import GraphQLEnumValue -from .data import getHero, getHuman, getCharacter, getDroid +from .data import getCharacter, getDroid, getHero, getHuman Episode = graphene.Enum('Episode', dict( NEWHOPE=GraphQLEnumValue(4), diff --git a/examples/starwars/tests/test_query.py b/examples/starwars/tests/test_query.py index 5c5939e5..2284e67b 100644 --- a/examples/starwars/tests/test_query.py +++ b/examples/starwars/tests/test_query.py @@ -1,9 +1,10 @@ -from ..schema import Schema, Query -from graphql.core import graphql + from ..data import setup +from ..schema import Schema setup() + def test_hero_name_query(): query = ''' query HeroNameQuery { diff --git a/examples/starwars_django/data.py b/examples/starwars_django/data.py index 82e72efa..b464731f 100644 --- a/examples/starwars_django/data.py +++ b/examples/starwars_django/data.py @@ -1,4 +1,4 @@ -from .models import Ship, Faction, Character +from .models import Character, Faction, Ship def initialize(): diff --git a/examples/starwars_django/models.py b/examples/starwars_django/models.py index 10050c33..31d06fe5 100644 --- a/examples/starwars_django/models.py +++ b/examples/starwars_django/models.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + from django.db import models diff --git a/examples/starwars_django/schema.py b/examples/starwars_django/schema.py index 2f3f9e38..e7530ecf 100644 --- a/examples/starwars_django/schema.py +++ b/examples/starwars_django/schema.py @@ -1,24 +1,18 @@ import graphene -from graphene import resolve_only_args, relay -from graphene.contrib.django import ( - DjangoObjectType, - DjangoNode -) -from .models import ( - Ship as ShipModel, Faction as FactionModel, Character as CharacterModel) -from .data import ( - get_faction, - get_ship, - get_ships, - get_rebels, - get_empire, - create_ship -) +from graphene import relay, resolve_only_args +from graphene.contrib.django import DjangoNode, DjangoObjectType + +from .data import (create_ship, get_empire, get_faction, get_rebels, get_ship, + get_ships) +from .models import Character as CharacterModel +from .models import Faction as FactionModel +from .models import Ship as ShipModel schema = graphene.Schema(name='Starwars Django Relay Schema') class Ship(DjangoNode): + class Meta: model = ShipModel @@ -29,11 +23,13 @@ class Ship(DjangoNode): @schema.register class Character(DjangoObjectType): + class Meta: model = CharacterModel class Faction(DjangoNode): + class Meta: model = FactionModel @@ -43,6 +39,7 @@ class Faction(DjangoNode): class IntroduceShip(relay.ClientIDMutation): + class Input: ship_name = graphene.StringField(required=True) faction_id = graphene.StringField(required=True) diff --git a/examples/starwars_django/tests/test_connections.py b/examples/starwars_django/tests/test_connections.py index 64981752..fa760d45 100644 --- a/examples/starwars_django/tests/test_connections.py +++ b/examples/starwars_django/tests/test_connections.py @@ -1,9 +1,7 @@ import pytest -from graphql.core import graphql -from ..models import * -from ..schema import schema from ..data import initialize +from ..schema import schema pytestmark = pytest.mark.django_db diff --git a/examples/starwars_django/tests/test_mutation.py b/examples/starwars_django/tests/test_mutation.py index 1eb28e08..aa312ff5 100644 --- a/examples/starwars_django/tests/test_mutation.py +++ b/examples/starwars_django/tests/test_mutation.py @@ -1,6 +1,7 @@ import pytest -from ..schema import schema + from ..data import initialize +from ..schema import schema pytestmark = pytest.mark.django_db diff --git a/examples/starwars_django/tests/test_objectidentification.py b/examples/starwars_django/tests/test_objectidentification.py index 4e0cd84d..fad1958d 100644 --- a/examples/starwars_django/tests/test_objectidentification.py +++ b/examples/starwars_django/tests/test_objectidentification.py @@ -1,8 +1,6 @@ import pytest -from pytest import raises -from graphql.core import graphql -from ..data import initialize +from ..data import initialize from ..schema import schema pytestmark = pytest.mark.django_db diff --git a/examples/starwars_relay/data.py b/examples/starwars_relay/data.py index eb2b0ca2..cb451deb 100644 --- a/examples/starwars_relay/data.py +++ b/examples/starwars_relay/data.py @@ -3,7 +3,7 @@ data = {} def setup(): global data - + from .schema import Ship, Faction xwing = Ship( id='1', diff --git a/examples/starwars_relay/schema.py b/examples/starwars_relay/schema.py index 9fa19540..b5d07cbc 100644 --- a/examples/starwars_relay/schema.py +++ b/examples/starwars_relay/schema.py @@ -1,13 +1,7 @@ import graphene -from graphene import resolve_only_args, relay +from graphene import relay, resolve_only_args -from .data import ( - get_faction, - get_ship, - get_rebels, - get_empire, - create_ship, -) +from .data import create_ship, get_empire, get_faction, get_rebels, get_ship schema = graphene.Schema(name='Starwars Relay Schema') @@ -38,6 +32,7 @@ class Faction(relay.Node): class IntroduceShip(relay.ClientIDMutation): + class Input: ship_name = graphene.StringField(required=True) faction_id = graphene.StringField(required=True) diff --git a/examples/starwars_relay/tests/test_connections.py b/examples/starwars_relay/tests/test_connections.py index 72910940..17b6865f 100644 --- a/examples/starwars_relay/tests/test_connections.py +++ b/examples/starwars_relay/tests/test_connections.py @@ -1,5 +1,5 @@ -from ..schema import schema from ..data import setup +from ..schema import schema setup() diff --git a/examples/starwars_relay/tests/test_mutation.py b/examples/starwars_relay/tests/test_mutation.py index 02baab5c..762d4b8b 100644 --- a/examples/starwars_relay/tests/test_mutation.py +++ b/examples/starwars_relay/tests/test_mutation.py @@ -1,5 +1,5 @@ -from ..schema import schema from ..data import setup +from ..schema import schema setup() diff --git a/examples/starwars_relay/tests/test_objectidentification.py b/examples/starwars_relay/tests/test_objectidentification.py index 913fdc42..90783dba 100644 --- a/examples/starwars_relay/tests/test_objectidentification.py +++ b/examples/starwars_relay/tests/test_objectidentification.py @@ -1,5 +1,5 @@ -from ..schema import schema from ..data import setup +from ..schema import schema setup() diff --git a/graphene/contrib/django/converter.py b/graphene/contrib/django/converter.py index 61058145..b1ddc791 100644 --- a/graphene/contrib/django/converter.py +++ b/graphene/contrib/django/converter.py @@ -1,15 +1,10 @@ -from singledispatch import singledispatch from django.db import models +from singledispatch import singledispatch -from graphene.core.fields import ( - StringField, - IDField, - IntField, - BooleanField, - FloatField, - ListField -) -from graphene.contrib.django.fields import ConnectionOrListField, DjangoModelField +from graphene.contrib.django.fields import (ConnectionOrListField, + DjangoModelField) +from graphene.core.fields import (BooleanField, FloatField, IDField, IntField, + StringField) try: UUIDField = models.UUIDField @@ -32,12 +27,12 @@ def convert_django_field(field): @convert_django_field.register(models.SlugField) @convert_django_field.register(models.URLField) @convert_django_field.register(UUIDField) -def _(field): +def convert_field_to_string(field): return StringField(description=field.help_text) @convert_django_field.register(models.AutoField) -def _(field): +def convert_field_to_id(field): return IDField(description=field.help_text) @@ -46,34 +41,34 @@ def _(field): @convert_django_field.register(models.SmallIntegerField) @convert_django_field.register(models.BigIntegerField) @convert_django_field.register(models.IntegerField) -def _(field): +def convert_field_to_int(field): return IntField(description=field.help_text) @convert_django_field.register(models.BooleanField) -def _(field): +def convert_field_to_boolean(field): return BooleanField(description=field.help_text, required=True) @convert_django_field.register(models.NullBooleanField) -def _(field): +def convert_field_to_nullboolean(field): return BooleanField(description=field.help_text) @convert_django_field.register(models.DecimalField) @convert_django_field.register(models.FloatField) -def _(field): +def convert_field_to_float(field): return FloatField(description=field.help_text) @convert_django_field.register(models.ManyToManyField) @convert_django_field.register(models.ManyToOneRel) -def _(field): +def convert_field_to_list_or_connection(field): model_field = DjangoModelField(field.related_model) return ConnectionOrListField(model_field) @convert_django_field.register(models.OneToOneField) @convert_django_field.register(models.ForeignKey) -def _(field): +def convert_field_to_djangomodel(field): return DjangoModelField(field.related_model, description=field.help_text) diff --git a/graphene/contrib/django/fields.py b/graphene/contrib/django/fields.py index f9659a99..6ee0da4a 100644 --- a/graphene/contrib/django/fields.py +++ b/graphene/contrib/django/fields.py @@ -1,21 +1,18 @@ -from graphene.core.fields import ( - ListField -) from graphene import relay - -from graphene.core.fields import Field, LazyField - -from graphene.relay.utils import is_node from graphene.contrib.django.utils import get_type_for_model, lazy_map +from graphene.core.fields import Field, LazyField, ListField +from graphene.relay.utils import is_node class DjangoConnectionField(relay.ConnectionField): + def wrap_resolved(self, value, instance, args, info): schema = info.schema.graphene_schema return lazy_map(value, self.get_object_type(schema)) class LazyListField(ListField): + def resolve(self, instance, args, info): schema = info.schema.graphene_schema resolved = super(LazyListField, self).resolve(instance, args, info) @@ -23,6 +20,7 @@ class LazyListField(ListField): class ConnectionOrListField(LazyField): + def get_field(self, schema): model_field = self.field_type field_object_type = model_field.get_object_type(schema) @@ -35,6 +33,7 @@ class ConnectionOrListField(LazyField): class DjangoModelField(Field): + def __init__(self, model, *args, **kwargs): super(DjangoModelField, self).__init__(None, *args, **kwargs) self.model = model diff --git a/graphene/contrib/django/options.py b/graphene/contrib/django/options.py index 76d72180..9293af6e 100644 --- a/graphene/contrib/django/options.py +++ b/graphene/contrib/django/options.py @@ -1,9 +1,10 @@ import inspect + from django.db import models from graphene.core.options import Options -from graphene.relay.utils import is_node from graphene.relay.types import Node +from graphene.relay.utils import is_node VALID_ATTRS = ('model', 'only_fields', 'exclude_fields') diff --git a/graphene/contrib/django/types.py b/graphene/contrib/django/types.py index 7675fdaa..b787f69b 100644 --- a/graphene/contrib/django/types.py +++ b/graphene/contrib/django/types.py @@ -1,12 +1,11 @@ import six -from graphene.core.types import ObjectTypeMeta, BaseObjectType -from graphene.contrib.django.options import DjangoOptions from graphene.contrib.django.converter import convert_django_field +from graphene.contrib.django.options import DjangoOptions from graphene.contrib.django.utils import get_reverse_fields - -from graphene.relay.types import BaseNode +from graphene.core.types import BaseObjectType, ObjectTypeMeta from graphene.relay.fields import GlobalIDField +from graphene.relay.types import BaseNode class DjangoObjectTypeMeta(ObjectTypeMeta): @@ -38,6 +37,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta): class InstanceObjectType(BaseObjectType): + def __init__(self, instance=None): self.instance = instance super(InstanceObjectType, self).__init__() diff --git a/graphene/contrib/django/utils.py b/graphene/contrib/django/utils.py index ad9c9c61..4a94741e 100644 --- a/graphene/contrib/django/utils.py +++ b/graphene/contrib/django/utils.py @@ -1,6 +1,6 @@ from django.db import models -from django.db.models.query import QuerySet from django.db.models.manager import Manager +from django.db.models.query import QuerySet from graphene.utils import LazyMap diff --git a/graphene/contrib/django/views.py b/graphene/contrib/django/views.py index 54e3ddc0..22a809a2 100644 --- a/graphene/contrib/django/views.py +++ b/graphene/contrib/django/views.py @@ -1,8 +1,8 @@ import json +from django.conf import settings from django.http import HttpResponse from django.views.generic import View -from django.conf import settings from graphql.core.error import GraphQLError, format_error @@ -26,8 +26,8 @@ class GraphQLView(View): def response_errors(self, *errors): errors = [{ - "message": str(e) - } for e in errors] + "message": str(e) + } for e in errors] return HttpResponse(json.dumps({'errors': errors}), content_type='application/json') def execute_query(self, request, query, *args, **kwargs): diff --git a/graphene/core/fields.py b/graphene/core/fields.py index f00105e5..4a8667fd 100644 --- a/graphene/core/fields.py +++ b/graphene/core/fields.py @@ -1,26 +1,21 @@ import inspect +from functools import total_ordering, wraps + import six + +from graphene.core.scalars import GraphQLSkipField +from graphene.core.types import BaseObjectType, InputObjectType +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 -from functools import total_ordering, wraps -from graphql.core.type import ( - GraphQLField, - GraphQLList, - GraphQLNonNull, - GraphQLInt, - GraphQLString, - GraphQLBoolean, - GraphQLID, - GraphQLArgument, - GraphQLFloat, - GraphQLInputObjectField, -) -from graphene.utils import to_camel_case, ProxySnakeDict, enum_to_graphql_enum -from graphene.core.types import BaseObjectType, InputObjectType -from graphene.core.scalars import GraphQLSkipField class Empty(object): @@ -252,10 +247,12 @@ class FloatField(TypeField): class ListField(Field): + def type_wrapper(self, field_type): return GraphQLList(field_type) class NonNullField(Field): + def type_wrapper(self, field_type): return GraphQLNonNull(field_type) diff --git a/graphene/core/options.py b/graphene/core/options.py index 2d93843d..132d61ce 100644 --- a/graphene/core/options.py +++ b/graphene/core/options.py @@ -1,5 +1,6 @@ +from collections import OrderedDict + from graphene.utils import cached_property -from collections import OrderedDict, namedtuple DEFAULT_NAMES = ('description', 'name', 'is_interface', 'is_mutation', 'type_name', 'interfaces', 'proxy') diff --git a/graphene/core/schema.py b/graphene/core/schema.py index f4a1b000..45733f93 100644 --- a/graphene/core/schema.py +++ b/graphene/core/schema.py @@ -1,19 +1,16 @@ -from functools import wraps from collections import OrderedDict +from functools import wraps -from graphql.core.type import ( - GraphQLSchema as _GraphQLSchema -) - -from graphql.core.execution.executor import Executor -from graphql.core.execution.middlewares.sync import SynchronousExecutionMiddleware - -from graphql.core.utils.introspection_query import introspection_query from graphene import signals -from graphene.utils import cached_property +from graphql.core.execution.executor import Executor +from graphql.core.execution.middlewares.sync import \ + SynchronousExecutionMiddleware +from graphql.core.type import GraphQLSchema as _GraphQLSchema +from graphql.core.utils.introspection_query import introspection_query class GraphQLSchema(_GraphQLSchema): + def __init__(self, schema, *args, **kwargs): self.graphene_schema = schema super(GraphQLSchema, self).__init__(*args, **kwargs) @@ -61,7 +58,8 @@ class Schema(object): @property def executor(self): if not self._executor: - self.executor = Executor([SynchronousExecutionMiddleware()], map_type=OrderedDict) + self.executor = Executor( + [SynchronousExecutionMiddleware()], map_type=OrderedDict) return self._executor @executor.setter diff --git a/graphene/core/types.py b/graphene/core/types.py index aeee813a..49c617fa 100644 --- a/graphene/core/types.py +++ b/graphene/core/types.py @@ -1,19 +1,14 @@ -import inspect -import six import copy +import inspect from collections import OrderedDict -from graphql.core.type import ( - GraphQLObjectType, - GraphQLInputObjectType, - GraphQLInterfaceType, - GraphQLArgument -) +import six from graphene import signals from graphene.core.options import Options -from graphene.utils import memoize from graphene.core.schema import register_internal_type +from graphql.core.type import (GraphQLArgument, GraphQLInputObjectType, + GraphQLInterfaceType, GraphQLObjectType) class ObjectTypeMeta(type): @@ -45,14 +40,15 @@ class ObjectTypeMeta(type): else: meta = attr_meta - base_meta = getattr(new_class, '_meta', None) + getattr(new_class, '_meta', None) new_class.add_to_class('_meta', new_class.options_cls(meta)) new_class._meta.is_interface = new_class.is_interface(parents) new_class._meta.is_mutation = new_class.is_mutation(parents) - assert not (new_class._meta.is_interface and new_class._meta.is_mutation) + assert not ( + new_class._meta.is_interface and new_class._meta.is_mutation) input_class = None if new_class._meta.is_mutation: @@ -63,12 +59,14 @@ class ObjectTypeMeta(type): new_class.add_to_class(obj_name, obj) if new_class._meta.is_mutation: - assert hasattr(new_class, 'mutate'), "All mutations must implement mutate method" + assert hasattr( + 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) + 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() @@ -166,7 +164,8 @@ class BaseObjectType(object): except AttributeError: pass if kwargs: - raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0]) + raise TypeError( + "'%s' is an invalid keyword argument for this function" % list(kwargs)[0]) signals.post_init.send(self.__class__, instance=self) @@ -215,12 +214,14 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, BaseObjectType)): class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)): + @classmethod def get_input_type(cls): return getattr(cls, 'input_type', None) class InputObjectType(ObjectType): + @classmethod @register_internal_type def internal_type(cls, schema): diff --git a/graphene/relay/__init__.py b/graphene/relay/__init__.py index ccfe86f2..0ad18b57 100644 --- a/graphene/relay/__init__.py +++ b/graphene/relay/__init__.py @@ -15,4 +15,4 @@ from graphene.relay.types import ( from graphene.relay.utils import is_node __all__ = ['ConnectionField', 'NodeField', 'GlobalIDField', 'Node', - 'PageInfo', 'Edge', 'Connection', 'is_node'] + 'PageInfo', 'Edge', 'Connection', 'ClientIDMutation', 'is_node'] diff --git a/graphene/relay/fields.py b/graphene/relay/fields.py index 8d115d83..7efa30d8 100644 --- a/graphene/relay/fields.py +++ b/graphene/relay/fields.py @@ -1,21 +1,10 @@ -from collections import Iterable, OrderedDict - -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.core.type import ( - GraphQLNonNull, - GraphQLID, - GraphQLArgument, -) +from collections import Iterable from graphene.core.fields import Field, IDField +from graphql.core.type import GraphQLArgument, GraphQLID, GraphQLNonNull +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 class ConnectionField(Field): @@ -68,6 +57,7 @@ class ConnectionField(Field): class NodeField(Field): + def __init__(self, object_type=None, *args, **kwargs): from graphene.relay.types import Node super(NodeField, self).__init__(object_type or Node, *args, **kwargs) @@ -84,7 +74,7 @@ class NodeField(Field): _type, _id = resolved_global_id.type, resolved_global_id.id object_type = schema.get_type(_type) if not is_node(object_type) or (self.field_object_type and - object_type != self.field_object_type): + object_type != self.field_object_type): return return object_type.get_node(_id) diff --git a/graphene/relay/types.py b/graphene/relay/types.py index 3b3177e4..748db640 100644 --- a/graphene/relay/types.py +++ b/graphene/relay/types.py @@ -1,18 +1,20 @@ -from graphql_relay.node.node import ( - to_global_id -) - -from graphene.core.types import Interface, ObjectType, Mutation, InputObjectType -from graphene.core.fields import BooleanField, StringField, ListField, Field +from graphene.core.fields import BooleanField, Field, ListField, StringField +from graphene.core.types import (InputObjectType, Interface, Mutation, + ObjectType) from graphene.relay.fields import GlobalIDField from graphene.utils import memoize +from graphql_relay.node.node import to_global_id class PageInfo(ObjectType): - has_next_page = BooleanField(required=True, description='When paginating forwards, are there more items?') - has_previous_page = BooleanField(required=True, description='When paginating backwards, are there more items?') - start_cursor = StringField(description='When paginating backwards, the cursor to continue.') - end_cursor = StringField(description='When paginating forwards, the cursor to continue.') + has_next_page = BooleanField( + required=True, description='When paginating forwards, are there more items?') + has_previous_page = BooleanField( + required=True, description='When paginating backwards, are there more items?') + start_cursor = StringField( + description='When paginating backwards, the cursor to continue.') + end_cursor = StringField( + description='When paginating forwards, the cursor to continue.') class Edge(ObjectType): @@ -20,8 +22,10 @@ class Edge(ObjectType): class Meta: type_name = 'DefaultEdge' - node = Field(lambda field: field.object_type.node_type, description='The item at the end of the edge') - cursor = StringField(required=True, description='A cursor for use in pagination') + node = Field(lambda field: field.object_type.node_type, + description='The item at the end of the edge') + cursor = StringField( + required=True, description='A cursor for use in pagination') @classmethod @memoize @@ -36,8 +40,10 @@ class Connection(ObjectType): class Meta: type_name = 'DefaultConnection' - page_info = Field(PageInfo, required=True, description='The Information to aid in pagination') - edges = ListField(lambda field: field.object_type.edge_type, description='Information to aid in pagination.') + page_info = Field(PageInfo, required=True, + description='The Information to aid in pagination') + edges = ListField(lambda field: field.object_type.edge_type, + description='Information to aid in pagination.') _connection_data = None @@ -57,6 +63,7 @@ class Connection(ObjectType): class BaseNode(object): + @classmethod def _prepare_class(cls): from graphene.relay.utils import is_node @@ -97,13 +104,16 @@ class ClientIDMutation(Mutation): def _prepare_class(cls): input_type = getattr(cls, 'input_type', None) if input_type: - assert hasattr(cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload' - new_input_inner_type = type('{}InnerInput'.format(cls._meta.type_name), (MutationInputType, input_type, ), {}) + assert hasattr( + cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload' + new_input_inner_type = type('{}InnerInput'.format( + cls._meta.type_name), (MutationInputType, input_type, ), {}) items = { 'input': Field(new_input_inner_type) } assert issubclass(new_input_inner_type, InputObjectType) - input_type = type('{}Input'.format(cls._meta.type_name), (ObjectType, ), items) + input_type = type('{}Input'.format( + cls._meta.type_name), (ObjectType, ), items) setattr(cls, 'input_type', input_type) @classmethod diff --git a/graphene/utils/lazymap.py b/graphene/utils/lazymap.py index 9c873619..237080c4 100644 --- a/graphene/utils/lazymap.py +++ b/graphene/utils/lazymap.py @@ -1,4 +1,5 @@ class LazyMap(object): + def __init__(self, origin, _map, state=None): self._origin = origin self._origin_iter = origin.__iter__() diff --git a/graphene/utils/misc.py b/graphene/utils/misc.py index b0dee69d..e7d1cc07 100644 --- a/graphene/utils/misc.py +++ b/graphene/utils/misc.py @@ -1,10 +1,12 @@ from collections import OrderedDict + from graphql.core.type import GraphQLEnumType, GraphQLEnumValue def enum_to_graphql_enum(enumeration): return GraphQLEnumType( name=enumeration.__name__, - values=OrderedDict([(it.name, GraphQLEnumValue(it.value)) for it in enumeration]), + values=OrderedDict([(it.name, GraphQLEnumValue(it.value)) + for it in enumeration]), description=enumeration.__doc__ ) diff --git a/setup.py b/setup.py index 924c4092..c3ab220b 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ import sys -from setuptools import setup, find_packages +from setuptools import find_packages, setup from setuptools.command.test import test as TestCommand diff --git a/tests/contrib_django/data.py b/tests/contrib_django/data.py index a9fa13f5..c5edbb06 100644 --- a/tests/contrib_django/data.py +++ b/tests/contrib_django/data.py @@ -1,6 +1,6 @@ from datetime import date -from .models import Reporter, Article +from .models import Article, Reporter r = Reporter(first_name='John', last_name='Smith', email='john@example.com') r.save() diff --git a/tests/contrib_django/models.py b/tests/contrib_django/models.py index 72ed0821..172352e4 100644 --- a/tests/contrib_django/models.py +++ b/tests/contrib_django/models.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + from django.db import models diff --git a/tests/contrib_django/test_converter.py b/tests/contrib_django/test_converter.py index 8c046997..217849ab 100644 --- a/tests/contrib_django/test_converter.py +++ b/tests/contrib_django/test_converter.py @@ -1,16 +1,13 @@ -from py.test import raises -from collections import namedtuple -from pytest import raises -import graphene -from graphene import relay -from graphene.contrib.django.converter import ( - convert_django_field -) -from graphene.contrib.django.fields import ( - ConnectionOrListField, - DjangoModelField -) + from django.db import models +from py.test import raises +from pytest import raises + +import graphene +from graphene.contrib.django.converter import convert_django_field +from graphene.contrib.django.fields import (ConnectionOrListField, + DjangoModelField) + from .models import Article, Reporter diff --git a/tests/contrib_django/test_schema.py b/tests/contrib_django/test_schema.py index 830aa2e7..a02cf81c 100644 --- a/tests/contrib_django/test_schema.py +++ b/tests/contrib_django/test_schema.py @@ -1,16 +1,14 @@ + from py.test import raises -from collections import namedtuple from pytest import raises + import graphene from graphene import relay -from graphene.contrib.django import ( - DjangoObjectType, - DjangoNode -) -from .models import Reporter, Article - +from graphene.contrib.django import DjangoNode, DjangoObjectType from tests.utils import assert_equal_lists +from .models import Article, Reporter + def test_should_raise_if_no_model(): with raises(Exception) as excinfo: diff --git a/tests/contrib_django/test_types.py b/tests/contrib_django/test_types.py index 6ef741fd..94472745 100644 --- a/tests/contrib_django/test_types.py +++ b/tests/contrib_django/test_types.py @@ -1,29 +1,14 @@ -from py.test import raises -from collections import namedtuple -from pytest import raises -from graphene.relay.fields import ( - GlobalIDField -) -from graphene.core.fields import ( - Field, - StringField, - IntField -) -from graphql.core.type import ( - GraphQLObjectType, - GraphQLInterfaceType -) + from graphene import Schema -from graphene.contrib.django.types import ( - DjangoNode, - DjangoInterface -) - -from .models import Reporter, Article - +from graphene.contrib.django.types import DjangoInterface, DjangoNode +from graphene.core.fields import IntField +from graphene.relay.fields import GlobalIDField +from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType from tests.utils import assert_equal_lists +from .models import Article, Reporter + class Character(DjangoInterface): '''Character description''' @@ -82,7 +67,7 @@ def test_interface_resolve_type(): def test_object_type(): object_type = schema.T(Human) - fields_map = Human._meta.fields_map + Human._meta.fields_map assert Human._meta.is_interface is False assert isinstance(object_type, GraphQLObjectType) assert_equal_lists( diff --git a/tests/contrib_django/test_urls.py b/tests/contrib_django/test_urls.py index 6b95105c..2f0801ee 100644 --- a/tests/contrib_django/test_urls.py +++ b/tests/contrib_django/test_urls.py @@ -1,18 +1,15 @@ from django.conf.urls import url -from graphene.contrib.django.views import GraphQLView - import graphene from graphene import Schema -from graphene.contrib.django.types import ( - DjangoNode, - DjangoInterface -) +from graphene.contrib.django.types import DjangoNode +from graphene.contrib.django.views import GraphQLView -from .models import Reporter, Article +from .models import Article, Reporter class Character(DjangoNode): + class Meta: model = Reporter diff --git a/tests/contrib_django/test_views.py b/tests/contrib_django/test_views.py index 435bcdf8..c04e8b6a 100644 --- a/tests/contrib_django/test_views.py +++ b/tests/contrib_django/test_views.py @@ -1,22 +1,4 @@ import json -import pytest -from py.test import raises -from collections import namedtuple -from pytest import raises -from graphene.core.fields import ( - Field, - StringField, -) -from graphql.core.type import ( - GraphQLObjectType, - GraphQLInterfaceType -) - -from graphene import Schema -from graphene.contrib.django.types import ( - DjangoNode, - DjangoInterface -) def format_response(response): @@ -27,33 +9,39 @@ def test_client_get_no_query(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' response = client.get('/graphql') json_response = format_response(response) - assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + assert json_response == {'errors': [ + {'message': 'Must provide query string.'}]} def test_client_post_no_query(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' response = client.post('/graphql', {}) json_response = format_response(response) - assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + assert json_response == {'errors': [ + {'message': 'Must provide query string.'}]} def test_client_post_malformed_json(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' response = client.post('/graphql', 'MALFORMED', 'application/json') json_response = format_response(response) - assert json_response == {'errors': [{'message': 'Malformed json body in the post data'}]} + assert json_response == {'errors': [ + {'message': 'Malformed json body in the post data'}]} def test_client_post_empty_query(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' - response = client.post('/graphql', json.dumps({'query': ''}), 'application/json') + response = client.post( + '/graphql', json.dumps({'query': ''}), 'application/json') json_response = format_response(response) - assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + assert json_response == {'errors': [ + {'message': 'Must provide query string.'}]} def test_client_post_bad_query(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' - response = client.post('/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json') + response = client.post( + '/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json') json_response = format_response(response) assert 'errors' in json_response assert len(json_response['errors']) == 1 @@ -76,13 +64,15 @@ def test_client_get_good_query_with_raise(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' response = client.get('/graphql', {'query': '{ raises }'}) json_response = format_response(response) - assert json_response['errors'][0]['message'] == 'This field should raise exception' + assert json_response['errors'][0][ + 'message'] == 'This field should raise exception' assert json_response['data']['raises'] is None def test_client_post_good_query(settings, client): settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' - response = client.post('/graphql', json.dumps({'query': '{ headline }'}), 'application/json') + response = client.post( + '/graphql', json.dumps({'query': '{ headline }'}), 'application/json') json_response = format_response(response) expected_json = { 'data': { @@ -97,5 +87,3 @@ def test_client_post_good_query(settings, client): # response = client.get('/graphql') # json_response = format_response(response) # assert json_response == {'errors': [{'message': 'Must provide query string.'}]} - - diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py index 028fba99..be565dd2 100644 --- a/tests/core/test_fields.py +++ b/tests/core/test_fields.py @@ -1,24 +1,13 @@ + from py.test import raises -from collections import namedtuple from pytest import raises -from graphql.core.type import ( - GraphQLField, - GraphQLNonNull, - GraphQLInt, - GraphQLString, - GraphQLBoolean, - GraphQLID, -) - -from graphene.core.fields import ( - Field, - StringField, - NonNullField -) +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): @@ -149,7 +138,8 @@ def test_field_none_type_raises_error(): 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" + assert str( + excinfo.value) == "Internal type for field ObjectType.field_name is None" def test_field_str(): diff --git a/tests/core/test_mutations.py b/tests/core/test_mutations.py index ad87a228..859e0444 100644 --- a/tests/core/test_mutations.py +++ b/tests/core/test_mutations.py @@ -1,5 +1,5 @@ + import graphene -from py.test import raises from graphene.core.schema import Schema my_id = 0 diff --git a/tests/core/test_options.py b/tests/core/test_options.py index 14a04402..04586afe 100644 --- a/tests/core/test_options.py +++ b/tests/core/test_options.py @@ -1,11 +1,8 @@ -from py.test import raises -from collections import namedtuple -from pytest import raises -from graphene.core.fields import ( - Field, - StringField, -) +from py.test import raises +from pytest import raises + +from graphene.core.fields import StringField from graphene.core.options import Options @@ -57,7 +54,6 @@ def test_options_description(): class ObjectType(object): '''False description''' - pass opt.contribute_to_class(ObjectType, '_meta') assert opt.description == 'False description' diff --git a/tests/core/test_query.py b/tests/core/test_query.py index 075cdea2..4814460f 100644 --- a/tests/core/test_query.py +++ b/tests/core/test_query.py @@ -1,23 +1,11 @@ -from py.test import raises -from collections import namedtuple -from pytest import raises -from graphql.core import graphql -from graphene.core.fields import ( - Field, - StringField, - ListField, -) -from graphql.core.type import ( - GraphQLObjectType, - GraphQLSchema, - GraphQLInterfaceType -) -from graphene.core.types import ( - Interface, - ObjectType -) + +from graphene.core.fields import Field, ListField, StringField from graphene.core.schema import Schema +from graphene.core.types import Interface, ObjectType +from graphql.core import graphql +from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType, + GraphQLSchema) class Character(Interface): @@ -50,7 +38,8 @@ Human_type = schema.T(Human) def test_type(): - assert Human._meta.fields_map['name'].resolve(Human(object()), None, None) == 'Peter' + assert Human._meta.fields_map['name'].resolve( + Human(object()), None, None) == 'Peter' def test_query(): diff --git a/tests/core/test_scalars.py b/tests/core/test_scalars.py index 654e99aa..1252741d 100644 --- a/tests/core/test_scalars.py +++ b/tests/core/test_scalars.py @@ -1,6 +1,4 @@ -from graphene.core.scalars import ( - GraphQLSkipField -) +from graphene.core.scalars import GraphQLSkipField def test_skipfield_serialize(): diff --git a/tests/core/test_schema.py b/tests/core/test_schema.py index a310648f..accc2f46 100644 --- a/tests/core/test_schema.py +++ b/tests/core/test_schema.py @@ -1,24 +1,12 @@ + from py.test import raises -from collections import namedtuple from pytest import raises + +from graphene import Interface, ObjectType, Schema +from graphene.core.fields import Field, ListField, StringField from graphql.core import graphql -from graphene.core.fields import ( - Field, - StringField, - ListField, -) -from graphql.core.type import ( - GraphQLObjectType, - GraphQLSchema, - GraphQLInterfaceType -) - -from graphene import ( - Interface, - ObjectType, - Schema -) - +from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType, + GraphQLSchema) from tests.utils import assert_equal_lists schema = Schema(name='My own schema') @@ -63,7 +51,7 @@ def test_schema_query(): def test_query_schema_graphql(): - a = object() + object() query = ''' { name @@ -84,7 +72,7 @@ def test_query_schema_graphql(): def test_query_schema_execute(): - a = object() + object() query = ''' { name @@ -107,7 +95,8 @@ def test_query_schema_execute(): def test_schema_get_type_map(): assert_equal_lists( schema.schema.get_type_map().keys(), - ['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive', '__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean'] + ['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive', + '__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean'] ) diff --git a/tests/core/test_types.py b/tests/core/test_types.py index c5d09f15..f7c29883 100644 --- a/tests/core/test_types.py +++ b/tests/core/test_types.py @@ -1,22 +1,12 @@ from py.test import raises from pytest import raises -from graphene.core.fields import ( - IntField, - StringField, -) -from graphql.core.execution.middlewares.utils import ( - tag_resolver, - resolver_has_tag -) -from graphql.core.type import ( - GraphQLObjectType, - GraphQLInterfaceType -) -from graphene.core.types import ( - Interface -) +from graphene.core.fields import IntField, StringField from graphene.core.schema import Schema +from graphene.core.types import Interface +from graphql.core.execution.middlewares.utils import (resolver_has_tag, + tag_resolver) +from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType class Character(Interface): @@ -60,7 +50,7 @@ def test_interface(): def test_interface_cannot_initialize(): with raises(Exception) as excinfo: - c = Character() + Character() assert 'An interface cannot be initialized' == str(excinfo.value) @@ -77,7 +67,8 @@ def test_object_type(): assert object_type.description == 'Human description' 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)} + # schema), 'friends': + # Human._meta.fields_map['friends'].internal_field(schema)} assert object_type.get_interfaces() == [schema.T(Character)] assert Human._meta.fields_map['name'].object_type == Human diff --git a/tests/relay/test_relay.py b/tests/relay/test_relay.py index 94c2cad3..0c011b0e 100644 --- a/tests/relay/test_relay.py +++ b/tests/relay/test_relay.py @@ -23,7 +23,7 @@ def test_field_no_contributed_raises_error(): def test_node_should_have_same_connection_always(): - s = object() + object() connection1 = relay.Connection.for_node(OtherNode) connection2 = relay.Connection.for_node(OtherNode) diff --git a/tests/relay/test_relay_mutations.py b/tests/relay/test_relay_mutations.py index 52ff2390..de206d70 100644 --- a/tests/relay/test_relay_mutations.py +++ b/tests/relay/test_relay_mutations.py @@ -1,11 +1,8 @@ -from graphql.core.type import ( - GraphQLInputObjectField -) - import graphene from graphene import relay -from graphene.core.types import InputObjectType from graphene.core.schema import Schema +from graphene.core.types import InputObjectType +from graphql.core.type import GraphQLInputObjectField my_id = 0 @@ -41,11 +38,13 @@ def test_mutation_input(): assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['input'] _input = ChangeNumber.input_type._meta.fields_map['input'] inner_type = _input.get_object_type(schema) - client_mutation_id_field = inner_type._meta.fields_map['client_mutation_id'] + client_mutation_id_field = inner_type._meta.fields_map[ + 'client_mutation_id'] assert issubclass(inner_type, InputObjectType) assert isinstance(client_mutation_id_field, graphene.StringField) assert client_mutation_id_field.object_type == inner_type - assert isinstance(client_mutation_id_field.internal_field(schema), GraphQLInputObjectField) + assert isinstance(client_mutation_id_field.internal_field( + schema), GraphQLInputObjectField) def test_execute_mutations(): diff --git a/tests/relay/test_relayfields.py b/tests/relay/test_relayfields.py index 9ae32d5a..34e6d305 100644 --- a/tests/relay/test_relayfields.py +++ b/tests/relay/test_relayfields.py @@ -1,16 +1,13 @@ -from graphql.core.type import ( - GraphQLNonNull, - GraphQLID -) - import graphene from graphene import relay +from graphql.core.type import GraphQLID, GraphQLNonNull schema = graphene.Schema() class MyConnection(relay.Connection): - my_custom_field = graphene.StringField(resolve=lambda instance, *_: 'Custom') + my_custom_field = graphene.StringField( + resolve=lambda instance, *_: 'Custom') class MyNode(relay.Node): @@ -23,7 +20,8 @@ class MyNode(relay.Node): class Query(graphene.ObjectType): my_node = relay.NodeField(MyNode) - all_my_nodes = relay.ConnectionField(MyNode, connection_type=MyConnection, customArg=graphene.Argument(graphene.String)) + all_my_nodes = relay.ConnectionField( + MyNode, connection_type=MyConnection, customArg=graphene.Argument(graphene.String)) def resolve_all_my_nodes(self, args, info): custom_arg = args.get('customArg') diff --git a/tests/utils/test_misc.py b/tests/utils/test_misc.py index a2811a11..f7393636 100644 --- a/tests/utils/test_misc.py +++ b/tests/utils/test_misc.py @@ -1,6 +1,7 @@ import collections -from graphql.core.type import GraphQLEnumType + from graphene.utils.misc import enum_to_graphql_enum +from graphql.core.type import GraphQLEnumType item = collections.namedtuple('type', 'name value') @@ -10,4 +11,5 @@ class MyCustomEnum(list): def test_enum_to_graphql_enum(): - assert isinstance(enum_to_graphql_enum(MyCustomEnum([item('k', 'v')])), GraphQLEnumType) + assert isinstance(enum_to_graphql_enum( + MyCustomEnum([item('k', 'v')])), GraphQLEnumType) diff --git a/tests/utils/test_proxy_snake_dict.py b/tests/utils/test_proxy_snake_dict.py index 0861c055..33b7a226 100644 --- a/tests/utils/test_proxy_snake_dict.py +++ b/tests/utils/test_proxy_snake_dict.py @@ -1,9 +1,11 @@ from py.test import raises + from graphene.utils import ProxySnakeDict def test_proxy_snake_dict(): - my_data = {'one': 1, 'two': 2, 'none': None, 'threeOrFor': 3, 'inside': {'otherCamelCase': 3}} + my_data = {'one': 1, 'two': 2, 'none': None, + 'threeOrFor': 3, 'inside': {'otherCamelCase': 3}} p = ProxySnakeDict(my_data) assert 'one' in p assert 'two' in p diff --git a/tests/utils/test_str_converter.py b/tests/utils/test_str_converter.py index 74940596..d8f1cdb9 100644 --- a/tests/utils/test_str_converter.py +++ b/tests/utils/test_str_converter.py @@ -1,4 +1,4 @@ -from graphene.utils import to_snake_case, to_camel_case +from graphene.utils import to_camel_case, to_snake_case def test_snake_case(): diff --git a/tox.ini b/tox.ini index eebc612c..e439ab84 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,6 @@ [tox] -envlist = py27,py33,py34,py35,pypy +envlist = flake8,py27,py33,py34,py35,pypy +skipsdist = true [testenv] deps= @@ -14,7 +15,13 @@ deps= setenv = PYTHONPATH = .:{envdir} commands= - py.test tests/ + py.test tests/ examples/ + +[testenv:flake8] +deps = flake8 +commands = + pip install -e . + flake8 graphene [pytest] DJANGO_SETTINGS_MODULE = tests.django_settings