DRY-ed up

This commit is contained in:
Kacppian 2018-07-12 19:25:25 +05:30
parent e88b050694
commit 11a3fe901a
19 changed files with 201 additions and 157 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 .comparison_helper import raise_assertion_if_true
def get_version(version=None): def get_version(version=None):
@ -44,11 +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:
if len(version) is not 5: raise_assertion_if_true(
raise AssertionError("Version needs to be 5") condition=len(version) is not 5,
if version[3] not in ("alpha", "beta", "rc", "final"): message="Version needs to be 5"
raise AssertionError("Release version is unkown") )
raise_assertion_if_true(
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_true
class PageInfo(ObjectType): class PageInfo(ObjectType):
@ -46,16 +47,20 @@ 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)
if not node:
raise AssertionError( error_message = "You have to provide a node in {}.Meta".format(cls.__name__)
"You have to provide a node in {}.Meta".format(cls.__name__) raise_assertion_if_true(
condition=not node,
message=error_message
) )
if not issubclass(node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)): error_message = 'Received incompatible node "{}" for Connection {}.'.format(
raise AssertionError( node, cls.__name__
'Received incompatible node "{}" for Connection {}.'.format( )
node, cls.__name__ condition = not issubclass(node, (Scalar, Enum, ObjectType, Interface, Union, NonNull))
) raise_assertion_if_true(
condition=condition,
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
@ -112,11 +117,11 @@ class IterableConnectionField(Field):
"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"
) )
if not issubclass(connection_type, Connection): error_message = '{} type have to be a subclass of Connection. Received "{}".'
raise AssertionError( .format(self.__class__.__name__, connection_type)
'{} type have to be a subclass of Connection. Received "{}".'.format( raise_assertion_if_true(
self.__class__.__name__, connection_type condition= not issubclass(connection_type, Connection),
) message=error_message
) )
return type return type

View File

@ -5,6 +5,7 @@ from promise import Promise, is_thenable
from ..types import Field, InputObjectType, String from ..types import Field, InputObjectType, String
from ..types.mutation import Mutation from ..types.mutation import Mutation
from ..utils.comparison_helper import raise_assertion_if_true
class ClientIDMutation(Mutation): class ClientIDMutation(Mutation):
@ -18,8 +19,7 @@ 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__)
if output: raise_assertion_if_true(condition=output, message="Can't specify any output")
raise AssertionError("Can't specify any output")
if arguments: if arguments:
raise AssertionError("Can't specify any arguments") raise AssertionError("Can't specify any arguments")

View File

