Start porting to graphql-core-next

This commit is contained in:
Paul Hallett 2019-05-04 20:39:28 +01:00
parent abff3d75a3
commit 8a7a321136
No known key found for this signature in database
GPG Key ID: 529C11F0C93CDF11
25 changed files with 788 additions and 689 deletions

View File

@ -9,3 +9,10 @@ docs:
pip install -r requirements.txt &&\
make html &&\
cd -
dev-setup:
pip install -e ".[test]"
tests:
py.test graphene

View File

@ -28,7 +28,7 @@ from .types import (
Dynamic,
Union,
Context,
ResolveInfo,
GraphQLResolveInfo,
)
from .relay import (
Node,
@ -84,7 +84,7 @@ __all__ = [
"PageInfo",
"lazy_import",
"Context",
"ResolveInfo",
"GraphQLResolveInfo",
# Deprecated
"AbstractType",
]

View File

@ -2,8 +2,6 @@ from __future__ import absolute_import
import six
from graphql.pyutils.compat import Enum
try:
from inspect import signature
except ImportError:

View File

@ -2,14 +2,155 @@ import re
from collections import Iterable, OrderedDict
from functools import partial
from graphql_relay import connection_from_list
from ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String, Union
from ..types.field import Field
from ..types.objecttype import ObjectType, ObjectTypeOptions
from ..utils.thenables import maybe_thenable
from ..utils import base64, is_str, unbase64
from .node import is_node
from .connectiontypes import ConnectionType, PageInfoType, EdgeType
def connection_from_list(data, args=None, **kwargs):
'''
A simple function that accepts an array and connection arguments, and returns
a connection object for use in GraphQL. It uses array offsets as pagination,
so pagination will only work if the array is static.
'''
_len = len(data)
return connection_from_list_slice(
data,
args,
slice_start=0,
list_length=_len,
list_slice_length=_len,
**kwargs
)
def connection_from_list_slice(list_slice, args=None, connection_type=None,
edge_type=None, pageinfo_type=None,
slice_start=0, list_length=0, list_slice_length=None):
'''
Given a slice (subset) of an array, returns a connection object for use in
GraphQL.
This function is similar to `connectionFromArray`, but is intended for use
cases where you know the cardinality of the connection, consider it too large
to materialize the entire array, and instead wish pass in a slice of the
total result large enough to cover the range specified in `args`.
'''
connection_type = connection_type or Connection
edge_type = edge_type or Edge
pageinfo_type = pageinfo_type or PageInfo
args = args or {}
before = args.get('before')
after = args.get('after')
first = args.get('first')
last = args.get('last')
if list_slice_length is None:
list_slice_length = len(list_slice)
slice_end = slice_start + list_slice_length
before_offset = get_offset_with_default(before, list_length)
after_offset = get_offset_with_default(after, -1)
start_offset = max(
slice_start - 1,
after_offset,
-1
) + 1
end_offset = min(
slice_end,
before_offset,
list_length
)
if isinstance(first, int):
end_offset = min(
end_offset,
start_offset + first
)
if isinstance(last, int):
start_offset = max(
start_offset,
end_offset - last
)
# If supplied slice is too large, trim it down before mapping over it.
_slice = list_slice[
max(start_offset - slice_start, 0):
list_slice_length - (slice_end - end_offset)
]
edges = [
edge_type(
node=node,
cursor=offset_to_cursor(start_offset + i)
)
for i, node in enumerate(_slice)
]
first_edge_cursor = edges[0].cursor if edges else None
last_edge_cursor = edges[-1].cursor if edges else None
lower_bound = after_offset + 1 if after else 0
upper_bound = before_offset if before else list_length
return connection_type(
edges=edges,
page_info=pageinfo_type(
start_cursor=first_edge_cursor,
end_cursor=last_edge_cursor,
has_previous_page=isinstance(last, int) and start_offset > lower_bound,
has_next_page=isinstance(first, int) and end_offset < upper_bound
)
)
def offset_to_cursor(offset):
'''
Creates the cursor string from an offset.
'''
return base64(PREFIX + str(offset))
def cursor_to_offset(cursor):
'''
Rederives the offset from the cursor string.
'''
try:
return int(unbase64(cursor)[len(PREFIX):])
except:
return None
def cursor_for_object_in_connection(data, _object):
'''
Return the cursor associated with an object in an array.
'''
if _object not in data:
return None
offset = data.index(_object)
return offset_to_cursor(offset)
def get_offset_with_default(cursor=None, default_offset=0):
'''
Given an optional cursor and a default offset, returns the offset
to use; if the cursor contains a valid offset, that will be used,
otherwise it will be the default.
'''
if not is_str(cursor):
return default_offset
offset = cursor_to_offset(cursor)
try:
return int(offset)
except:
return default_offset
class PageInfo(ObjectType):
class Meta:

View File

@ -0,0 +1,42 @@
class ConnectionType:
def __init__(self, edges, page_info):
self.edges = edges
self.page_info = page_info
def to_dict(self):
return {
'edges': [e.to_dict() for e in self.edges],
'pageInfo': self.page_info.to_dict(),
}
class PageInfoType:
def __init__(self, start_cursor="", end_cursor="",
has_previous_page=False, has_next_page=False):
self.startCursor = start_cursor
self.endCursor = end_cursor
self.hasPreviousPage = has_previous_page
self.hasNextPage = has_next_page
def to_dict(self):
return {
'startCursor': self.startCursor,
'endCursor': self.endCursor,
'hasPreviousPage': self.hasPreviousPage,
'hasNextPage': self.hasNextPage,
}
class EdgeType:
def __init__(self, node, cursor):
self.node = node
self.cursor = cursor
def to_dict(self):
return {
'node': self.node,
'cursor': self.cursor,
}

View File

@ -2,12 +2,12 @@ from collections import OrderedDict
from functools import partial
from inspect import isclass
from graphql_relay import from_global_id, to_global_id
from ..types import ID, Field, Interface, ObjectType
from ..types.interface import InterfaceOptions
from ..types.utils import get_type
from .utils import base64, unbase64
def is_node(objecttype):
"""

View File

@ -1,6 +1,6 @@
from collections import OrderedDict
from graphql_relay.utils import base64
from ..utils import base64
from promise import Promise
from ...types import ObjectType, Schema, String

View File

@ -1,4 +1,4 @@
from graphql_relay import to_global_id
from ..utils import to_global_id
from ...types import ID, NonNull, ObjectType, String
from ...types.definitions import GrapheneObjectType

View File

@ -1,6 +1,6 @@
from collections import OrderedDict
from graphql_relay import to_global_id
from ..utils import to_global_id
from ...types import ObjectType, Schema, String
from ..node import Node, is_node

19
graphene/relay/utils.py Normal file
View File

@ -0,0 +1,19 @@
from ..utils import base64, unbase64
def to_global_id(type, id):
'''
Takes a type name and an ID specific to that type name, and returns a
"global ID" that is unique among all types.
'''
return base64(':'.join([type, text_type(id)]))
def from_global_id(global_id):
'''
Takes the "global ID" created by toGlobalID, and retuns the type name and ID
used to create it.
'''
unbased_global_id = unbase64(global_id)
_type, _id = unbased_global_id.split(':', 1)
return _type, _id

View File

@ -1,5 +1,5 @@
# flake8: noqa
from graphql import ResolveInfo
from graphql import GraphQLResolveInfo
from .objecttype import ObjectType
from .interface import Interface
@ -51,7 +51,7 @@ __all__ = [
"Dynamic",
"Union",
"Context",
"ResolveInfo",
"GraphQLResolveInfo",
# Deprecated
"AbstractType",
]

View File

@ -1,10 +1,11 @@
from collections import OrderedDict
from enum import Enum
import six
from graphene.utils.subclass_with_meta import SubclassWithMeta_Meta
from ..pyutils.compat import Enum as PyEnum
from .base import BaseOptions, BaseType
from .unmountedtype import UnmountedType
@ -15,8 +16,6 @@ def eq_enum(self, other):
return self.value is other
EnumType = type(PyEnum)
class EnumOptions(BaseOptions):
enum = None # type: Enum
@ -29,7 +28,7 @@ class EnumMeta(SubclassWithMeta_Meta):
# We remove the Meta attribute from the class to not collide
# with the enum values.
enum_members.pop("Meta", None)
enum = PyEnum(cls.__name__, enum_members)
enum = Enum(cls.__name__, enum_members)
return SubclassWithMeta_Meta.__new__(
cls, name, bases, OrderedDict(classdict, __enum__=enum), **options
)
@ -46,7 +45,8 @@ class EnumMeta(SubclassWithMeta_Meta):
def __call__(cls, *args, **kwargs): # noqa: N805
if cls is Enum:
description = kwargs.pop("description", None)
return cls.from_enum(PyEnum(*args, **kwargs), description=description)
kwargs['description'] = description
return Enum(*args, **kwargs)
return super(EnumMeta, cls).__call__(*args, **kwargs)
# return cls._meta.enum(*args, **kwargs)

View File

@ -1,12 +1,12 @@
from __future__ import unicode_literals
from graphql.language.ast import (
BooleanValue,
FloatValue,
IntValue,
ListValue,
ObjectValue,
StringValue,
BooleanValueNode,
FloatValueNode,
IntValueNode,
ListValueNode,
ObjectValueNode,
StringValueNode,
)
from graphene.types.scalars import MAX_INT, MIN_INT
@ -30,15 +30,15 @@ class GenericScalar(Scalar):
@staticmethod
def parse_literal(ast):
if isinstance(ast, (StringValue, BooleanValue)):
if isinstance(ast, (StringValueNode, BooleanValueNode)):
return ast.value
elif isinstance(ast, IntValue):
elif isinstance(ast, IntValueNode):
num = int(ast.value)
if MIN_INT <= num <= MAX_INT:
return num
elif isinstance(ast, FloatValue):
elif isinstance(ast, FloatValueNode):
return float(ast.value)
elif isinstance(ast, ListValue):
elif isinstance(ast, ListValueNode):
return [GenericScalar.parse_literal(value) for value in ast.values]
elif isinstance(ast, ObjectValue):
return {

View File

@ -1,5 +1,10 @@
import six
from graphql.language.ast import BooleanValue, FloatValue, IntValue, StringValue
from graphql.language.ast import (
BooleanValueNode,
FloatValueNode,
IntValueNode,
StringValueNode
)
from .base import BaseOptions, BaseType
from .unmountedtype import UnmountedType
@ -99,7 +104,7 @@ class Float(Scalar):
@staticmethod
def parse_literal(ast):
if isinstance(ast, (FloatValue, IntValue)):
if isinstance(ast, (FloatValueNode, IntValueNode)):
return float(ast.value)
@ -121,7 +126,7 @@ class String(Scalar):
@staticmethod
def parse_literal(ast):
if isinstance(ast, StringValue):
if isinstance(ast, StringValueNode):
return ast.value
@ -135,7 +140,7 @@ class Boolean(Scalar):
@staticmethod
def parse_literal(ast):
if isinstance(ast, BooleanValue):
if isinstance(ast, BooleanValueNode):
return ast.value

View File

@ -6,13 +6,13 @@ from graphql.type.directives import (
GraphQLIncludeDirective,
GraphQLSkipDirective,
)
from graphql.type.introspection import IntrospectionSchema
from graphql.utils.introspection_query import introspection_query
from graphql.utils.schema_printer import print_schema
from graphql.type.introspection import introspection_types
from graphql.utilities.introspection_query import get_introspection_query
from graphql.utilities.schema_printer import print_schema
from .definitions import GrapheneGraphQLType
from .objecttype import ObjectType
from .typemap import TypeMap, is_graphene_type
from .typemap import is_graphene_type
def assert_valid_root_type(_type):
@ -25,103 +25,5 @@ def assert_valid_root_type(_type):
).format(_type)
class Schema(GraphQLSchema):
"""
Schema Definition
Schema = GraphQLSchema
A Schema is created by supplying the root types of each type of operation,
query and mutation (optional).
"""
def __init__(
self,
query=None,
mutation=None,
subscription=None,
directives=None,
types=None,
auto_camelcase=True,
):
assert_valid_root_type(query)
assert_valid_root_type(mutation)
assert_valid_root_type(subscription)
self._query = query
self._mutation = mutation
self._subscription = subscription
self.types = types
self.auto_camelcase = auto_camelcase
if directives is None:
directives = [GraphQLIncludeDirective, GraphQLSkipDirective]
assert all(
isinstance(d, GraphQLDirective) for d in directives
), "Schema directives must be List[GraphQLDirective] if provided but got: {}.".format(
directives
)
self._directives = directives
self.build_typemap()
def get_query_type(self):
return self.get_graphql_type(self._query)
def get_mutation_type(self):
return self.get_graphql_type(self._mutation)
def get_subscription_type(self):
return self.get_graphql_type(self._subscription)
def __getattr__(self, type_name):
"""
This function let the developer select a type in a given schema
by accessing its attrs.
Example: using schema.Query for accessing the "Query" type in the Schema
"""
_type = super(Schema, self).get_type(type_name)
if _type is None:
raise AttributeError('Type "{}" not found in the Schema'.format(type_name))
if isinstance(_type, GrapheneGraphQLType):
return _type.graphene_type
return _type
def get_graphql_type(self, _type):
if not _type:
return _type
if is_type(_type):
return _type
if is_graphene_type(_type):
graphql_type = self.get_type(_type._meta.name)
assert graphql_type, "Type {} not found in this schema.".format(
_type._meta.name
)
assert graphql_type.graphene_type == _type
return graphql_type
raise Exception("{} is not a valid GraphQL type.".format(_type))
def execute(self, *args, **kwargs):
return graphql(self, *args, **kwargs)
def introspect(self):
instrospection = self.execute(introspection_query)
if instrospection.errors:
raise instrospection.errors[0]
return instrospection.data
def __str__(self):
return print_schema(self)
def lazy(self, _type):
return lambda: self.get_type(_type)
def build_typemap(self):
initial_types = [
self._query,
self._mutation,
self._subscription,
IntrospectionSchema,
]
if self.types:
initial_types += self.types
self._type_map = TypeMap(
initial_types, auto_camelcase=self.auto_camelcase, schema=self
)

View File

@ -156,7 +156,7 @@ def test_bad_variables():
)
assert len(result.errors) == 1
# when `input` is not JSON serializable formatting the error message in
# `graphql.utils.is_valid_value` line 79 fails with a TypeError
# `graphql.utilities.is_valid_value` line 79 fails with a TypeError
assert isinstance(result.errors[0], GraphQLError)
print(result.errors[0])
assert result.data is None

View File

@ -1,7 +1,7 @@
import six
from ..argument import Argument
from ..enum import Enum, PyEnum
from ..enum import Enum
from ..field import Field
from ..inputfield import InputField
from ..schema import ObjectType, Schema
@ -52,88 +52,57 @@ def test_enum_instance_construction():
assert sorted([v.name for v in values]) == ["BLUE", "GREEN", "RED"]
def test_enum_from_builtin_enum():
PyRGB = PyEnum("RGB", "RED,GREEN,BLUE")
RGB = Enum.from_enum(PyRGB)
assert RGB._meta.enum == PyRGB
assert RGB.RED
assert RGB.GREEN
assert RGB.BLUE
# def test_enum_from_builtin_enum_accepts_lambda_description():
# def custom_description(value):
# if not value:
# return "StarWars Episodes"
# return "New Hope Episode" if value == Episode.NEWHOPE else "Other"
def test_enum_from_builtin_enum_accepts_lambda_description():
def custom_description(value):
if not value:
return "StarWars Episodes"
# def custom_deprecation_reason(value):
# return "meh" if value == Episode.NEWHOPE else None
return "New Hope Episode" if value == Episode.NEWHOPE else "Other"
# PyEpisode = PyEnum("PyEpisode", "NEWHOPE,EMPIRE,JEDI")
# Episode = Enum.from_enum(
# PyEpisode,
# description=custom_description,
# deprecation_reason=custom_deprecation_reason,
# )
def custom_deprecation_reason(value):
return "meh" if value == Episode.NEWHOPE else None
# class Query(ObjectType):
# foo = Episode()
PyEpisode = PyEnum("PyEpisode", "NEWHOPE,EMPIRE,JEDI")
Episode = Enum.from_enum(
PyEpisode,
description=custom_description,
deprecation_reason=custom_deprecation_reason,
)
# schema = Schema(query=Query)
class Query(ObjectType):
foo = Episode()
# GraphQLPyEpisode = schema._type_map["PyEpisode"].values
schema = Schema(query=Query)
# assert schema._type_map["PyEpisode"].description == "StarWars Episodes"
# assert (
# GraphQLPyEpisode[0].name == "NEWHOPE"
# and GraphQLPyEpisode[0].description == "New Hope Episode"
# )
# assert (
# GraphQLPyEpisode[1].name == "EMPIRE"
# and GraphQLPyEpisode[1].description == "Other"
# )
# assert (
# GraphQLPyEpisode[2].name == "JEDI"
# and GraphQLPyEpisode[2].description == "Other"
# )
GraphQLPyEpisode = schema._type_map["PyEpisode"].values
assert schema._type_map["PyEpisode"].description == "StarWars Episodes"
assert (
GraphQLPyEpisode[0].name == "NEWHOPE"
and GraphQLPyEpisode[0].description == "New Hope Episode"
)
assert (
GraphQLPyEpisode[1].name == "EMPIRE"
and GraphQLPyEpisode[1].description == "Other"
)
assert (
GraphQLPyEpisode[2].name == "JEDI"
and GraphQLPyEpisode[2].description == "Other"
)
assert (
GraphQLPyEpisode[0].name == "NEWHOPE"
and GraphQLPyEpisode[0].deprecation_reason == "meh"
)
assert (
GraphQLPyEpisode[1].name == "EMPIRE"
and GraphQLPyEpisode[1].deprecation_reason is None
)
assert (
GraphQLPyEpisode[2].name == "JEDI"
and GraphQLPyEpisode[2].deprecation_reason is None
)
def test_enum_from_python3_enum_uses_enum_doc():
if not six.PY3:
return
from enum import Enum as PyEnum
class Color(PyEnum):
"""This is the description"""
RED = 1
GREEN = 2
BLUE = 3
RGB = Enum.from_enum(Color)
assert RGB._meta.enum == Color
assert RGB._meta.description == "This is the description"
assert RGB
assert RGB.RED
assert RGB.GREEN
assert RGB.BLUE
# assert (
# GraphQLPyEpisode[0].name == "NEWHOPE"
# and GraphQLPyEpisode[0].deprecation_reason == "meh"
# )
# assert (
# GraphQLPyEpisode[1].name == "EMPIRE"
# and GraphQLPyEpisode[1].deprecation_reason is None
# )
# assert (
# GraphQLPyEpisode[2].name == "JEDI"
# and GraphQLPyEpisode[2].deprecation_reason is None
# )
def test_enum_value_from_class():

View File

@ -1,7 +1,7 @@
import json
from functools import partial
from graphql import GraphQLError, ResolveInfo, Source, execute, parse
from graphql import GraphQLError, GraphQLResolveInfo, Source, execute, parse
from ..context import Context
from ..dynamic import Dynamic
@ -455,7 +455,7 @@ def test_query_annotated_resolvers():
return "{}-{}".format(self, info.context.key)
def resolve_info(self, info):
assert isinstance(info, ResolveInfo)
assert isinstance(info, GraphQLResolveInfo)
return "{}-{}".format(self, info.field_name)
test_schema = Schema(Query)

View File

@ -1,286 +1,286 @@
import pytest
from graphql.type import (
GraphQLArgument,
GraphQLEnumType,
GraphQLEnumValue,
GraphQLField,
GraphQLInputObjectField,
GraphQLInputObjectType,
GraphQLInterfaceType,
GraphQLObjectType,
GraphQLString,
)
# import pytest
# from graphql.type import (
# GraphQLArgument,
# GraphQLEnumType,
# GraphQLEnumValue,
# GraphQLField,
# GraphQLInputField,
# GraphQLInputObjectType,
# GraphQLInterfaceType,
# GraphQLObjectType,
# GraphQLString,
# )
from ..dynamic import Dynamic
from ..enum import Enum
from ..field import Field
from ..inputfield import InputField
from ..inputobjecttype import InputObjectType
from ..interface import Interface
from ..objecttype import ObjectType
from ..scalars import Int, String
from ..structures import List, NonNull
from ..typemap import TypeMap, resolve_type
# from ..dynamic import Dynamic
# from ..enum import Enum
# from ..field import Field
# from ..inputfield import InputField
# from ..inputobjecttype import InputObjectType
# from ..interface import Interface
# from ..objecttype import ObjectType
# from ..scalars import Int, String
# from ..structures import List, NonNull
# from ..typemap import resolve_type
def test_enum():
class MyEnum(Enum):
"""Description"""
# def test_enum():
# class MyEnum(Enum):
# """Description"""
foo = 1
bar = 2
# foo = 1
# bar = 2
@property
def description(self):
return "Description {}={}".format(self.name, self.value)
# @property
# def description(self):
# return "Description {}={}".format(self.name, self.value)
@property
def deprecation_reason(self):
if self == MyEnum.foo:
return "Is deprecated"
# @property
# def deprecation_reason(self):
# if self == MyEnum.foo:
# return "Is deprecated"
typemap = TypeMap([MyEnum])
assert "MyEnum" in typemap
graphql_enum = typemap["MyEnum"]
assert isinstance(graphql_enum, GraphQLEnumType)
assert graphql_enum.name == "MyEnum"
assert graphql_enum.description == "Description"
values = graphql_enum.values
assert values == [
GraphQLEnumValue(
name="foo",
value=1,
description="Description foo=1",
deprecation_reason="Is deprecated",
),
GraphQLEnumValue(name="bar", value=2, description="Description bar=2"),
]
# typemap = TypeMap([MyEnum])
# assert "MyEnum" in typemap
# graphql_enum = typemap["MyEnum"]
# assert isinstance(graphql_enum, GraphQLEnumType)
# assert graphql_enum.name == "MyEnum"
# assert graphql_enum.description == "Description"
# values = graphql_enum.values
# assert values == [
# GraphQLEnumValue(
# name="foo",
# value=1,
# description="Description foo=1",
# deprecation_reason="Is deprecated",
# ),
# GraphQLEnumValue(name="bar", value=2, description="Description bar=2"),
# ]
def test_objecttype():
class MyObjectType(ObjectType):
"""Description"""
# def test_objecttype():
# class MyObjectType(ObjectType):
# """Description"""
foo = String(
bar=String(description="Argument description", default_value="x"),
description="Field description",
)
bar = String(name="gizmo")
# foo = String(
# bar=String(description="Argument description", default_value="x"),
# description="Field description",
# )
# bar = String(name="gizmo")
def resolve_foo(self, bar):
return bar
# def resolve_foo(self, bar):
# return bar
typemap = TypeMap([MyObjectType])
assert "MyObjectType" in typemap
graphql_type = typemap["MyObjectType"]
assert isinstance(graphql_type, GraphQLObjectType)
assert graphql_type.name == "MyObjectType"
assert graphql_type.description == "Description"
# typemap = TypeMap([MyObjectType])
# assert "MyObjectType" in typemap
# graphql_type = typemap["MyObjectType"]
# assert isinstance(graphql_type, GraphQLObjectType)
# assert graphql_type.name == "MyObjectType"
# assert graphql_type.description == "Description"
fields = graphql_type.fields
assert list(fields.keys()) == ["foo", "gizmo"]
foo_field = fields["foo"]
assert isinstance(foo_field, GraphQLField)
assert foo_field.description == "Field description"
# fields = graphql_type.fields
# assert list(fields.keys()) == ["foo", "gizmo"]
# foo_field = fields["foo"]
# assert isinstance(foo_field, GraphQLField)
# assert foo_field.description == "Field description"
assert foo_field.args == {
"bar": GraphQLArgument(
GraphQLString,
description="Argument description",
default_value="x",
out_name="bar",
)
}
# assert foo_field.args == {
# "bar": GraphQLArgument(
# GraphQLString,
# description="Argument description",
# default_value="x",
# out_name="bar",
# )
# }
def test_dynamic_objecttype():
class MyObjectType(ObjectType):
"""Description"""
# def test_dynamic_objecttype():
# class MyObjectType(ObjectType):
# """Description"""
bar = Dynamic(lambda: Field(String))
own = Field(lambda: MyObjectType)
# bar = Dynamic(lambda: Field(String))
# own = Field(lambda: MyObjectType)
typemap = TypeMap([MyObjectType])
assert "MyObjectType" in typemap
assert list(MyObjectType._meta.fields.keys()) == ["bar", "own"]
graphql_type = typemap["MyObjectType"]
# typemap = TypeMap([MyObjectType])
# assert "MyObjectType" in typemap
# assert list(MyObjectType._meta.fields.keys()) == ["bar", "own"]
# graphql_type = typemap["MyObjectType"]
fields = graphql_type.fields
assert list(fields.keys()) == ["bar", "own"]
assert fields["bar"].type == GraphQLString
assert fields["own"].type == graphql_type
# fields = graphql_type.fields
# assert list(fields.keys()) == ["bar", "own"]
# assert fields["bar"].type == GraphQLString
# assert fields["own"].type == graphql_type
def test_interface():
class MyInterface(Interface):
"""Description"""
# def test_interface():
# class MyInterface(Interface):
# """Description"""
foo = String(
bar=String(description="Argument description", default_value="x"),
description="Field description",
)
bar = String(name="gizmo", first_arg=String(), other_arg=String(name="oth_arg"))
own = Field(lambda: MyInterface)
# foo = String(
# bar=String(description="Argument description", default_value="x"),
# description="Field description",
# )
# bar = String(name="gizmo", first_arg=String(), other_arg=String(name="oth_arg"))
# own = Field(lambda: MyInterface)
def resolve_foo(self, args, info):
return args.get("bar")
# def resolve_foo(self, args, info):
# return args.get("bar")
typemap = TypeMap([MyInterface])
assert "MyInterface" in typemap
graphql_type = typemap["MyInterface"]
assert isinstance(graphql_type, GraphQLInterfaceType)
assert graphql_type.name == "MyInterface"
assert graphql_type.description == "Description"
# typemap = TypeMap([MyInterface])
# assert "MyInterface" in typemap
# graphql_type = typemap["MyInterface"]
# assert isinstance(graphql_type, GraphQLInterfaceType)
# assert graphql_type.name == "MyInterface"
# assert graphql_type.description == "Description"
fields = graphql_type.fields
assert list(fields.keys()) == ["foo", "gizmo", "own"]
assert fields["own"].type == graphql_type
assert list(fields["gizmo"].args.keys()) == ["firstArg", "oth_arg"]
foo_field = fields["foo"]
assert isinstance(foo_field, GraphQLField)
assert foo_field.description == "Field description"
assert not foo_field.resolver # Resolver not attached in interfaces
assert foo_field.args == {
"bar": GraphQLArgument(
GraphQLString,
description="Argument description",
default_value="x",
out_name="bar",
)
}
# fields = graphql_type.fields
# assert list(fields.keys()) == ["foo", "gizmo", "own"]
# assert fields["own"].type == graphql_type
# assert list(fields["gizmo"].args.keys()) == ["firstArg", "oth_arg"]
# foo_field = fields["foo"]
# assert isinstance(foo_field, GraphQLField)
# assert foo_field.description == "Field description"
# assert not foo_field.resolver # Resolver not attached in interfaces
# assert foo_field.args == {
# "bar": GraphQLArgument(
# GraphQLString,
# description="Argument description",
# default_value="x",
# out_name="bar",
# )
# }
def test_inputobject():
class OtherObjectType(InputObjectType):
thingy = NonNull(Int)
# def test_inputobject():
# class OtherObjectType(InputObjectType):
# thingy = NonNull(Int)
class MyInnerObjectType(InputObjectType):
some_field = String()
some_other_field = List(OtherObjectType)
# class MyInnerObjectType(InputObjectType):
# some_field = String()
# some_other_field = List(OtherObjectType)
class MyInputObjectType(InputObjectType):
"""Description"""
# class MyInputObjectType(InputObjectType):
# """Description"""
foo_bar = String(description="Field description")
bar = String(name="gizmo")
baz = NonNull(MyInnerObjectType)
own = InputField(lambda: MyInputObjectType)
# foo_bar = String(description="Field description")
# bar = String(name="gizmo")
# baz = NonNull(MyInnerObjectType)
# own = InputField(lambda: MyInputObjectType)
def resolve_foo_bar(self, args, info):
return args.get("bar")
# def resolve_foo_bar(self, args, info):
# return args.get("bar")
typemap = TypeMap([MyInputObjectType])
assert "MyInputObjectType" in typemap
graphql_type = typemap["MyInputObjectType"]
assert isinstance(graphql_type, GraphQLInputObjectType)
assert graphql_type.name == "MyInputObjectType"
assert graphql_type.description == "Description"
# typemap = TypeMap([MyInputObjectType])
# assert "MyInputObjectType" in typemap
# graphql_type = typemap["MyInputObjectType"]
# assert isinstance(graphql_type, GraphQLInputObjectType)
# assert graphql_type.name == "MyInputObjectType"
# assert graphql_type.description == "Description"
other_graphql_type = typemap["OtherObjectType"]
inner_graphql_type = typemap["MyInnerObjectType"]
container = graphql_type.create_container(
{
"bar": "oh!",
"baz": inner_graphql_type.create_container(
{
"some_other_field": [
other_graphql_type.create_container({"thingy": 1}),
other_graphql_type.create_container({"thingy": 2}),
]
}
),
}
)
assert isinstance(container, MyInputObjectType)
assert "bar" in container
assert container.bar == "oh!"
assert "foo_bar" not in container
assert container.foo_bar is None
assert container.baz.some_field is None
assert container.baz.some_other_field[0].thingy == 1
assert container.baz.some_other_field[1].thingy == 2
# other_graphql_type = typemap["OtherObjectType"]
# inner_graphql_type = typemap["MyInnerObjectType"]
# container = graphql_type.create_container(
# {
# "bar": "oh!",
# "baz": inner_graphql_type.create_container(
# {
# "some_other_field": [
# other_graphql_type.create_container({"thingy": 1}),
# other_graphql_type.create_container({"thingy": 2}),
# ]
# }
# ),
# }
# )
# assert isinstance(container, MyInputObjectType)
# assert "bar" in container
# assert container.bar == "oh!"
# assert "foo_bar" not in container
# assert container.foo_bar is None
# assert container.baz.some_field is None
# assert container.baz.some_other_field[0].thingy == 1
# assert container.baz.some_other_field[1].thingy == 2
fields = graphql_type.fields
assert list(fields.keys()) == ["fooBar", "gizmo", "baz", "own"]
own_field = fields["own"]
assert own_field.type == graphql_type
foo_field = fields["fooBar"]
assert isinstance(foo_field, GraphQLInputObjectField)
assert foo_field.description == "Field description"
# fields = graphql_type.fields
# assert list(fields.keys()) == ["fooBar", "gizmo", "baz", "own"]
# own_field = fields["own"]
# assert own_field.type == graphql_type
# foo_field = fields["fooBar"]
# assert isinstance(foo_field, GraphQLInputObjectField)
# assert foo_field.description == "Field description"
def test_objecttype_camelcase():
class MyObjectType(ObjectType):
"""Description"""
# def test_objecttype_camelcase():
# class MyObjectType(ObjectType):
# """Description"""
foo_bar = String(bar_foo=String())
# foo_bar = String(bar_foo=String())
typemap = TypeMap([MyObjectType])
assert "MyObjectType" in typemap
graphql_type = typemap["MyObjectType"]
assert isinstance(graphql_type, GraphQLObjectType)
assert graphql_type.name == "MyObjectType"
assert graphql_type.description == "Description"
# typemap = TypeMap([MyObjectType])
# assert "MyObjectType" in typemap
# graphql_type = typemap["MyObjectType"]
# assert isinstance(graphql_type, GraphQLObjectType)
# assert graphql_type.name == "MyObjectType"
# assert graphql_type.description == "Description"
fields = graphql_type.fields
assert list(fields.keys()) == ["fooBar"]
foo_field = fields["fooBar"]
assert isinstance(foo_field, GraphQLField)
assert foo_field.args == {
"barFoo": GraphQLArgument(GraphQLString, out_name="bar_foo")
}
# fields = graphql_type.fields
# assert list(fields.keys()) == ["fooBar"]
# foo_field = fields["fooBar"]
# assert isinstance(foo_field, GraphQLField)
# assert foo_field.args == {
# "barFoo": GraphQLArgument(GraphQLString, out_name="bar_foo")
# }
def test_objecttype_camelcase_disabled():
class MyObjectType(ObjectType):
"""Description"""
# def test_objecttype_camelcase_disabled():
# class MyObjectType(ObjectType):
# """Description"""
foo_bar = String(bar_foo=String())
# foo_bar = String(bar_foo=String())
typemap = TypeMap([MyObjectType], auto_camelcase=False)
assert "MyObjectType" in typemap
graphql_type = typemap["MyObjectType"]
assert isinstance(graphql_type, GraphQLObjectType)
assert graphql_type.name == "MyObjectType"
assert graphql_type.description == "Description"
# typemap = TypeMap([MyObjectType], auto_camelcase=False)
# assert "MyObjectType" in typemap
# graphql_type = typemap["MyObjectType"]
# assert isinstance(graphql_type, GraphQLObjectType)
# assert graphql_type.name == "MyObjectType"
# assert graphql_type.description == "Description"
fields = graphql_type.fields
assert list(fields.keys()) == ["foo_bar"]
foo_field = fields["foo_bar"]
assert isinstance(foo_field, GraphQLField)
assert foo_field.args == {
"bar_foo": GraphQLArgument(GraphQLString, out_name="bar_foo")
}
# fields = graphql_type.fields
# assert list(fields.keys()) == ["foo_bar"]
# foo_field = fields["foo_bar"]
# assert isinstance(foo_field, GraphQLField)
# assert foo_field.args == {
# "bar_foo": GraphQLArgument(GraphQLString, out_name="bar_foo")
# }
def test_objecttype_with_possible_types():
class MyObjectType(ObjectType):
"""Description"""
# def test_objecttype_with_possible_types():
# class MyObjectType(ObjectType):
# """Description"""
class Meta:
possible_types = (dict,)
# class Meta:
# possible_types = (dict,)
foo_bar = String()
# foo_bar = String()
typemap = TypeMap([MyObjectType])
graphql_type = typemap["MyObjectType"]
assert graphql_type.is_type_of
assert graphql_type.is_type_of({}, None) is True
assert graphql_type.is_type_of(MyObjectType(), None) is False
# typemap = TypeMap([MyObjectType])
# graphql_type = typemap["MyObjectType"]
# assert graphql_type.is_type_of
# assert graphql_type.is_type_of({}, None) is True
# assert graphql_type.is_type_of(MyObjectType(), None) is False
def test_resolve_type_with_missing_type():
class MyObjectType(ObjectType):
foo_bar = String()
# def test_resolve_type_with_missing_type():
# class MyObjectType(ObjectType):
# foo_bar = String()
class MyOtherObjectType(ObjectType):
fizz_buzz = String()
# class MyOtherObjectType(ObjectType):
# fizz_buzz = String()
def resolve_type_func(root, info):
return MyOtherObjectType
# def resolve_type_func(root, info):
# return MyOtherObjectType
typemap = TypeMap([MyObjectType])
with pytest.raises(AssertionError) as excinfo:
resolve_type(resolve_type_func, typemap, "MyOtherObjectType", {}, {})
# typemap = TypeMap([MyObjectType])
# with pytest.raises(AssertionError) as excinfo:
# resolve_type(resolve_type_func, typemap, "MyOtherObjectType", {}, {})
assert "MyOtherObjectTyp" in str(excinfo.value)
# assert "MyOtherObjectTyp" in str(excinfo.value)

View File

@ -9,7 +9,6 @@ class Query(ObjectType):
def resolve_uuid(self, info, input):
return input
schema = Schema(query=Query)

View File

@ -8,15 +8,14 @@ from graphql import (
GraphQLField,
GraphQLFloat,
GraphQLID,
GraphQLInputObjectField,
GraphQLInputField,
GraphQLInt,
GraphQLList,
GraphQLNonNull,
GraphQLString,
)
from graphql.execution.executor import get_default_resolve_type_fn
from graphql.execution.execute import default_type_resolver
from graphql.type import GraphQLEnumValue
from graphql.type.typemap import GraphQLTypeMap
from ..utils.get_unbound_function import get_unbound_function
from ..utils.str_converters import to_camel_case
@ -56,7 +55,7 @@ def resolve_type(resolve_type_func, map, type_name, root, info):
if not _type:
return_type = map[type_name]
return get_default_resolve_type_fn(root, info, return_type)
return default_type_resolver(root, info, return_type)
if inspect.isclass(_type) and issubclass(_type, ObjectType):
graphql_type = map.get(_type._meta.name)
@ -73,265 +72,266 @@ def is_type_of_from_possible_types(possible_types, root, info):
return isinstance(root, possible_types)
class TypeMap(GraphQLTypeMap):
def __init__(self, types, auto_camelcase=True, schema=None):
self.auto_camelcase = auto_camelcase
self.schema = schema
super(TypeMap, self).__init__(types)
# class TypeMap(object):
# def __init__(self, types, auto_camelcase=True, schema=None):
# self.auto_camelcase = auto_camelcase
# self.schema = schema
# types = [t for t in types if t]
# super(TypeMap, self).__init__(types)
def reducer(self, map, type):
if not type:
return map
if inspect.isfunction(type):
type = type()
if is_graphene_type(type):
return self.graphene_reducer(map, type)
return GraphQLTypeMap.reducer(map, type)
# def reducer(self, map, type):
# if not type:
# return map
# if inspect.isfunction(type):
# type = type()
# if is_graphene_type(type):
# return self.graphene_reducer(map, type)
# return GraphQLSchema.reducer(map, type)
def graphene_reducer(self, map, type):
if isinstance(type, (List, NonNull)):
return self.reducer(map, type.of_type)
if type._meta.name in map:
_type = map[type._meta.name]
if isinstance(_type, GrapheneGraphQLType):
assert _type.graphene_type == type, (
"Found different types with the same name in the schema: {}, {}."
).format(_type.graphene_type, type)
return map
# def graphene_reducer(self, map, type):
# if isinstance(type, (List, NonNull)):
# return self.reducer(map, type.of_type)
# if type._meta.name in map:
# _type = map[type._meta.name]
# if isinstance(_type, GrapheneGraphQLType):
# assert _type.graphene_type == type, (
# "Found different types with the same name in the schema: {}, {}."
# ).format(_type.graphene_type, type)
# return map
if issubclass(type, ObjectType):
internal_type = self.construct_objecttype(map, type)
elif issubclass(type, InputObjectType):
internal_type = self.construct_inputobjecttype(map, type)
elif issubclass(type, Interface):
internal_type = self.construct_interface(map, type)
elif issubclass(type, Scalar):
internal_type = self.construct_scalar(map, type)
elif issubclass(type, Enum):
internal_type = self.construct_enum(map, type)
elif issubclass(type, Union):
internal_type = self.construct_union(map, type)
else:
raise Exception("Expected Graphene type, but received: {}.".format(type))
# if issubclass(type, ObjectType):
# internal_type = self.construct_objecttype(map, type)
# elif issubclass(type, InputObjectType):
# internal_type = self.construct_inputobjecttype(map, type)
# elif issubclass(type, Interface):
# internal_type = self.construct_interface(map, type)
# elif issubclass(type, Scalar):
# internal_type = self.construct_scalar(map, type)
# elif issubclass(type, Enum):
# internal_type = self.construct_enum(map, type)
# elif issubclass(type, Union):
# internal_type = self.construct_union(map, type)
# else:
# raise Exception("Expected Graphene type, but received: {}.".format(type))
return GraphQLTypeMap.reducer(map, internal_type)
# return GraphQLSchema.reducer(map, internal_type)
def construct_scalar(self, map, type):
# We have a mapping to the original GraphQL types
# so there are no collisions.
_scalars = {
String: GraphQLString,
Int: GraphQLInt,
Float: GraphQLFloat,
Boolean: GraphQLBoolean,
ID: GraphQLID,
}
if type in _scalars:
return _scalars[type]
# def construct_scalar(self, map, type):
# # We have a mapping to the original GraphQL types
# # so there are no collisions.
# _scalars = {
# String: GraphQLString,
# Int: GraphQLInt,
# Float: GraphQLFloat,
# Boolean: GraphQLBoolean,
# ID: GraphQLID,
# }
# if type in _scalars:
# return _scalars[type]
return GrapheneScalarType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
serialize=getattr(type, "serialize", None),
parse_value=getattr(type, "parse_value", None),
parse_literal=getattr(type, "parse_literal", None),
)
# return GrapheneScalarType(
# graphene_type=type,
# name=type._meta.name,
# description=type._meta.description,
# serialize=getattr(type, "serialize", None),
# parse_value=getattr(type, "parse_value", None),
# parse_literal=getattr(type, "parse_literal", None),
# )
def construct_enum(self, map, type):
values = OrderedDict()
for name, value in type._meta.enum.__members__.items():
description = getattr(value, "description", None)
deprecation_reason = getattr(value, "deprecation_reason", None)
if not description and callable(type._meta.description):
description = type._meta.description(value)
# def construct_enum(self, map, type):
# values = OrderedDict()
# for name, value in type._meta.enum.__members__.items():
# description = getattr(value, "description", None)
# deprecation_reason = getattr(value, "deprecation_reason", None)
# if not description and callable(type._meta.description):
# description = type._meta.description(value)
if not deprecation_reason and callable(type._meta.deprecation_reason):
deprecation_reason = type._meta.deprecation_reason(value)
# if not deprecation_reason and callable(type._meta.deprecation_reason):
# deprecation_reason = type._meta.deprecation_reason(value)
values[name] = GraphQLEnumValue(
name=name,
value=value.value,
description=description,
deprecation_reason=deprecation_reason,
)
# values[name] = GraphQLEnumValue(
# name=name,
# value=value.value,
# description=description,
# deprecation_reason=deprecation_reason,
# )
type_description = (
type._meta.description(None)
if callable(type._meta.description)
else type._meta.description
)
# type_description = (
# type._meta.description(None)
# if callable(type._meta.description)
# else type._meta.description
# )
return GrapheneEnumType(
graphene_type=type,
values=values,
name=type._meta.name,
description=type_description,
)
# return GrapheneEnumType(
# graphene_type=type,
# values=values,
# name=type._meta.name,
# description=type_description,
# )
def construct_objecttype(self, map, type):
if type._meta.name in map:
_type = map[type._meta.name]
if isinstance(_type, GrapheneGraphQLType):
assert _type.graphene_type == type, (
"Found different types with the same name in the schema: {}, {}."
).format(_type.graphene_type, type)
return _type
# def construct_objecttype(self, map, type):
# if type._meta.name in map:
# _type = map[type._meta.name]
# if isinstance(_type, GrapheneGraphQLType):
# assert _type.graphene_type == type, (
# "Found different types with the same name in the schema: {}, {}."
# ).format(_type.graphene_type, type)
# return _type
def interfaces():
interfaces = []
for interface in type._meta.interfaces:
self.graphene_reducer(map, interface)
internal_type = map[interface._meta.name]
assert internal_type.graphene_type == interface
interfaces.append(internal_type)
return interfaces
# def interfaces():
# interfaces = []
# for interface in type._meta.interfaces:
# self.graphene_reducer(map, interface)
# internal_type = map[interface._meta.name]
# assert internal_type.graphene_type == interface
# interfaces.append(internal_type)
# return interfaces
if type._meta.possible_types:
is_type_of = partial(
is_type_of_from_possible_types, type._meta.possible_types
)
else:
is_type_of = type.is_type_of
# if type._meta.possible_types:
# is_type_of = partial(
# is_type_of_from_possible_types, type._meta.possible_types
# )
# else:
# is_type_of = type.is_type_of
return GrapheneObjectType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
fields=partial(self.construct_fields_for_type, map, type),
is_type_of=is_type_of,
interfaces=interfaces,
)
# return GrapheneObjectType(
# graphene_type=type,
# name=type._meta.name,
# description=type._meta.description,
# fields=partial(self.construct_fields_for_type, map, type),
# is_type_of=is_type_of,
# interfaces=interfaces,
# )
def construct_interface(self, map, type):
if type._meta.name in map:
_type = map[type._meta.name]
if isinstance(_type, GrapheneInterfaceType):
assert _type.graphene_type == type, (
"Found different types with the same name in the schema: {}, {}."
).format(_type.graphene_type, type)
return _type
# def construct_interface(self, map, type):
# if type._meta.name in map:
# _type = map[type._meta.name]
# if isinstance(_type, GrapheneInterfaceType):
# assert _type.graphene_type == type, (
# "Found different types with the same name in the schema: {}, {}."
# ).format(_type.graphene_type, type)
# return _type
_resolve_type = None
if type.resolve_type:
_resolve_type = partial(
resolve_type, type.resolve_type, map, type._meta.name
)
return GrapheneInterfaceType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
fields=partial(self.construct_fields_for_type, map, type),
resolve_type=_resolve_type,
)
# _resolve_type = None
# if type.resolve_type:
# _resolve_type = partial(
# resolve_type, type.resolve_type, map, type._meta.name
# )
# return GrapheneInterfaceType(
# graphene_type=type,
# name=type._meta.name,
# description=type._meta.description,
# fields=partial(self.construct_fields_for_type, map, type),
# resolve_type=_resolve_type,
# )
def construct_inputobjecttype(self, map, type):
return GrapheneInputObjectType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
container_type=type._meta.container,
fields=partial(
self.construct_fields_for_type, map, type, is_input_type=True
),
)
# def construct_inputobjecttype(self, map, type):
# return GrapheneInputObjectType(
# graphene_type=type,
# name=type._meta.name,
# description=type._meta.description,
# container_type=type._meta.container,
# fields=partial(
# self.construct_fields_for_type, map, type, is_input_type=True
# ),
# )
def construct_union(self, map, type):
_resolve_type = None
if type.resolve_type:
_resolve_type = partial(
resolve_type, type.resolve_type, map, type._meta.name
)
# def construct_union(self, map, type):
# _resolve_type = None
# if type.resolve_type:
# _resolve_type = partial(
# resolve_type, type.resolve_type, map, type._meta.name
# )
def types():
union_types = []
for objecttype in type._meta.types:
self.graphene_reducer(map, objecttype)
internal_type = map[objecttype._meta.name]
assert internal_type.graphene_type == objecttype
union_types.append(internal_type)
return union_types
# def types():
# union_types = []
# for objecttype in type._meta.types:
# self.graphene_reducer(map, objecttype)
# internal_type = map[objecttype._meta.name]
# assert internal_type.graphene_type == objecttype
# union_types.append(internal_type)
# return union_types
return GrapheneUnionType(
graphene_type=type,
name=type._meta.name,
description=type._meta.description,
types=types,
resolve_type=_resolve_type,
)
# return GrapheneUnionType(
# graphene_type=type,
# name=type._meta.name,
# description=type._meta.description,
# types=types,
# resolve_type=_resolve_type,
# )
def get_name(self, name):
if self.auto_camelcase:
return to_camel_case(name)
return name
# def get_name(self, name):
# if self.auto_camelcase:
# return to_camel_case(name)
# return name
def construct_fields_for_type(self, map, type, is_input_type=False):
fields = OrderedDict()
for name, field in type._meta.fields.items():
if isinstance(field, Dynamic):
field = get_field_as(field.get_type(self.schema), _as=Field)
if not field:
continue
map = self.reducer(map, field.type)
field_type = self.get_field_type(map, field.type)
if is_input_type:
_field = GraphQLInputObjectField(
field_type,
default_value=field.default_value,
out_name=name,
description=field.description,
)
else:
args = OrderedDict()
for arg_name, arg in field.args.items():
map = self.reducer(map, arg.type)
arg_type = self.get_field_type(map, arg.type)
processed_arg_name = arg.name or self.get_name(arg_name)
args[processed_arg_name] = GraphQLArgument(
arg_type,
out_name=arg_name,
description=arg.description,
default_value=arg.default_value,
)
_field = GraphQLField(
field_type,
args=args,
resolver=field.get_resolver(
self.get_resolver_for_type(type, name, field.default_value)
),
deprecation_reason=field.deprecation_reason,
description=field.description,
)
field_name = field.name or self.get_name(name)
fields[field_name] = _field
return fields
# def construct_fields_for_type(self, map, type, is_input_type=False):
# fields = OrderedDict()
# for name, field in type._meta.fields.items():
# if isinstance(field, Dynamic):
# field = get_field_as(field.get_type(self.schema), _as=Field)
# if not field:
# continue
# map = self.reducer(map, field.type)
# field_type = self.get_field_type(map, field.type)
# if is_input_type:
# _field = GraphQLInputField(
# field_type,
# default_value=field.default_value,
# out_name=name,
# description=field.description,
# )
# else:
# args = OrderedDict()
# for arg_name, arg in field.args.items():
# map = self.reducer(map, arg.type)
# arg_type = self.get_field_type(map, arg.type)
# processed_arg_name = arg.name or self.get_name(arg_name)
# args[processed_arg_name] = GraphQLArgument(
# arg_type,
# out_name=arg_name,
# description=arg.description,
# default_value=arg.default_value,
# )
# _field = GraphQLField(
# field_type,
# args=args,
# resolver=field.get_resolver(
# self.get_resolver_for_type(type, name, field.default_value)
# ),
# deprecation_reason=field.deprecation_reason,
# description=field.description,
# )
# field_name = field.name or self.get_name(name)
# fields[field_name] = _field
# return fields
def get_resolver_for_type(self, type, name, default_value):
if not issubclass(type, ObjectType):
return
resolver = getattr(type, "resolve_{}".format(name), None)
if not resolver:
# If we don't find the resolver in the ObjectType class, then try to
# find it in each of the interfaces
interface_resolver = None
for interface in type._meta.interfaces:
if name not in interface._meta.fields:
continue
interface_resolver = getattr(interface, "resolve_{}".format(name), None)
if interface_resolver:
break
resolver = interface_resolver
# def get_resolver_for_type(self, type, name, default_value):
# if not issubclass(type, ObjectType):
# return
# resolver = getattr(type, "resolve_{}".format(name), None)
# if not resolver:
# # If we don't find the resolver in the ObjectType class, then try to
# # find it in each of the interfaces
# interface_resolver = None
# for interface in type._meta.interfaces:
# if name not in interface._meta.fields:
# continue
# interface_resolver = getattr(interface, "resolve_{}".format(name), None)
# if interface_resolver:
# break
# resolver = interface_resolver
# Only if is not decorated with classmethod
if resolver:
return get_unbound_function(resolver)
# # Only if is not decorated with classmethod
# if resolver:
# return get_unbound_function(resolver)
default_resolver = type._meta.default_resolver or get_default_resolver()
return partial(default_resolver, name, default_value)
# default_resolver = type._meta.default_resolver or get_default_resolver()
# return partial(default_resolver, name, default_value)
def get_field_type(self, map, type):
if isinstance(type, List):
return GraphQLList(self.get_field_type(map, type.of_type))
if isinstance(type, NonNull):
return GraphQLNonNull(self.get_field_type(map, type.of_type))
return map.get(type._meta.name)
# def get_field_type(self, map, type):
# if isinstance(type, List):
# return GraphQLList(self.get_field_type(map, type.of_type))
# if isinstance(type, NonNull):
# return GraphQLNonNull(self.get_field_type(map, type.of_type))
# return map.get(type._meta.name)

View File

@ -0,0 +1,7 @@
from .helpers import base64, unbase64, is_str
__all__ = [
"base64",
"unbase64",
"is_str"
]

13
graphene/utils/helpers.py Normal file
View File

@ -0,0 +1,13 @@
from base64 import b64encode as _base64, b64decode as _unbase64
def base64(s):
return _base64(s.encode('utf-8')).decode('utf-8')
def unbase64(s):
return _unbase64(s).decode('utf-8')
def is_str(s):
return isinstance(s, str)

View File

@ -73,8 +73,6 @@ setup(
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
@ -86,8 +84,7 @@ setup(
packages=find_packages(exclude=["tests", "tests.*", "examples"]),
install_requires=[
"six>=1.10.0,<2",
"graphql-core>=2.1,<3",
"graphql-relay>=0.4.5,<1",
"graphql-core-next==1.0.3",
"aniso8601>=3,<4",
],
tests_require=tests_require,

View File

@ -1,5 +1,5 @@
[tox]
envlist = flake8,py27,py34,py35,py36,py37,pre-commit,pypy,mypy
envlist = flake8,py34,py35,py36,py37,pre-commit,pypy,mypy
skipsdist = true
[testenv]
@ -9,7 +9,7 @@ deps =
setenv =
PYTHONPATH = .:{envdir}
commands =
py{27,34,py}: py.test --cov=graphene graphene examples {posargs}
py{34,py}: py.test --cov=graphene graphene examples {posargs}
py{35,36,37}: py.test --cov=graphene graphene examples tests_asyncio {posargs}
[testenv:pre-commit]