issubclass()
issubclass(class, classinfo) Returns:
bool · Updated March 13, 2026 · Built-in Functions built-in class inheritance type-checking
The issubclass() function checks whether a class is a subclass of another class or any class in a tuple of classes. A class is considered a subclass of itself. This function is useful for type checking and implementing polymorphic behavior.
Syntax
issubclass(class, classinfo)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
class | class | — | The class to check |
classinfo | class or tuple of classes | — | The class or classes to check against |
Examples
Basic usage
class Animal:
pass
class Dog(Animal):
pass
class Cat(Animal):
pass
print(issubclass(Dog, Animal)) # True — Dog inherits from Animal
print(issubclass(Cat, Animal)) # True — Cat inherits from Animal
print(issubclass(Animal, Animal)) # True — a class is a subclass of itself
print(issubclass(Dog, Cat)) # False — no inheritance relationship
Checking against a tuple of classes
class Vehicle:
pass
class Car(Vehicle):
pass
class Bicycle:
pass
print(issubclass(Car, (Vehicle, Bicycle))) # True — Car is a subclass of Vehicle
print(issubclass(Bicycle, (Vehicle, Bicycle))) # True — Bicycle is a subclass of itself
print(issubclass(str, (Vehicle, Bicycle))) # False — str is unrelated
Practical pattern: type checking before casting
class User:
def __init__(self, name):
self.name = name
class Admin(User):
def delete_users(self):
return True
class Guest:
pass
def process_user(user):
# Check the type before acting on admin-specific features
if issubclass(type(user), User):
print(f"Processing user: {user.name}")
if issubclass(type(user), Admin):
user.delete_users()
print(f"Admin {user.name} can delete users")
admin = Admin("Alice")
guest = Guest()
process_user(admin) # Processing user: Alice\nAdmin Alice can delete users
process_user(guest) # (nothing printed for User check since Guest isn't a subclass)
Common Patterns
Factory pattern with class registration
class Plugin:
pass
class TextPlugin(Plugin):
def process(self, data):
return data.upper()
class ImagePlugin(Plugin):
def process(self, data):
return f"[IMAGE: {data}]"
# Registry of available plugins
plugins = [TextPlugin, ImagePlugin]
def get_plugin(plugin_class):
if issubclass(plugin_class, Plugin):
return plugin_class()
raise TypeError(f"{plugin_class} is not a subclass of Plugin")
text = get_plugin(TextPlugin)
print(text.process("hello")) # HELLO
Duck typing verification
class Serializable:
def serialize(self):
raise NotImplementedError
class JSONSerializable(Serializable):
def serialize(self):
return {"data": "serialized"}
class CustomData:
def serialize(self):
return "custom"
def save_to_database(obj):
if issubclass(type(obj), Serializable):
return obj.serialize()
raise TypeError("Object must be serializable")
data = JSONSerializable()
print(save_to_database(data)) # {'data': 'serialized'}
Errors
TypeError: classinfo is not a class or tuple of classes
class Foo:
pass
# This raises TypeError
issubclass(Foo, "not a class")
# Error: issubclass() arg 2 must be a class, a tuple of classes, or a class variable
The function raises TypeError when classinfo is neither a class nor a tuple of classes. This prevents accidental misuse with invalid type arguments.
# Correct usage
print(issubclass(Dog, Animal)) # True
print(issubclass(Dog, (Animal, object))) # True
# Incorrect usage raises TypeError
issubclass(Dog, "Animal") # TypeError
issubclass(Dog, 123) # TypeError
issubclass(Dog, [Animal, object]) # TypeError — lists aren't allowed
See Also
- built-in::isinstance — check if an object is an instance of a class or tuple of classes
- built-in::type — get the type of an object
- built-in::hasattr — check if an object has a specific attribute