issubclass()
Type-vs-type check. The class-level counterpart to isinstance (which is instance-vs-type).
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(classclass — The class to check. Must be a class object — passing an instance raises TypeError.type: type · required, classinfoclassinfo — A 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
| Name | Type | Required | Description |
|---|---|---|---|
| class | type | yes | The class to check. Must be a class object — passing an instance raises TypeError. |
| classinfo | type | tuple[type] | yes | A class or tuple of classes. Returns True if `class` is a subclass of it (or any one in the tuple). |
Return value
bool — True 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 trivia2. int ⊂ object
issubclass(int, object)
Returns
True3. Self
issubclass(int, int)
Returns
True4. Unrelated
issubclass(int, str)
Returns
False5. Tuple of bases
issubclass(bool, (str, int))
Returns
True # via int6. Instance rejected
issubclass(42, int)
Returns
TypeError: issubclass() arg 1 must be a classPitfalls
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.