Source code for callee.types
"""
Type-related matchers.
"""
import inspect
from callee.base import BaseMatcher
__all__ = [
'InstanceOf', 'IsA', 'SubclassOf', 'Inherits', 'Type', 'Class',
]
class TypeMatcher(BaseMatcher):
"""Matches an object to a type.
This class shouldn't be used directly.
"""
def __init__(self, type_):
""":param type\ _: Type to match against"""
if not isinstance(type_, type):
raise TypeError("%s requires a type, got %r" % (
self.__class__.__name__, type_))
self.type_ = type_
def __repr__(self):
return "<%s %r>" % (self.__class__.__name__, self.type_)
# TODO: reverse of this matcher (TypeOf / ClassOf)
[docs]class InstanceOf(TypeMatcher):
"""Matches an object that's an instance of given type
(as per `isinstance`).
"""
def __init__(self, type_, exact=False):
"""
:param type\ _: Type to match against
:param exact:
If True, the match will only succeed if the value type matches
given ``type_`` exactly.
Otherwise (the default), a subtype of ``type_`` will also match.
"""
super(InstanceOf, self).__init__(type_)
self.exact = exact
def match(self, value):
if self.exact:
return type(value) is self.type_
else:
return isinstance(value, self.type_)
IsA = InstanceOf
# TODO: reverse of this matcher (SuperclassOf)
[docs]class SubclassOf(TypeMatcher):
"""Matches a class that's a subclass of given type
(as per `issubclass`).
"""
def __init__(self, type_, strict=False):
"""
:param type\ _: Type to match against
:param strict:
If True, the match if only succeed if the value is a _strict_
subclass of ``type_`` -- that is, it's not ``type_`` itself.
Otherwise (the default), any subclass of ``type_`` matches.
"""
super(SubclassOf, self).__init__(type_)
self.strict = strict
def match(self, value):
if not isinstance(value, type):
return False
if not issubclass(value, self.type_):
return False
if value is self.type_ and self.strict:
return False
return True
Inherits = SubclassOf
[docs]class Type(BaseMatcher):
"""Matches any Python type object."""
def match(self, value):
return isinstance(value, type)
def __repr__(self):
return "<Type>"
[docs]class Class(BaseMatcher):
"""Matches a class (but not any other type object)."""
def match(self, value):
return inspect.isclass(value)
def __repr__(self):
return "<Class>"
# TODO: Module() matcher