diff --git a/graphene/pyutils/version.py b/graphene/pyutils/version.py index f2005442..de329c43 100644 --- a/graphene/pyutils/version.py +++ b/graphene/pyutils/version.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import datetime import os import subprocess +from ..utils.comparison_helper import raise_assertion_if def get_version(version=None): @@ -44,8 +45,14 @@ def get_complete_version(version=None): if version is None: from graphene import VERSION as version else: - assert len(version) == 5 - assert version[3] in ("alpha", "beta", "rc", "final") + raise_assertion_if( + 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 diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index f23849f2..c195ae42 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -9,6 +9,7 @@ from ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String from ..types.field import Field from ..types.objecttype import ObjectType, ObjectTypeOptions from .node import is_node +from ..utils.comparison_helper import raise_assertion_if class PageInfo(ObjectType): @@ -46,12 +47,18 @@ class Connection(ObjectType): @classmethod def __init_subclass_with_meta__(cls, node=None, name=None, **options): _meta = ConnectionOptions(cls) - assert node, "You have to provide a node in {}.Meta".format(cls.__name__) - assert issubclass( - node, (Scalar, Enum, ObjectType, Interface, Union, NonNull) - ), ('Received incompatible node "{}" for Connection {}.').format( + error_message = "You have to provide a node in {}.Meta".format(cls.__name__) + raise_assertion_if(condition=not node, message=error_message) + + error_message = 'Received incompatible node "{}" for Connection {}.'.format( 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 if not name: @@ -101,15 +108,20 @@ class IterableConnectionField(Field): if isinstance(type, NonNull): connection_type = type.of_type - if is_node(connection_type): - raise Exception( - "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" - ) + error_message = """ + ConnectionField's now need a explicit ConnectionType for Nodes. + 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), ( - '{} type have to be a subclass of Connection. Received "{}".' - ).format(self.__class__.__name__, connection_type) + error_message = '{} type have to be a subclass of Connection. Received "{}".'.format( + self.__class__.__name__, connection_type + ) + raise_assertion_if( + condition=not issubclass(connection_type, Connection), message=error_message + ) return type @classmethod @@ -117,10 +129,16 @@ class IterableConnectionField(Field): if isinstance(resolved, connection_type): return resolved - assert isinstance(resolved, Iterable), ( - "Resolved value from the connection field have to be iterable or instance of {}. " - 'Received "{}"' - ).format(connection_type, resolved) + error_message = """ + Resolved value from the connection field have to be iterable or instance of {}. + Received "{}" + """.format( + connection_type, resolved + ) + raise_assertion_if( + condition=not isinstance(resolved, Iterable), message=error_message + ) + connection = connection_from_list( resolved, args, diff --git a/graphene/relay/mutation.py b/graphene/relay/mutation.py index 1b8b855e..211ee44f 100644 --- a/graphene/relay/mutation.py +++ b/graphene/relay/mutation.py @@ -18,8 +18,11 @@ class ClientIDMutation(Mutation): input_class = getattr(cls, "Input", None) base_name = re.sub("Payload$", "", name or cls.__name__) - assert not output, "Can't specify any output" - assert not arguments, "Can't specify any arguments" + if output: + raise AssertionError("Can't specify any output") + + if arguments: + raise AssertionError("Can't specify any arguments") bases = (InputObjectType,) if input_class: @@ -42,10 +45,12 @@ class ClientIDMutation(Mutation): ) mutate_and_get_payload = getattr(cls, "mutate_and_get_payload", None) if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__: - assert mutate_and_get_payload, ( - "{name}.mutate_and_get_payload method is required" - " in a ClientIDMutation." - ).format(name=name or cls.__name__) + if not mutate_and_get_payload: + raise AssertionError( + "{name}.mutate_and_get_payload method is required in a ClientIDMutation.".format( + name=name or cls.__name__ + ) + ) if not name: name = "{}Payload".format(base_name) diff --git a/graphene/relay/node.py b/graphene/relay/node.py index d9c4c0f6..44020ae3 100644 --- a/graphene/relay/node.py +++ b/graphene/relay/node.py @@ -49,7 +49,8 @@ class GlobalID(Field): class NodeField(Field): 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.field_type = type @@ -98,9 +99,10 @@ class Node(AbstractNode): return None if only_type: - assert graphene_type == only_type, ("Must receive a {} id.").format( - only_type._meta.name - ) + if graphene_type != only_type: + raise AssertionError( + "Must receive a {} id.".format(only_type._meta.name) + ) # We make sure the ObjectType implements the "Node" interface if cls not in graphene_type._meta.interfaces: diff --git a/graphene/types/argument.py b/graphene/types/argument.py index 9c75bcee..326e173d 100644 --- a/graphene/types/argument.py +++ b/graphene/types/argument.py @@ -73,11 +73,10 @@ def to_arguments(args, extra_args=None): raise ValueError('Unknown argument "{}".'.format(default_name)) arg_name = default_name or arg.name - assert ( - arg_name not in arguments - ), 'More than one Argument have same name "{}".'.format( - arg_name - ) + if arg_name in arguments: + raise AssertionError( + 'More than one Argument have same name "{}".'.format(arg_name) + ) arguments[arg_name] = arg return arguments diff --git a/graphene/types/base.py b/graphene/types/base.py index aa97ed22..1b4d4034 100644 --- a/graphene/types/base.py +++ b/graphene/types/base.py @@ -31,7 +31,8 @@ class BaseType(SubclassWithMeta): @classmethod 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: return _meta.name = name or cls.__name__ diff --git a/graphene/types/datetime.py b/graphene/types/datetime.py index 739032b0..3aa38c98 100644 --- a/graphene/types/datetime.py +++ b/graphene/types/datetime.py @@ -19,9 +19,8 @@ class Date(Scalar): def serialize(date): if isinstance(date, datetime.datetime): date = date.date() - assert isinstance( - date, datetime.date - ), 'Received not compatible date "{}"'.format(repr(date)) + if not isinstance(date, datetime.date): + raise AssertionError('Received not compatible date "{}"'.format(repr(date))) return date.isoformat() @classmethod @@ -46,9 +45,10 @@ class DateTime(Scalar): @staticmethod def serialize(dt): - assert isinstance( - dt, (datetime.datetime, datetime.date) - ), 'Received not compatible datetime "{}"'.format(repr(dt)) + if not isinstance(dt, (datetime.datetime, datetime.date)): + raise AssertionError( + 'Received not compatible datetime "{}"'.format(repr(dt)) + ) return dt.isoformat() @classmethod @@ -73,9 +73,8 @@ class Time(Scalar): @staticmethod def serialize(time): - assert isinstance( - time, datetime.time - ), 'Received not compatible time "{}"'.format(repr(time)) + if not isinstance(time, datetime.time): + raise AssertionError('Received not compatible time "{}"'.format(repr(time))) return time.isoformat() @classmethod diff --git a/graphene/types/dynamic.py b/graphene/types/dynamic.py index 588c53bb..d7747644 100644 --- a/graphene/types/dynamic.py +++ b/graphene/types/dynamic.py @@ -12,7 +12,10 @@ class Dynamic(MountedType): def __init__(self, type, with_schema=False, _creation_counter=None): 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.with_schema = with_schema diff --git a/graphene/types/field.py b/graphene/types/field.py index a1428632..a42d131a 100644 --- a/graphene/types/field.py +++ b/graphene/types/field.py @@ -34,15 +34,21 @@ class Field(MountedType): **extra_args ): 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 "{}".' - ).format(args) - assert not ( - source and resolver - ), "A Field cannot have a source and a resolver in at the same time." - assert not callable(default_value), ( - 'The default value can not be a function but received "{}".' - ).format(base_type(default_value)) + + if args and not isinstance(args, Mapping): + raise AssertionError( + 'Arguments in a field have to be a mapping, received "{}".'.format(args) + ) + if source and resolver: + raise AssertionError( + "A Field cannot have a source and a resolver in at the same time." + ) + if callable(default_value): + raise AssertionError( + 'The default value can not be a function but received "{}".'.format( + base_type(default_value) + ) + ) if required: type = NonNull(type) diff --git a/graphene/types/mountedtype.py b/graphene/types/mountedtype.py index 6d0c8cf8..fc4efb85 100644 --- a/graphene/types/mountedtype.py +++ b/graphene/types/mountedtype.py @@ -8,9 +8,10 @@ class MountedType(OrderedType): """ Mount the UnmountedType instance """ - assert isinstance(unmounted, UnmountedType), ("{} can't mount {}").format( - cls.__name__, repr(unmounted) - ) + if not isinstance(unmounted, UnmountedType): + raise AssertionError( + "{} can't mount {}".format(cls.__name__, repr(unmounted)) + ) return cls( unmounted.get_type(), diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py index be4addb2..2be97358 100644 --- a/graphene/types/objecttype.py +++ b/graphene/types/objecttype.py @@ -47,10 +47,15 @@ class ObjectType(BaseType): for base in reversed(cls.__mro__): fields.update(yank_fields_from_attrs(base.__dict__, _as=Field)) - assert not (possible_types and cls.is_type_of), ( - "{name}.Meta.possible_types will cause type collision with {name}.is_type_of. " - "Please use one or other." - ).format(name=cls.__name__) + if possible_types and cls.is_type_of: + raise AssertionError( + """ + {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: _meta.fields.update(fields) diff --git a/graphene/types/resolver.py b/graphene/types/resolver.py index 888aba8a..d9151b2a 100644 --- a/graphene/types/resolver.py +++ b/graphene/types/resolver.py @@ -11,7 +11,8 @@ default_resolver = attr_resolver def set_default_resolver(resolver): global default_resolver - assert callable(resolver), "Received non-callable resolver." + if not callable(resolver): + raise AssertionError("Received non-callable resolver.") default_resolver = resolver diff --git a/graphene/types/schema.py b/graphene/types/schema.py index a885c88a..9250f86d 100644 --- a/graphene/types/schema.py +++ b/graphene/types/schema.py @@ -20,9 +20,8 @@ def assert_valid_root_type(_type): return is_graphene_objecttype = inspect.isclass(_type) and issubclass(_type, ObjectType) is_graphql_objecttype = isinstance(_type, GraphQLObjectType) - assert is_graphene_objecttype or is_graphql_objecttype, ( - "Type {} is not a valid ObjectType." - ).format(_type) + if not (is_graphene_objecttype or is_graphql_objecttype): + raise AssertionError("Type {} is not a valid ObjectType.".format(_type)) class Schema(GraphQLSchema): @@ -53,11 +52,12 @@ class Schema(GraphQLSchema): 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 - ) + if not all(isinstance(d, GraphQLDirective) for d in directives): + raise AssertionError( + "Schema directives must be List[GraphQLDirective] if provided but got: {}.".format( + directives + ) + ) self._directives = directives self.build_typemap() @@ -91,10 +91,16 @@ class Schema(GraphQLSchema): 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 + if not graphql_type: + 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 + ) + ) return graphql_type raise Exception("{} is not a valid GraphQL type.".format(_type)) diff --git a/graphene/types/tests/test_objecttype.py b/graphene/types/tests/test_objecttype.py index 2acb578f..d7cdd992 100644 --- a/graphene/types/tests/test_objecttype.py +++ b/graphene/types/tests/test_objecttype.py @@ -228,10 +228,13 @@ def test_objecttype_with_possible_types_and_is_type_of_should_raise(): def is_type_of(cls, root, context, info): return False - assert str(excinfo.value) == ( - "MyObjectType.Meta.possible_types will cause type collision with " - "MyObjectType.is_type_of. Please use one or other." - ) + assertion_message = """ + MyObjectType.Meta.possible_types will cause type collision with MyObjectType.is_type_of. + 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(): diff --git a/graphene/types/typemap.py b/graphene/types/typemap.py index dce04445..f34cd50e 100644 --- a/graphene/types/typemap.py +++ b/graphene/types/typemap.py @@ -60,10 +60,16 @@ def resolve_type(resolve_type_func, map, type_name, root, info): if inspect.isclass(_type) and issubclass(_type, ObjectType): graphql_type = map.get(_type._meta.name) - assert graphql_type, "Can't find type {} in schema".format(_type._meta.name) - assert graphql_type.graphene_type == _type, ( - "The type {} does not match with the associated graphene type {}." - ).format(_type, graphql_type.graphene_type) + if not graphql_type: + raise AssertionError( + "Can't find type {} in 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 + ) + ) return graphql_type return _type @@ -94,9 +100,12 @@ class TypeMap(GraphQLTypeMap): 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) + if _type.graphene_type is not type: + raise AssertionError( + "Found different types with the same name in the schema: {}, {}.".format( + _type.graphene_type, type + ) + ) return map if issubclass(type, ObjectType): @@ -173,9 +182,12 @@ class TypeMap(GraphQLTypeMap): 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) + if _type.graphene_type != type: + raise AssertionError( + "Found different types with the same name in the schema: {}, {}.".format( + _type.graphene_type, type + ) + ) return _type def interfaces(): @@ -183,7 +195,12 @@ class TypeMap(GraphQLTypeMap): for interface in type._meta.interfaces: self.graphene_reducer(map, interface) 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) return interfaces @@ -207,9 +224,12 @@ class TypeMap(GraphQLTypeMap): 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) + if _type.graphene_type != type: + raise AssertionError( + "Found different types with the same name in the schema: {}, {}.".format( + _type.graphene_type, type + ) + ) return _type _resolve_type = None @@ -248,7 +268,12 @@ class TypeMap(GraphQLTypeMap): for objecttype in type._meta.types: self.graphene_reducer(map, objecttype) 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) return union_types diff --git a/graphene/types/union.py b/graphene/types/union.py index dc207e8e..1c14fd71 100644 --- a/graphene/types/union.py +++ b/graphene/types/union.py @@ -23,10 +23,10 @@ class Union(UnmountedType, BaseType): @classmethod def __init_subclass_with_meta__(cls, types=None, **options): - assert ( - isinstance(types, (list, tuple)) and len(types) > 0 - ), "Must provide types for Union {name}.".format(name=cls.__name__) - + if not (isinstance(types, (list, tuple)) and len(types) > 0): + raise AssertionError( + "Must provide types for Union {name}.".format(name=cls.__name__) + ) _meta = UnionOptions(cls) _meta.types = types super(Union, cls).__init_subclass_with_meta__(_meta=_meta, **options) diff --git a/graphene/types/uuid.py b/graphene/types/uuid.py index abb8f110..84089a2d 100644 --- a/graphene/types/uuid.py +++ b/graphene/types/uuid.py @@ -14,9 +14,8 @@ class UUID(Scalar): def serialize(uuid): if isinstance(uuid, str): uuid = _UUID(uuid) - assert isinstance(uuid, _UUID), "Expected UUID instance, received {}".format( - uuid - ) + if not isinstance(uuid, _UUID): + raise AssertionError("Expected UUID instance, received {}".format(uuid)) return str(uuid) @staticmethod diff --git a/graphene/utils/annotate.py b/graphene/utils/annotate.py index 43a26ef6..18dcd881 100644 --- a/graphene/utils/annotate.py +++ b/graphene/utils/annotate.py @@ -22,9 +22,12 @@ def annotate(_func=None, _trigger_warning=True, **annotations): # We make sure the annotations are valid for key, value in annotations.items(): - assert key in func_signature.parameters, ( - 'The key {key} is not a function parameter in the function "{func_name}".' - ).format(key=key, func_name=func_name(_func)) + if func_signature.parameters.get(key, None) is None: + raise AssertionError( + '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) if func_annotations is None: diff --git a/graphene/utils/comparison_helper.py b/graphene/utils/comparison_helper.py new file mode 100644 index 00000000..c0dc8242 --- /dev/null +++ b/graphene/utils/comparison_helper.py @@ -0,0 +1,3 @@ +def raise_assertion_if(condition=None, message=None): + if condition: + raise AssertionError(message) diff --git a/graphene/utils/subclass_with_meta.py b/graphene/utils/subclass_with_meta.py index 01fc5375..2889862f 100644 --- a/graphene/utils/subclass_with_meta.py +++ b/graphene/utils/subclass_with_meta.py @@ -42,10 +42,15 @@ class SubclassWithMeta(six.with_metaclass(SubclassWithMeta_Meta)): abstract = options.pop("abstract", False) if abstract: - assert not options, ( - "Abstract types can only contain the abstract attribute. " - "Received: abstract, {option_keys}" - ).format(option_keys=", ".join(options.keys())) + if options: + raise AssertionError( + """ + Abstract types can only contain the abstract attribute. + Received: abstract, {option_keys} + """.format( + option_keys=", ".join(options.keys()) + ) + ) else: super_class = super(cls, cls) if hasattr(super_class, "__init_subclass_with_meta__"):