mirror of
https://github.com/graphql-python/graphene.git
synced 2025-07-27 08:19:45 +03:00
assertion helper added
This commit is contained in:
parent
131cbebc88
commit
f38fc5136f
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||
import datetime
|
||||
import os
|
||||
import subprocess
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
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_not(
|
||||
condition=len(version) is 5,
|
||||
message="Wrong tuple provided"
|
||||
)
|
||||
raise_assertion_if_not(
|
||||
condition=version[3] in ("alpha", "beta", "rc", "final"),
|
||||
message="Version not correct."
|
||||
)
|
||||
|
||||
return version
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from ..types.field import Field
|
|||
from ..types.objecttype import ObjectType, ObjectTypeOptions
|
||||
from ..utils.thenables import maybe_thenable
|
||||
from .node import is_node
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class PageInfo(ObjectType):
|
||||
|
@ -52,11 +53,17 @@ 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(
|
||||
node, cls.__name__
|
||||
raise_assertion_if_not(
|
||||
condition=node,
|
||||
message="You have to provide a node in {}.Meta".format(cls.__name__)
|
||||
)
|
||||
raise_assertion_if_not(
|
||||
condition=issubclass(
|
||||
node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
|
||||
),
|
||||
message=('Received incompatible node "{}" for Connection {}.').format(
|
||||
node, cls.__name__
|
||||
)
|
||||
)
|
||||
|
||||
base_name = re.sub("Connection$", "", name or cls.__name__) or node._meta.name
|
||||
|
@ -132,9 +139,12 @@ class IterableConnectionField(Field):
|
|||
"Read more: https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#node-connections"
|
||||
)
|
||||
|
||||
assert issubclass(connection_type, Connection), (
|
||||
'{} type have to be a subclass of Connection. Received "{}".'
|
||||
).format(self.__class__.__name__, connection_type)
|
||||
raise_assertion_if_not(
|
||||
condition=issubclass(connection_type, Connection),
|
||||
message='{} type have to be a subclass of Connection. Received "{}".'.format(
|
||||
self.__class__.__name__, connection_type
|
||||
)
|
||||
)
|
||||
return type
|
||||
|
||||
@classmethod
|
||||
|
@ -142,10 +152,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)
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(resolved, Iterable),
|
||||
message="""
|
||||
Resolved value from the connection field have to be iterable or instance of {}.
|
||||
Received "{}"
|
||||
""".format(
|
||||
connection_type, resolved
|
||||
)
|
||||
)
|
||||
|
||||
connection = connection_from_list(
|
||||
resolved,
|
||||
args,
|
||||
|
|
|
@ -17,8 +17,15 @@ 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"
|
||||
raise_assertion_if_not(
|
||||
condition=not output,
|
||||
message="Can't specify any output"
|
||||
)
|
||||
|
||||
raise_assertion_if_not(
|
||||
condition=not arguments,
|
||||
message="Can't specify any arguments"
|
||||
)
|
||||
|
||||
bases = (InputObjectType,)
|
||||
if input_class:
|
||||
|
@ -41,10 +48,13 @@ 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__)
|
||||
raise_assertion_if_not(
|
||||
condition=mutate_and_get_payload,
|
||||
message="{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)
|
||||
|
|
|
@ -7,6 +7,7 @@ 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.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
def is_node(objecttype):
|
||||
|
|
|
@ -5,6 +5,7 @@ from .dynamic import Dynamic
|
|||
from .mountedtype import MountedType
|
||||
from .structures import NonNull
|
||||
from .utils import get_type
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class Argument(MountedType):
|
||||
|
@ -73,10 +74,11 @@ 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
|
||||
raise_assertion_if_not(
|
||||
condition=arg_name not in arguments,
|
||||
message='More than one Argument have same name "{}".'.format(
|
||||
arg_name
|
||||
)
|
||||
)
|
||||
arguments[arg_name] = arg
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from ..utils.subclass_with_meta import SubclassWithMeta
|
||||
from ..utils.trim_docstring import trim_docstring
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class BaseOptions(object):
|
||||
|
@ -31,7 +32,10 @@ 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"
|
||||
raise_assertion_if_not(
|
||||
condition="_meta" not in cls.__dict__,
|
||||
message="Can't assign directly meta"
|
||||
)
|
||||
if not _meta:
|
||||
return
|
||||
_meta.name = name or cls.__name__
|
||||
|
|
|
@ -6,6 +6,7 @@ from aniso8601 import parse_date, parse_datetime, parse_time
|
|||
from graphql.language import ast
|
||||
|
||||
from .scalars import Scalar
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class Date(Scalar):
|
||||
|
@ -19,9 +20,10 @@ 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))
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(date, datetime.date),
|
||||
message='Received not compatible date "{}"'.format(repr(date))
|
||||
)
|
||||
return date.isoformat()
|
||||
|
||||
@classmethod
|
||||
|
@ -46,9 +48,10 @@ class DateTime(Scalar):
|
|||
|
||||
@staticmethod
|
||||
def serialize(dt):
|
||||
assert isinstance(
|
||||
dt, (datetime.datetime, datetime.date)
|
||||
), 'Received not compatible datetime "{}"'.format(repr(dt))
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(dt, (datetime.datetime, datetime.date)),
|
||||
message='Received not compatible datetime "{}"'.format(repr(dt))
|
||||
)
|
||||
return dt.isoformat()
|
||||
|
||||
@classmethod
|
||||
|
@ -73,9 +76,10 @@ class Time(Scalar):
|
|||
|
||||
@staticmethod
|
||||
def serialize(time):
|
||||
assert isinstance(
|
||||
time, datetime.time
|
||||
), 'Received not compatible time "{}"'.format(repr(time))
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(time, datetime.time),
|
||||
message='Received not compatible time "{}"'.format(repr(time))
|
||||
)
|
||||
return time.isoformat()
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -7,6 +7,7 @@ from .mountedtype import MountedType
|
|||
from .structures import NonNull
|
||||
from .unmountedtype import UnmountedType
|
||||
from .utils import get_type
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
base_type = type
|
||||
|
||||
|
@ -34,15 +35,24 @@ 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))
|
||||
raise_assertion_if_not(
|
||||
condition=not args or isinstance(args, Mapping),
|
||||
message='Arguments in a field have to be a mapping, received "{}".'.format(
|
||||
args
|
||||
)
|
||||
)
|
||||
|
||||
raise_assertion_if_not(
|
||||
condition=not(source and resolver),
|
||||
message="A Field cannot have a source and a resolver in at the same time."
|
||||
)
|
||||
|
||||
raise_assertion_if_not(
|
||||
condition=not callable(default_value),
|
||||
message='The default value can not be a function but received "{}".'.format(
|
||||
base_type(default_value)
|
||||
)
|
||||
)
|
||||
|
||||
if required:
|
||||
type = NonNull(type)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from ..utils.orderedtype import OrderedType
|
||||
from .unmountedtype import UnmountedType
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class MountedType(OrderedType):
|
||||
|
@ -8,8 +9,9 @@ class MountedType(OrderedType):
|
|||
"""
|
||||
Mount the UnmountedType instance
|
||||
"""
|
||||
assert isinstance(unmounted, UnmountedType), ("{} can't mount {}").format(
|
||||
cls.__name__, repr(unmounted)
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(unmounted, UnmountedType),
|
||||
message="{} can't mount {}".format(cls.__name__, repr(unmounted))
|
||||
)
|
||||
|
||||
return cls(
|
||||
|
|
|
@ -6,6 +6,7 @@ from ..utils.props import props
|
|||
from .field import Field
|
||||
from .objecttype import ObjectType, ObjectTypeOptions
|
||||
from .utils import yank_fields_from_attrs
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
# For static type checking with Mypy
|
||||
MYPY = False
|
||||
|
@ -62,7 +63,10 @@ class Mutation(ObjectType):
|
|||
|
||||
if not resolver:
|
||||
mutate = getattr(cls, "mutate", None)
|
||||
assert mutate, "All mutations must define a mutate method in it"
|
||||
raise_assertion_if_not(
|
||||
condition=mutate,
|
||||
message="All mutations must define a mutate method in it"
|
||||
)
|
||||
resolver = get_unbound_function(mutate)
|
||||
|
||||
if _meta.fields:
|
||||
|
|
|
@ -4,6 +4,7 @@ from .base import BaseOptions, BaseType
|
|||
from .field import Field
|
||||
from .interface import Interface
|
||||
from .utils import yank_fields_from_attrs
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
# For static type checking with Mypy
|
||||
MYPY = False
|
||||
|
@ -39,18 +40,25 @@ class ObjectType(BaseType):
|
|||
fields = OrderedDict()
|
||||
|
||||
for interface in interfaces:
|
||||
assert issubclass(interface, Interface), (
|
||||
'All interfaces of {} must be a subclass of Interface. Received "{}".'
|
||||
).format(cls.__name__, interface)
|
||||
raise_assertion_if_not(
|
||||
condition=issubclass(interface, Interface),
|
||||
message='All interfaces of {} must be a subclass of Interface. Received "{}".'.format(
|
||||
cls.__name__, interface
|
||||
)
|
||||
)
|
||||
fields.update(interface._meta.fields)
|
||||
|
||||
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__)
|
||||
raise_assertion_if_not(
|
||||
condition=not (possible_types and cls.is_type_of),
|
||||
message=("{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)
|
||||
|
|
|
@ -13,6 +13,7 @@ from graphql.utils.schema_printer import print_schema
|
|||
from .definitions import GrapheneGraphQLType
|
||||
from .objecttype import ObjectType
|
||||
from .typemap import TypeMap, is_graphene_type
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
def assert_valid_root_type(_type):
|
||||
|
@ -20,9 +21,10 @@ 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)
|
||||
raise_assertion_if_not(
|
||||
condition=is_graphene_objecttype or is_graphql_objecttype,
|
||||
message="Type {} is not a valid ObjectType.".format(_type)
|
||||
)
|
||||
|
||||
|
||||
class Schema(GraphQLSchema):
|
||||
|
@ -53,10 +55,11 @@ 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
|
||||
raise_assertion_if_not(
|
||||
condition=all(isinstance(d, GraphQLDirective) for d in directives),
|
||||
message="Schema directives must be List[GraphQLDirective] if provided but got: {}.".format(
|
||||
directives
|
||||
)
|
||||
)
|
||||
self._directives = directives
|
||||
self.build_typemap()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from .unmountedtype import UnmountedType
|
||||
from .utils import get_type
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class Structure(UnmountedType):
|
||||
|
@ -67,9 +68,12 @@ class NonNull(Structure):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NonNull, self).__init__(*args, **kwargs)
|
||||
assert not isinstance(self._of_type, NonNull), (
|
||||
"Can only create NonNull of a Nullable GraphQLType but got: {}."
|
||||
).format(self._of_type)
|
||||
raise_assertion_if_not(
|
||||
condition=not isinstance(self._of_type, NonNull),
|
||||
message="Can only create NonNull of a Nullable GraphQLType but got: {}.".format(
|
||||
self._of_type
|
||||
)
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "{}!".format(self.of_type)
|
||||
|
|
|
@ -40,6 +40,7 @@ from .scalars import ID, Boolean, Float, Int, Scalar, String
|
|||
from .structures import List, NonNull
|
||||
from .union import Union
|
||||
from .utils import get_field_as
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
def is_graphene_type(_type):
|
||||
|
@ -60,10 +61,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)
|
||||
raise_assertion_if_not(
|
||||
condition=graphql_type,
|
||||
message="Can't find type {} in schema".format(_type._meta.name)
|
||||
)
|
||||
raise_assertion_if_not(
|
||||
condition=graphql_type.graphene_type is _type,
|
||||
message="The type {} does not match with the associated graphene type {}.".format(
|
||||
_type, graphql_type.graphene_type
|
||||
)
|
||||
)
|
||||
return graphql_type
|
||||
|
||||
return _type
|
||||
|
@ -94,9 +101,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)
|
||||
raise_assertion_if_not(
|
||||
condition=_type.graphene_type is type,
|
||||
message="Found different types with the same name in the schema: {}, {}.".format(
|
||||
_type.graphene_type, type
|
||||
)
|
||||
)
|
||||
return map
|
||||
|
||||
if issubclass(type, ObjectType):
|
||||
|
@ -173,9 +183,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)
|
||||
raise_assertion_if_not(
|
||||
condition=_type.graphene_type is type,
|
||||
message="Found different types with the same name in the schema: {}, {}.".format(
|
||||
_type.graphene_type, type
|
||||
)
|
||||
)
|
||||
return _type
|
||||
|
||||
def interfaces():
|
||||
|
@ -183,7 +196,9 @@ 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
|
||||
raise_assertion_if_not(
|
||||
condition=internal_type.graphene_type is interface
|
||||
)
|
||||
interfaces.append(internal_type)
|
||||
return interfaces
|
||||
|
||||
|
@ -207,9 +222,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)
|
||||
raise_assertion_if_not(
|
||||
condition=_type.graphene_type is type,
|
||||
message="Found different types with the same name in the schema: {}, {}.".format(
|
||||
_type.graphene_type, type
|
||||
)
|
||||
)
|
||||
return _type
|
||||
|
||||
_resolve_type = None
|
||||
|
@ -248,7 +266,9 @@ 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
|
||||
raise_assertion_if_not(
|
||||
condition=internal_type.graphene_type is objecttype
|
||||
)
|
||||
union_types.append(internal_type)
|
||||
return union_types
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from .base import BaseOptions, BaseType
|
||||
from .unmountedtype import UnmountedType
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
# For static type checking with Mypy
|
||||
MYPY = False
|
||||
|
@ -23,10 +24,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__)
|
||||
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(types, (list, tuple)) and len(types) > 0,
|
||||
message="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)
|
||||
|
|
|
@ -5,6 +5,7 @@ from uuid import UUID as _UUID
|
|||
from graphql.language import ast
|
||||
|
||||
from .scalars import Scalar
|
||||
from ..utils.comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
class UUID(Scalar):
|
||||
|
@ -14,8 +15,9 @@ class UUID(Scalar):
|
|||
def serialize(uuid):
|
||||
if isinstance(uuid, str):
|
||||
uuid = _UUID(uuid)
|
||||
assert isinstance(uuid, _UUID), "Expected UUID instance, received {}".format(
|
||||
uuid
|
||||
raise_assertion_if_not(
|
||||
condition=isinstance(uuid, _UUID),
|
||||
message="Expected UUID instance, received {}".format(uuid)
|
||||
)
|
||||
return str(uuid)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import six
|
|||
|
||||
from ..pyutils.compat import func_name, signature
|
||||
from .deprecated import warn_deprecation
|
||||
from .comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
def annotate(_func=None, _trigger_warning=True, **annotations):
|
||||
|
@ -22,9 +23,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))
|
||||
raise_assertion_if_not(
|
||||
condition= key in func_signature.parameters,
|
||||
message='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:
|
||||
|
|
3
graphene/utils/comparison_helper.py
Normal file
3
graphene/utils/comparison_helper.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
def raise_assertion_if_not(condition=None, message=None):
|
||||
if not condition:
|
||||
raise AssertionError(message)
|
|
@ -4,6 +4,8 @@ import six
|
|||
|
||||
from ..pyutils.init_subclass import InitSubclassMeta
|
||||
from .props import props
|
||||
from .comparison_helper import raise_assertion_if_not
|
||||
|
||||
|
||||
|
||||
class SubclassWithMeta_Meta(InitSubclassMeta):
|
||||
|
@ -42,10 +44,13 @@ 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()))
|
||||
raise_assertion_if_not(
|
||||
condition=not options,
|
||||
message="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__"):
|
||||
|
|
Loading…
Reference in New Issue
Block a user