@ -7,6 +7,9 @@ from graphql_relay import from_global_id, to_global_id
from ..types import ID, Field, Interface, ObjectType from ..types import ID, Field, Interface, ObjectType
from ..types.interface import InterfaceOptions from ..types.interface import InterfaceOptions
from ..types.utils import get_type from ..types.utils import get_type
from ..utils.comparison_helper import raise_assertion_if_true
def is_node(objecttype): def is_node(objecttype):
@ -49,8 +52,10 @@ 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):
if not issubclass(node, Node): raise_assertion_if_true(
raise AssertionError("NodeField can only operate in Nodes") condition= not issubclass(node, Node),
message="NodeField can only operate in Nodes"
)
self.node_type = node self.node_type = node
self.field_type = type self.field_type = type
@ -98,12 +103,10 @@ class Node(AbstractNode):
except Exception: except Exception:
return None return None
if only_type: raise_assertion_if_true(
if graphene_type != only_type: condition=only_type and (graphene_type is not only_type),
raise AssertionError( message="Must receive a {} id.".format(only_type._meta.name)
"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
if cls not in graphene_type._meta.interfaces: if cls not in graphene_type._meta.interfaces:
return None return None

View File

@ -5,7 +5,7 @@ from .dynamic import Dynamic
from .mountedtype import MountedType from .mountedtype import MountedType
from .structures import NonNull from .structures import NonNull
from .utils import get_type from .utils import get_type
from ..utils.comparison_helper import raise_assertion_if_true
class Argument(MountedType): class Argument(MountedType):
def __init__( def __init__(
@ -73,10 +73,10 @@ 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
if arg_name in arguments: raise_assertion_if_true(
raise AssertionError( condition=arg_name in arguments,
'More than one Argument have same name "{}".'.format(arg_name) message='More than one Argument have same name "{}".'.format(arg_name)
) )
arguments[arg_name] = arg arguments[arg_name] = arg
return arguments return arguments

View File

@ -1,6 +1,6 @@
from ..utils.subclass_with_meta import SubclassWithMeta from ..utils.subclass_with_meta import SubclassWithMeta
from ..utils.trim_docstring import trim_docstring from ..utils.trim_docstring import trim_docstring
from ..utils.comparison_helper import raise_assertion_if_true
class BaseOptions(object): class BaseOptions(object):
name = None # type: str name = None # type: str
@ -31,8 +31,10 @@ 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):
if "_meta" in cls.__dict__: raise_assertion_if_true(
raise AssertionError("Can't assign meta directly") condition="_meta" in cls.__dict__,
message="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

@ -6,7 +6,7 @@ from aniso8601 import parse_date, parse_datetime, parse_time
from graphql.language import ast from graphql.language import ast
from .scalars import Scalar from .scalars import Scalar
from ..utils.comparison_helper import raise_assertion_if_true
class Date(Scalar): class Date(Scalar):
""" """
@ -19,8 +19,10 @@ 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()
if not isinstance(date, datetime.date): raise_assertion_if_true(
raise AssertionError('Received not compatible date "{}"'.format(repr(date))) condition=not isinstance(date, datetime.date),
message='Received not compatible date "{}"'.format(repr(date))
)
return date.isoformat() return date.isoformat()
@classmethod @classmethod
@ -45,10 +47,11 @@ class DateTime(Scalar):
@staticmethod @staticmethod
def serialize(dt): def serialize(dt):
if not isinstance(dt, (datetime.datetime, datetime.date)):
raise AssertionError( raise_assertion_if_true(
'Received not compatible datetime "{}"'.format(repr(dt)) condition=not isinstance(dt, (datetime.datetime, datetime.date)),
) message='Received not compatible datetime "{}"'.format(repr(dt))
)
return dt.isoformat() return dt.isoformat()
@classmethod @classmethod
@ -73,8 +76,10 @@ class Time(Scalar):
@staticmethod @staticmethod
def serialize(time): def serialize(time):
if not isinstance(time, datetime.time): raise_assertion_if_true(
raise AssertionError('Received not compatible time "{}"'.format(repr(time))) condition= not isinstance(time, datetime.time),
message='Received not compatible time "{}"'.format(repr(time))
)
return time.isoformat() return time.isoformat()
@classmethod @classmethod

View File

@ -3,6 +3,8 @@ from functools import partial
from .mountedtype import MountedType from .mountedtype import MountedType
from ..utils.comparison_helper import raise_assertion_if_true
class Dynamic(MountedType): class Dynamic(MountedType):
""" """
@ -12,10 +14,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)
if not (inspect.isfunction(type) or isinstance(type, partial)): raise_assertion_if_true(
raise AssertionError( condition=not (inspect.isfunction(type) or isinstance(type, partial)),
"type is expected to be a function or an instance of partial" message="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

@ -7,6 +7,7 @@ from .mountedtype import MountedType
from .structures import NonNull from .structures import NonNull
from .unmountedtype import UnmountedType from .unmountedtype import UnmountedType
from .utils import get_type from .utils import get_type
from ..utils.comparison_helper import raise_assertion_if_true
base_type = type base_type = type
@ -35,20 +36,20 @@ class Field(MountedType):
): ):
super(Field, self).__init__(_creation_counter=_creation_counter) super(Field, self).__init__(_creation_counter=_creation_counter)
if args and not isinstance(args, Mapping): raise_assertion_if_true(
raise AssertionError( condition=args and not isinstance(args, Mapping),
'Arguments in a field have to be a mapping, received "{}".'.format(args) message='Arguments in a field have to be a mapping, received "{}".'.format(args)
) )
if source and resolver:
raise AssertionError( raise_assertion_if_true(
"A Field cannot have a source and a resolver in at the same time." condition=source and resolver,
) message="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( raise_assertion_if_true(
base_type(default_value) condition=callable(default_value),
) message='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

@ -1,6 +1,7 @@
from ..utils.orderedtype import OrderedType from ..utils.orderedtype import OrderedType
from .unmountedtype import UnmountedType from .unmountedtype import UnmountedType
from ..utils.comparison_helper import raise_assertion_if_true
class MountedType(OrderedType): class MountedType(OrderedType):
@classmethod @classmethod
@ -8,10 +9,10 @@ class MountedType(OrderedType):
""" """
Mount the UnmountedType instance Mount the UnmountedType instance
""" """
if not isinstance(unmounted, UnmountedType): raise_assertion_if_true(
raise AssertionError( condition=not isinstance(unmounted, UnmountedType),
"{} can't mount {}".format(cls.__name__, repr(unmounted)) message="{} can't mount {}".format(cls.__name__, repr(unmounted)
) )
return cls( return cls(
unmounted.get_type(), unmounted.get_type(),

View File

@ -5,6 +5,8 @@ from .field import Field
from .interface import Interface from .interface import Interface
from .utils import yank_fields_from_attrs from .utils import yank_fields_from_attrs
from ..utils.comparison_helper import raise_assertion_if_true
# For static type checking with Mypy # For static type checking with Mypy
MYPY = False MYPY = False
if MYPY: if MYPY:
@ -47,15 +49,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))
if possible_types and cls.is_type_of: error_message = """
raise AssertionError( {name}.Meta.possible_types will cause type collision with {name}.is_type_of.
""" Please use one or other.
{name}.Meta.possible_types will cause type collision with {name}.is_type_of. """.format(name=cls.__name__)
Please use one or other.
""".format( raise_assertion_if_true(
name=cls.__name__ condition=possible_types and cls.is_type_of,
) message=error_message
) )
if _meta.fields: if _meta.fields:
_meta.fields.update(fields) _meta.fields.update(fields)

View File

@ -1,3 +1,5 @@
from ..utils.comparison_helper import raise_assertion_if_true
def attr_resolver(attname, default_value, root, info, **args): def attr_resolver(attname, default_value, root, info, **args):
return getattr(root, attname, default_value) return getattr(root, attname, default_value)
@ -11,8 +13,11 @@ default_resolver = attr_resolver
def set_default_resolver(resolver): def set_default_resolver(resolver):
global default_resolver global default_resolver
if not callable(resolver):
raise AssertionError("Received non-callable resolver.") raise_assertion_if_true(
condition=not callable(resolver),
message="Received non-callable resolver."
)
default_resolver = resolver default_resolver = resolver

View File

@ -13,15 +13,17 @@ from graphql.utils.schema_printer import print_schema
from .definitions import GrapheneGraphQLType from .definitions import GrapheneGraphQLType
from .objecttype import ObjectType from .objecttype import ObjectType
from .typemap import TypeMap, is_graphene_type from .typemap import TypeMap, is_graphene_type
from ..utils.comparison_helper import raise_assertion_if_true
def assert_valid_root_type(_type): def assert_valid_root_type(_type):
if _type is None: if _type is None:
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)
if not (is_graphene_objecttype or is_graphql_objecttype): raise_assertion_if_true(
raise AssertionError("Type {} is not a valid ObjectType.".format(_type)) condition=not (is_graphene_objecttype or is_graphql_objecttype),
message="Type {} is not a valid ObjectType.".format(_type)
)
class Schema(GraphQLSchema): class Schema(GraphQLSchema):
@ -52,12 +54,10 @@ class Schema(GraphQLSchema):
if directives is None: if directives is None:
directives = [GraphQLIncludeDirective, GraphQLSkipDirective] directives = [GraphQLIncludeDirective, GraphQLSkipDirective]
if not all(isinstance(d, GraphQLDirective) for d in directives): raise_assertion_if_true(
raise AssertionError( condition=not all(isinstance(d, GraphQLDirective) for d in directives),
"Schema directives must be List[GraphQLDirective] if provided but got: {}.".format( message="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,16 +91,19 @@ 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)
if not graphql_type:
raise AssertionError( raise_assertion_if_true(
"Type {} not found in this schema.".format(_type._meta.name) condition=not graphql_type,
) message="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( error_message = "The type {} does not match with the associated graphene type {}."
_type, graphql_type.graphene_type .format(_type, graphql_type.graphene_type)
) raise_assertion_if_true(
) condition=graphql_type.graphene_type is not _type,
message=error_message
)
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

@ -40,6 +40,7 @@ from .scalars import ID, Boolean, Float, Int, Scalar, String
from .structures import List, NonNull from .structures import List, NonNull
from .union import Union from .union import Union
from .utils import get_field_as from .utils import get_field_as
from ..utils.comparison_helper import raise_assertion_if_true
def is_graphene_type(_type): def is_graphene_type(_type):
@ -60,16 +61,18 @@ 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)
if not graphql_type: raise_assertion_if_true(
raise AssertionError( condition=not graphql_type,
"Can't find type {} in schema".format(_type._meta.name) message="Can't find type {} in schema".format(_type._meta.name)
) )
if graphql_type.graphene_type != _type:
raise AssertionError( error_message = "The type {} does not match with the associated graphene type {}."
"The type {} does not match with the associated graphene type {}.".format( .format( _type, graphql_type.graphene_type)
_type, graphql_type.graphene_type raise_assertion_if_true(
) condition=graphql_type.graphene_type is not _type,
) message=error_message
)
return graphql_type return graphql_type
return _type return _type
@ -100,12 +103,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):
if _type.graphene_type is not type: error_message = "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( raise_assertion_if_true(
_type.graphene_type, type condition=_type.graphene_type is not type,
) message=error_message
) )
return map return map
if issubclass(type, ObjectType): if issubclass(type, ObjectType):
@ -182,12 +185,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):
if _type.graphene_type != type: error_message = "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( raise_assertion_if_true(
_type.graphene_type, type condition=_type.graphene_type is not type,
) message=error_message
) )
return _type return _type
def interfaces(): def interfaces():
@ -195,12 +198,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]
if internal_type.graphene_type != interface: error_message = "Found different types with the same name in the schema: {}, {}."
raise AssertionError( .format(internal_type.graphene_type, interface)
"Found different types with the same name in the schema: {}, {}.".format( raise_assertion_if_true(
internal_type.graphene_type, interface condition=internal_type.graphene_type is not interface,
) message=error_message
) )
interfaces.append(internal_type) interfaces.append(internal_type)
return interfaces return interfaces
@ -224,12 +227,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):
if _type.graphene_type != type: error_message = "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( raise_assertion_if_true(
_type.graphene_type, type condition= _type.graphene_type is not type,
) message=error_message
) )
return _type return _type
_resolve_type = None _resolve_type = None
@ -268,12 +271,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]
if internal_type.graphene_type != objecttype: error_message = "Found different types with the same name in the schema: {}, {}."
raise AssertionError( .format(internal_type.graphene_type, objecttype)
"Found different types with the same name in the schema: {}, {}.".format( raise_assertion_if_true(
internal_type.graphene_type, objecttype condition=internal_type.graphene_type is not objecttype,
) message=error_message
) )
union_types.append(internal_type) union_types.append(internal_type)
return union_types return union_types

