This commit is contained in:
Kaushik Asp 2018-07-28 10:00:38 +00:00 committed by GitHub
commit 854324cf22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 197 additions and 106 deletions

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
import datetime import datetime
import os import os
import subprocess import subprocess
from ..utils.comparison_helper import raise_assertion_if
def get_version(version=None): def get_version(version=None):
@ -44,8 +45,14 @@ def get_complete_version(version=None):
if version is None: if version is None:
from graphene import VERSION as version from graphene import VERSION as version
else: else:
assert len(version) == 5 raise_assertion_if(
assert version[3] in ("alpha", "beta", "rc", "final") condition=len(version) is not 5, message="Version needs to be 5"
)
raise_assertion_if(
condition=version[3] not in ("alpha", "beta", "rc", "final"),
message="Release version is unkown",
)
return version return version

View File

@ -9,6 +9,7 @@ from ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String
from ..types.field import Field from ..types.field import Field
from ..types.objecttype import ObjectType, ObjectTypeOptions from ..types.objecttype import ObjectType, ObjectTypeOptions
from .node import is_node from .node import is_node
from ..utils.comparison_helper import raise_assertion_if
class PageInfo(ObjectType): class PageInfo(ObjectType):
@ -46,12 +47,18 @@ class Connection(ObjectType):
@classmethod @classmethod
def __init_subclass_with_meta__(cls, node=None, name=None, **options): def __init_subclass_with_meta__(cls, node=None, name=None, **options):
_meta = ConnectionOptions(cls) _meta = ConnectionOptions(cls)
assert node, "You have to provide a node in {}.Meta".format(cls.__name__) error_message = "You have to provide a node in {}.Meta".format(cls.__name__)
assert issubclass( raise_assertion_if(condition=not node, message=error_message)
node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
), ('Received incompatible node "{}" for Connection {}.').format( error_message = 'Received incompatible node "{}" for Connection {}.'.format(
node, cls.__name__ node, cls.__name__
) )
raise_assertion_if(
condition=not issubclass(
node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
),
error_message=error_message,
)
base_name = re.sub("Connection$", "", name or cls.__name__) or node._meta.name base_name = re.sub("Connection$", "", name or cls.__name__) or node._meta.name
if not name: if not name:
@ -101,15 +108,20 @@ class IterableConnectionField(Field):
if isinstance(type, NonNull): if isinstance(type, NonNull):
connection_type = type.of_type connection_type = type.of_type
if is_node(connection_type): error_message = """
raise Exception( ConnectionField's now need a explicit ConnectionType for Nodes.
"ConnectionField's now need a explicit ConnectionType for Nodes.\n" Read more: https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#node-connections
"Read more: https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#node-connections" """
raise_assertion_if(
condition=is_node(connection_type), error_message=error_message
) )
assert issubclass(connection_type, Connection), ( error_message = '{} type have to be a subclass of Connection. Received "{}".'.format(
'{} type have to be a subclass of Connection. Received "{}".' self.__class__.__name__, connection_type
).format(self.__class__.__name__, connection_type) )
raise_assertion_if(
condition=not issubclass(connection_type, Connection), message=error_message
)
return type return type
@classmethod @classmethod
@ -117,10 +129,16 @@ class IterableConnectionField(Field):
if isinstance(resolved, connection_type): if isinstance(resolved, connection_type):
return resolved return resolved
assert isinstance(resolved, Iterable), ( error_message = """
"Resolved value from the connection field have to be iterable or instance of {}. " Resolved value from the connection field have to be iterable or instance of {}.
'Received "{}"' Received "{}"
).format(connection_type, resolved) """.format(
connection_type, resolved
)
raise_assertion_if(
condition=not isinstance(resolved, Iterable), message=error_message
)
connection = connection_from_list( connection = connection_from_list(
resolved, resolved,
args, args,

View File

@ -18,8 +18,11 @@ class ClientIDMutation(Mutation):
input_class = getattr(cls, "Input", None) input_class = getattr(cls, "Input", None)
base_name = re.sub("Payload$", "", name or cls.__name__) base_name = re.sub("Payload$", "", name or cls.__name__)
assert not output, "Can't specify any output" if output:
assert not arguments, "Can't specify any arguments" raise AssertionError("Can't specify any output")
if arguments:
raise AssertionError("Can't specify any arguments")
bases = (InputObjectType,) bases = (InputObjectType,)
if input_class: if input_class:
@ -42,10 +45,12 @@ class ClientIDMutation(Mutation):
) )
mutate_and_get_payload = getattr(cls, "mutate_and_get_payload", None) mutate_and_get_payload = getattr(cls, "mutate_and_get_payload", None)
if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__: if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:
assert mutate_and_get_payload, ( if not mutate_and_get_payload:
"{name}.mutate_and_get_payload method is required" raise AssertionError(
" in a ClientIDMutation." "{name}.mutate_and_get_payload method is required in a ClientIDMutation.".format(
).format(name=name or cls.__name__) name=name or cls.__name__
)
)
if not name: if not name:
name = "{}Payload".format(base_name) name = "{}Payload".format(base_name)

View File

@ -49,7 +49,8 @@ class GlobalID(Field):
class NodeField(Field): class NodeField(Field):
def __init__(self, node, type=False, deprecation_reason=None, name=None, **kwargs): def __init__(self, node, type=False, deprecation_reason=None, name=None, **kwargs):
assert issubclass(node, Node), "NodeField can only operate in Nodes" if not issubclass(node, Node):
raise AssertionError("NodeField can only operate in Nodes")
self.node_type = node self.node_type = node
self.field_type = type self.field_type = type
@ -98,8 +99,9 @@ class Node(AbstractNode):
return None return None
if only_type: if only_type:
assert graphene_type == only_type, ("Must receive a {} id.").format( if graphene_type != only_type:
only_type._meta.name raise AssertionError(
"Must receive a {} id.".format(only_type._meta.name)
) )
# We make sure the ObjectType implements the "Node" interface # We make sure the ObjectType implements the "Node" interface

View File

@ -73,10 +73,9 @@ def to_arguments(args, extra_args=None):
raise ValueError('Unknown argument "{}".'.format(default_name)) raise ValueError('Unknown argument "{}".'.format(default_name))
arg_name = default_name or arg.name arg_name = default_name or arg.name
assert ( if arg_name in arguments:
arg_name not in arguments raise AssertionError(
), 'More than one Argument have same name "{}".'.format( 'More than one Argument have same name "{}".'.format(arg_name)
arg_name
) )
arguments[arg_name] = arg arguments[arg_name] = arg

View File

@ -31,7 +31,8 @@ class BaseType(SubclassWithMeta):
@classmethod @classmethod
def __init_subclass_with_meta__(cls, name=None, description=None, _meta=None): def __init_subclass_with_meta__(cls, name=None, description=None, _meta=None):
assert "_meta" not in cls.__dict__, "Can't assign directly meta" if "_meta" in cls.__dict__:
raise AssertionError("Can't assign meta directly")
if not _meta: if not _meta:
return return
_meta.name = name or cls.__name__ _meta.name = name or cls.__name__

View File

@ -19,9 +19,8 @@ class Date(Scalar):
def serialize(date): def serialize(date):
if isinstance(date, datetime.datetime): if isinstance(date, datetime.datetime):
date = date.date() date = date.date()
assert isinstance( if not isinstance(date, datetime.date):
date, datetime.date raise AssertionError('Received not compatible date "{}"'.format(repr(date)))
), 'Received not compatible date "{}"'.format(repr(date))
return date.isoformat() return date.isoformat()
@classmethod @classmethod
@ -46,9 +45,10 @@ class DateTime(Scalar):
@staticmethod @staticmethod
def serialize(dt): def serialize(dt):
assert isinstance( if not isinstance(dt, (datetime.datetime, datetime.date)):
dt, (datetime.datetime, datetime.date) raise AssertionError(
), 'Received not compatible datetime "{}"'.format(repr(dt)) 'Received not compatible datetime "{}"'.format(repr(dt))
)
return dt.isoformat() return dt.isoformat()
@classmethod @classmethod
@ -73,9 +73,8 @@ class Time(Scalar):
@staticmethod @staticmethod
def serialize(time): def serialize(time):
assert isinstance( if not isinstance(time, datetime.time):
time, datetime.time raise AssertionError('Received not compatible time "{}"'.format(repr(time)))
), 'Received not compatible time "{}"'.format(repr(time))
return time.isoformat() return time.isoformat()
@classmethod @classmethod

View File

@ -12,7 +12,10 @@ class Dynamic(MountedType):
def __init__(self, type, with_schema=False, _creation_counter=None): def __init__(self, type, with_schema=False, _creation_counter=None):
super(Dynamic, self).__init__(_creation_counter=_creation_counter) super(Dynamic, self).__init__(_creation_counter=_creation_counter)
assert inspect.isfunction(type) or isinstance(type, partial) if not (inspect.isfunction(type) or isinstance(type, partial)):
raise AssertionError(
"type is expected to be a function or an instance of partial"
)
self.type = type self.type = type
self.with_schema = with_schema self.with_schema = with_schema

View File

@ -34,15 +34,21 @@ class Field(MountedType):
**extra_args **extra_args
): ):
super(Field, self).__init__(_creation_counter=_creation_counter) super(Field, self).__init__(_creation_counter=_creation_counter)
assert not args or isinstance(args, Mapping), (
'Arguments in a field have to be a mapping, received "{}".' if args and not isinstance(args, Mapping):
).format(args) raise AssertionError(
assert not ( 'Arguments in a field have to be a mapping, received "{}".'.format(args)
source and resolver )
), "A Field cannot have a source and a resolver in at the same time." if source and resolver:
assert not callable(default_value), ( raise AssertionError(
'The default value can not be a function but received "{}".' "A Field cannot have a source and a resolver in at the same time."
).format(base_type(default_value)) )
if callable(default_value):
raise AssertionError(
'The default value can not be a function but received "{}".'.format(
base_type(default_value)
)
)
if required: if required:
type = NonNull(type) type = NonNull(type)

