issubclass()

Type-vs-type check. The class-level counterpart to isinstance (which is instance-vs-type).

Built-in functionPython 1.0+
Common call
issubclass(Sub, Base)
Returns
True or False
Replaces
walking .__mro__ or .__bases__ manually
Watch out
first argument MUST be a class — passing an instance raises TypeError
issubclass(classclassThe class to check. Must be a class object — passing an instance raises TypeError.type: type · required, classinfoclassinfoA class or tuple of classes. Returns True if `class` is a subclass of it (or any one in the tuple).type: type | tuple[type] · required)
bool

Parameters

NameTypeRequiredDescription
classtypeyesThe class to check. Must be a class object — passing an instance raises TypeError.
classinfotype | tuple[type]yesA class or tuple of classes. Returns True if `class` is a subclass of it (or any one in the tuple).

Return value

boolTrue if `class` is a subclass (direct, indirect, or virtual) of `classinfo`. A class is considered a subclass of itself. If classinfo is a tuple of classes, returns True when class is a subclass of ANY of them.

Common patterns

Register handlers by base class
Dispatch based on class relationships rather than exact type.
for base, handler in HANDLERS.items():
    if issubclass(cls, base):
        return handler
Sanity check in metaclass / decorator
Ensure a decorated class satisfies a contract.
def register(cls):
    if not issubclass(cls, Serializable):
        raise TypeError("must inherit from Serializable")
Tuple form for "any of"
Match against a set of allowed base classes in one call.
if issubclass(cls, (Exception, Warning)):
    ...

Examples

1. bool ⊂ int
issubclass(bool, int)
Returns
True # Python trivia
2. int ⊂ object
issubclass(int, object)
Returns
True
3. Self
issubclass(int, int)
Returns
True
4. Unrelated
issubclass(int, str)
Returns
False
5. Tuple of bases
issubclass(bool, (str, int))
Returns
True # via int
6. Instance rejected
issubclass(42, int)
Returns
TypeError: issubclass() arg 1 must be a class

Pitfalls

1. First argument must be a CLASS — not an instance
The most common mix-up. issubclass takes CLASSES; isinstance takes an INSTANCE and a class. Passing an instance to issubclass raises TypeError.
Instance rejected
issubclass(42, int)
TypeError: issubclass() arg 1 must be a class
Use type or isinstance
isinstance(42, int)   # True
2. A class IS considered a subclass of itself
issubclass(C, C) is True. Reflexive by design. If you need "strictly a subclass", check inequality separately.
Strict expected
issubclass(int, int)
True # strict? No
For strict
cls is not Base and issubclass(cls, Base)
strict subclass
3. bool IS a subclass of int
A frequent surprise in type-narrowing code. If you branch on int vs bool separately, check bool first — issubclass(bool, int) is True.
Assumed disjoint
if issubclass(cls, int): ...   # bool falls here
True even for bool
Check bool first
if issubclass(cls, bool): ...
elif issubclass(cls, int): ...
ordered
4. Virtual subclasses (ABCs) can register without inheritance
abc.ABCMeta.register() lets a class be considered a subclass of an ABC without actually inheriting. issubclass returns True for virtual subclasses — sometimes surprising when reading class hierarchies.
Assumed lineage
issubclass(cls, ABC)
True even for registered virtual subclasses
Look at __mro__
ABC in cls.__mro__
False for virtual

When to use

Use it
  • Dispatch tables keyed by class
  • Sanity checks in decorators, metaclasses, or framework code
  • Filtering a set of classes by base
  • Any place `if type(x) is C` is too strict but `isinstance` is the wrong direction
Reach for something else
  • You have an instance → isinstance
  • You need exact type equality → `type(x) is C`
  • You want to know why → inspect __mro__ / __bases__ directly

Notes

Complexity
O(depth of MRO) — walk the class hierarchy
Return
bool
CPython impl
Python/bltinmodule.c :: builtin_issubclass
Memory
No allocation
Thread-safe
Yes for immutable hierarchies

FAQ

isinstance takes an INSTANCE and a class: `isinstance(42, int)` → True. issubclass takes two CLASSES: `issubclass(bool, int)` → True. isinstance is by far the more common of the two.

History

1.0
issubclass() has been a builtin since Python 1.0.
2.2
Extended to accept a tuple of classes as classinfo.