Explain Codes LogoExplain Codes Logo

Super() fails with error: TypeError "argument 1 must be type, not classobj" when parent does not inherit from object

python
method-resolution-order
class-inheritance
python-2.x
Anton ShumikhinbyAnton Shumikhin·Mar 8, 2025
TLDR

To bypass the notorious TypeError with super(), in Python 2.x let your class be a proud heir of object:

class Parent(object): # Royal lineage from object pass class Child(Parent): def __init__(self): # Who's your daddy now? 👉 It's Parent! super(Child, self).__init__()

Python 3 is a democratic universe where all classes are of new-style, implicitly inherit from object, and thus, super() works without trouble.

Old-style vs New-style: The Class War!

Python has two types of classes: old-style and new-style. In Python 2.x, classes that don't inherit from object are old-style, which sadly don't support super() and have issues with Method Resolution Order (MRO). Spoiler: old-style classes usually end up on the losing side of the class war. 🚫

However, classes inheriting from object are known as new-style classes. Blazing the trail with consistent support for super() and a predictable MRO, new-style classes are the brave warriors of Python, always ready to win the battle! ✅ New-style also unlocks valuable additional features, such as descriptors.

Marching from Old to New

Refactoring your Python 2.x codebase to adopt new-style classes is as easy as letting your classes inherit from __metaclass__ = type. That's right - it's like declaring their royal lineage right at birth! 👑

__metaclass__ = type # Change your stars, old ones! class Parent: # Voila! Parent is now new and all shiny! pass class Child(Parent): def __init__(self): # Like Parent, Like Child. New-style is contagious! super(Child, self).__init__()

Multiple Inherits: Who's Your Daddy?

In Python's aristocratic society, one can have multiple parents! But to ensure the Class War doesn't get messier, always inherit from object in multi-inheritance scenarios:

class Base1(object): pass class Base2(object): pass class MultiDerived(Base1, Base2): def __init__(self): # Always remember your parents, all of them! super(MultiDerived, self).__init__()

Failure to do so might lead to an unexpected "TypeError". Trust me, you don't want that surprise!

The Magic Metaclass

__metaclass__ can be your fairy godmother, transforming old-classes into new-style balls of effectiveness with a single line! When defined at module-level, it paves the way for new-style amenities, especially useful when dealing with extensive codebases!

But remember, there's no substitute for good-old hard work! So, refactor your classes to new-style whenever possible.

Tips for a Happy Coding Kingdom

In the land of Python 2.x, remember these golden rules for a blissful reign:

  • All class definitions should own their inheritance from (object).
  • Use __metaclass__ = type for migrating large codebases to new-style classes.
  • Pay your respects to both parents in multiple inheritance by inheriting from object.
  • Regularly refactor your code to use new-style classes.

So, keep calm and code on!