View File

@ -8,8 +8,9 @@ class MountedType(OrderedType):
""" """
Mount the UnmountedType instance Mount the UnmountedType instance
""" """
assert isinstance(unmounted, UnmountedType), ("{} can't mount {}").format( if not isinstance(unmounted, UnmountedType):
cls.__name__, repr(unmounted) raise AssertionError(
"{} can't mount {}".format(cls.__name__, repr(unmounted))
) )
return cls( return cls(

View File

@ -47,10 +47,15 @@ class ObjectType(BaseType):
for base in reversed(cls.__mro__): for base in reversed(cls.__mro__):
fields.update(yank_fields_from_attrs(base.__dict__, _as=Field)) fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))
assert not (possible_types and cls.is_type_of), ( if possible_types and cls.is_type_of:
"{name}.Meta.possible_types will cause type collision with {name}.is_type_of. " raise AssertionError(
"Please use one or other." """
).format(name=cls.__name__) {name}.Meta.possible_types will cause type collision with {name}.is_type_of.
Please use one or other.
""".format(
name=cls.__name__
)
)
if _meta.fields: if _meta.fields:
_meta.fields.update(fields) _meta.fields.update(fields)

View File

@ -11,7 +11,8 @@ default_resolver = attr_resolver
def set_default_resolver(resolver): def set_default_resolver(resolver):
global default_resolver global default_resolver
assert callable(resolver), "Received non-callable resolver." if not callable(resolver):
raise AssertionError("Received non-callable resolver.")
default_resolver = resolver default_resolver = resolver

View File

@ -20,9 +20,8 @@ def assert_valid_root_type(_type):
return return
is_graphene_objecttype = inspect.isclass(_type) and issubclass(_type, ObjectType) is_graphene_objecttype = inspect.isclass(_type) and issubclass(_type, ObjectType)
is_graphql_objecttype = isinstance(_type, GraphQLObjectType) is_graphql_objecttype = isinstance(_type, GraphQLObjectType)
assert is_graphene_objecttype or is_graphql_objecttype, ( if not (is_graphene_objecttype or is_graphql_objecttype):
"Type {} is not a valid ObjectType." raise AssertionError("Type {} is not a valid ObjectType.".format(_type))
).format(_type)
class Schema(GraphQLSchema): class Schema(GraphQLSchema):
@ -53,11 +52,12 @@ class Schema(GraphQLSchema):
if directives is None: if directives is None:
directives = [GraphQLIncludeDirective, GraphQLSkipDirective] directives = [GraphQLIncludeDirective, GraphQLSkipDirective]
assert all( if not all(isinstance(d, GraphQLDirective) for d in directives):
isinstance(d, GraphQLDirective) for d in directives raise AssertionError(
), "Schema directives must be List[GraphQLDirective] if provided but got: {}.".format( "Schema directives must be List[GraphQLDirective] if provided but got: {}.".format(
directives directives
) )
)
self._directives = directives self._directives = directives
self.build_typemap() self.build_typemap()
@ -91,10 +91,16 @@ class Schema(GraphQLSchema):
return _type return _type
if is_graphene_type(_type): if is_graphene_type(_type):
graphql_type = self.get_type(_type._meta.name) graphql_type = self.get_type(_type._meta.name)
assert graphql_type, "Type {} not found in this schema.".format( if not graphql_type:
_type._meta.name raise AssertionError(
"Type {} not found in this schema.".format(_type._meta.name)
)
if graphql_type.graphene_type != _type:
raise AssertionError(
"The type {} does not match with the associated graphene type {}.".format(
_type, graphql_type.graphene_type
)
) )
assert graphql_type.graphene_type == _type
return graphql_type return graphql_type
raise Exception("{} is not a valid GraphQL type.".format(_type)) raise Exception("{} is not a valid GraphQL type.".format(_type))

View File

@ -228,10 +228,13 @@ def test_objecttype_with_possible_types_and_is_type_of_should_raise():
def is_type_of(cls, root, context, info): def is_type_of(cls, root, context, info):
return False return False
assert str(excinfo.value) == ( assertion_message = """
"MyObjectType.Meta.possible_types will cause type collision with " MyObjectType.Meta.possible_types will cause type collision with MyObjectType.is_type_of.
"MyObjectType.is_type_of. Please use one or other." Please use one or other.
) """
space_removed_excinfo = str(excinfo.value).replace(" ", "")
space_removed_assertion_message = assertion_message.replace(" ", "")
assert space_removed_assertion_message == space_removed_excinfo
def test_objecttype_no_fields_output(): def test_objecttype_no_fields_output():

View File

@ -60,10 +60,16 @@ def resolve_type(resolve_type_func, map, type_name, root, info):
if inspect.isclass(_type) and issubclass(_type, ObjectType): if inspect.isclass(_type) and issubclass(_type, ObjectType):
graphql_type = map.get(_type._meta.name) graphql_type = map.get(_type._meta.name)
assert graphql_type, "Can't find type {} in schema".format(_type._meta.name) if not graphql_type:
assert graphql_type.graphene_type == _type, ( raise AssertionError(
"The type {} does not match with the associated graphene type {}." "Can't find type {} in schema".format(_type._meta.name)
).format(_type, graphql_type.graphene_type) )
if graphql_type.graphene_type != _type:
raise AssertionError(
"The type {} does not match with the associated graphene type {}.".format(
_type, graphql_type.graphene_type
)
)
return graphql_type return graphql_type
return _type return _type
@ -94,9 +100,12 @@ class TypeMap(GraphQLTypeMap):
if type._meta.name in map: if type._meta.name in map:
_type = map[type._meta.name] _type = map[type._meta.name]
if isinstance(_type, GrapheneGraphQLType): if isinstance(_type, GrapheneGraphQLType):
assert _type.graphene_type == type, ( if _type.graphene_type is not type:
"Found different types with the same name in the schema: {}, {}." raise AssertionError(
).format(_type.graphene_type, type) "Found different types with the same name in the schema: {}, {}.".format(
_type.graphene_type, type
)
)
return map return map
if issubclass(type, ObjectType): if issubclass(type, ObjectType):
@ -173,9 +182,12 @@ class TypeMap(GraphQLTypeMap):
if type._meta.name in map: if type._meta.name in map:
_type = map[type._meta.name] _type = map[type._meta.name]
if isinstance(_type, GrapheneGraphQLType): if isinstance(_type, GrapheneGraphQLType):
assert _type.graphene_type == type, ( if _type.graphene_type != type:
"Found different types with the same name in the schema: {}, {}." raise AssertionError(
).format(_type.graphene_type, type) "Found different types with the same name in the schema: {}, {}.".format(
_type.graphene_type, type
)
)
return _type return _type
def interfaces(): def interfaces():
@ -183,7 +195,12 @@ class TypeMap(GraphQLTypeMap):
for interface in type._meta.interfaces: for interface in type._meta.interfaces:
self.graphene_reducer(map, interface) self.graphene_reducer(map, interface)
internal_type = map[interface._meta.name] internal_type = map[interface._meta.name]
assert internal_type.graphene_type == interface if internal_type.graphene_type != interface:
raise AssertionError(
"Found different types with the same name in the schema: {}, {}.".format(
internal_type.graphene_type, interface
)
)
interfaces.append(internal_type) interfaces.append(internal_type)
return interfaces return interfaces
@ -207,9 +224,12 @@ class TypeMap(GraphQLTypeMap):
if type._meta.name in map: if type._meta.name in map:
_type = map[type._meta.name] _type = map[type._meta.name]
if isinstance(_type, GrapheneInterfaceType): if isinstance(_type, GrapheneInterfaceType):
assert _type.graphene_type == type, ( if _type.graphene_type != type:
"Found different types with the same name in the schema: {}, {}." raise AssertionError(
).format(_type.graphene_type, type) "Found different types with the same name in the schema: {}, {}.".format(
_type.graphene_type, type
)
)
return _type return _type
_resolve_type = None _resolve_type = None
@ -248,7 +268,12 @@ class TypeMap(GraphQLTypeMap):
for objecttype in type._meta.types: for objecttype in type._meta.types:
self.graphene_reducer(map, objecttype) self.graphene_reducer(map, objecttype)
internal_type = map[objecttype._meta.name] internal_type = map[objecttype._meta.name]
assert internal_type.graphene_type == objecttype if internal_type.graphene_type != objecttype:
raise AssertionError(
"Found different types with the same name in the schema: {}, {}.".format(
internal_type.graphene_type, objecttype
)
)
union_types.append(internal_type) union_types.append(internal_type)
return union_types return union_types

View File

@ -23,10 +23,10 @@ class Union(UnmountedType, BaseType):
@classmethod @classmethod
def __init_subclass_with_meta__(cls, types=None, **options): def __init_subclass_with_meta__(cls, types=None, **options):
assert ( if not (isinstance(types, (list, tuple)) and len(types) > 0):
isinstance(types, (list, tuple)) and len(types) > 0 raise AssertionError(
), "Must provide types for Union {name}.".format(name=cls.__name__) "Must provide types for Union {name}.".format(name=cls.__name__)
)
_meta = UnionOptions(cls) _meta = UnionOptions(cls)
_meta.types = types _meta.types = types
super(Union, cls).__init_subclass_with_meta__(_meta=_meta, **options) super(Union, cls).__init_subclass_with_meta__(_meta=_meta, **options)

View File

@ -14,9 +14,8 @@ class UUID(Scalar):
def serialize(uuid): def serialize(uuid):
if isinstance(uuid, str): if isinstance(uuid, str):
uuid = _UUID(uuid) uuid = _UUID(uuid)
assert isinstance(uuid, _UUID), "Expected UUID instance, received {}".format( if not isinstance(uuid, _UUID):
uuid raise AssertionError("Expected UUID instance, received {}".format(uuid))
)
return str(uuid) return str(uuid)
@staticmethod @staticmethod

View File

@ -22,9 +22,12 @@ def annotate(_func=None, _trigger_warning=True, **annotations):
# We make sure the annotations are valid # We make sure the annotations are valid
for key, value in annotations.items(): for key, value in annotations.items():
assert key in func_signature.parameters, ( if func_signature.parameters.get(key, None) is None:
'The key {key} is not a function parameter in the function "{func_name}".' raise AssertionError(
).format(key=key, func_name=func_name(_func)) 'The key {key} is not a function parameter in the function "{func_name}".'.format(
key=key, func_name=func_name(_func)
)
)
func_annotations = getattr(_func, "__annotations__", None) func_annotations = getattr(_func, "__annotations__", None)
if func_annotations is None: if func_annotations is None:

View File

@ -0,0 +1,3 @@
def raise_assertion_if(condition=None, message=None):
if condition:
raise AssertionError(message)

View File

@ -42,10 +42,15 @@ class SubclassWithMeta(six.with_metaclass(SubclassWithMeta_Meta)):
abstract = options.pop("abstract", False) abstract = options.pop("abstract", False)
if abstract: if abstract:
assert not options, ( if options:
"Abstract types can only contain the abstract attribute. " raise AssertionError(
"Received: abstract, {option_keys}" """
).format(option_keys=", ".join(options.keys())) Abstract types can only contain the abstract attribute.
Received: abstract, {option_keys}
""".format(
option_keys=", ".join(options.keys())
)
)
else: else:
super_class = super(cls, cls) super_class = super(cls, cls)
if hasattr(super_class, "__init_subclass_with_meta__"): if hasattr(super_class, "__init_subclass_with_meta__"):