View File

@ -1,6 +1,8 @@
from .base import BaseOptions, BaseType from .base import BaseOptions, BaseType
from .unmountedtype import UnmountedType from .unmountedtype import UnmountedType
from ..utils.comparison_helper import raise_assertion_if_true
# For static type checking with Mypy # For static type checking with Mypy
MYPY = False MYPY = False
if MYPY: if MYPY:
@ -23,10 +25,11 @@ class Union(UnmountedType, BaseType):
@classmethod @classmethod
def __init_subclass_with_meta__(cls, types=None, **options): def __init_subclass_with_meta__(cls, types=None, **options):
if not (isinstance(types, (list, tuple)) and len(types) > 0):
raise AssertionError( raise_assertion_if_true(
"Must provide types for Union {name}.".format(name=cls.__name__) condition=not (isinstance(types, (list, tuple)) and len(types) > 0,
) message="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

@ -5,7 +5,7 @@ from uuid import UUID as _UUID
from graphql.language import ast from graphql.language import ast
from .scalars import Scalar from .scalars import Scalar
from ..utils.comparison_helper import raise_assertion_if_true
class UUID(Scalar): class UUID(Scalar):
"""UUID""" """UUID"""
@ -14,8 +14,10 @@ class UUID(Scalar):
def serialize(uuid): def serialize(uuid):
if isinstance(uuid, str): if isinstance(uuid, str):
uuid = _UUID(uuid) uuid = _UUID(uuid)
if not isinstance(uuid, _UUID): raise_assertion_if_true(
raise AssertionError("Expected UUID instance, received {}".format(uuid)) condition=not isinstance(uuid, _UUID),
message="Expected UUID instance, received {}".format(uuid)
)
return str(uuid) return str(uuid)
@staticmethod @staticmethod

View File

@ -2,6 +2,7 @@ import six
from ..pyutils.compat import func_name, signature from ..pyutils.compat import func_name, signature
from .deprecated import warn_deprecation from .deprecated import warn_deprecation
from .comparison_helper import raise_assertion_if_true
def annotate(_func=None, _trigger_warning=True, **annotations): def annotate(_func=None, _trigger_warning=True, **annotations):
@ -22,11 +23,13 @@ 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():
if func_signature.parameters.get(key, None) is None: func_param = func_signature.parameters.get(key, None)
raise AssertionError( assertion_message = 'The key {key} is not a function parameter in the function "{func_name}".'
'The key {key} is not a function parameter in the function "{func_name}".'.format( .format(key=key, func_name=func_name(_func)
key=key, func_name=func_name(_func)
) raise_assertion_if_true(
condition=func_param is None,
message=assertion_message
) )
func_annotations = getattr(_func, "__annotations__", None) func_annotations = getattr(_func, "__annotations__", None)

View File

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

View File

@ -41,16 +41,13 @@ class SubclassWithMeta(six.with_metaclass(SubclassWithMeta_Meta)):
options = dict(meta_options, **_meta_props) options = dict(meta_options, **_meta_props)
abstract = options.pop("abstract", False) abstract = options.pop("abstract", False)
if abstract: error_message = """
if options:
raise AssertionError(
"""
Abstract types can only contain the abstract attribute. Abstract types can only contain the abstract attribute.
Received: abstract, {option_keys} Received: abstract, {option_keys}
""".format( """.format(option_keys=", ".join(options.keys())
option_keys=", ".join(options.keys())
) raise_assertion_if_true(condition=options and abstract, message=error_message)
)
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__"):