python/cpython · error · TypeError
issubclass() arg 1 must be a class
Error message
issubclass() arg 1 must be a class
What it means
Raised by ABCMeta.__subclasscheck__ (pure-Python _py_abc fallback; the C _abc raises the equivalent) when issubclass() is called with a first argument that is not a class. ABCs implement duck-typed virtual subclass checks that only make sense for classes, so issubclass(instance, MyABC) fails fast with TypeError instead of guessing.
Source
Thrown at Lib/_py_abc.py:111
"""Override for isinstance(instance, cls)."""
# Inline the cache checking
subclass = instance.__class__
if subclass in cls._abc_cache:
return True
subtype = type(instance)
if subtype is subclass:
if (cls._abc_negative_cache_version ==
ABCMeta._abc_invalidation_counter and
subclass in cls._abc_negative_cache):
return False
# Fall back to the subclass check.
return cls.__subclasscheck__(subclass)
return any(cls.__subclasscheck__(c) for c in (subclass, subtype))
def __subclasscheck__(cls, subclass):
"""Override for issubclass(subclass, cls)."""
if not isinstance(subclass, type):
raise TypeError('issubclass() arg 1 must be a class')
# Check cache
if subclass in cls._abc_cache:
return True
# Check negative cache; may have to invalidate
if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
# Invalidate the negative cache
cls._abc_negative_cache = WeakSet()
cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
elif subclass in cls._abc_negative_cache:
return False
# Check the subclass hook
ok = cls.__subclasshook__(subclass)
if ok is not NotImplemented:
assert isinstance(ok, bool)
if ok:
cls._abc_cache.add(subclass)
else:
cls._abc_negative_cache.add(subclass)View on GitHub (pinned to bc6749cc3b)
Solutions
- Use isinstance(obj, MyABC) when checking an instance
- Branch on the argument kind: issubclass(x, MyABC) if isinstance(x, type) else isinstance(x, MyABC)
- Validate external input before passing it to issubclass
Example fix
# before issubclass(widget, Drawable) # widget is an instance -> TypeError # after isinstance(widget, Drawable) # instance check # or, for either kind: isinstance(widget, Drawable) if not isinstance(widget, type) else issubclass(widget, Drawable)
Defensive patterns
Strategy: type-guard
Validate before calling
def is_a(obj, abc) -> bool:
"""Works for both instances and classes."""
if isinstance(obj, type):
return issubclass(obj, abc)
return isinstance(obj, abc) Type guard
def is_klass(obj) -> bool:
return isinstance(obj, type) Prevention
- issubclass(A, B) takes two classes; isinstance(a, B) takes an instance
- In generic helpers, branch on isinstance(obj, type) before choosing the check
- Never forward unvalidated external input into issubclass against an ABC
When it happens
Trigger: issubclass(obj, MyABC) where obj is an instance; passing a non-type (module, function, mock) to issubclass against any ABC; custom code that forwards user input into issubclass without checking it is a type. isinstance(instance, MyABC) does NOT raise — the error only comes from the issubclass path.
Common situations: Generic helper functions that want to accept 'class or instance' and call issubclass unconditionally; copy/paste swapping isinstance/issubclass; serialization frameworks dispatching on either a class or an instance; tests probing ABCs with fixtures.
Related errors
- Can only register classes
- Callable must be used as Callable[[arg, ...], result].
- Expected a list of types, an ellipsis, ParamSpec, or Concate
- Refusing to create an inheritance cycle
- Forward reference must be a string -- got {arg!r}
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/230492a069184f86.
Report an issue: GitHub.