Python

super raises TypeError must be type not classobj for new-style class

25 September 2026 · 6 min read

super raises TypeError must be type not classobj for new-style class

Inheriting and extending class functionality is a cornerstone of object-oriented programming in Python. The super() function, introduced with new-style classes, provides a clean and reliable way to achieve this. However, it can sometimes throw a curveball in the form of a “TypeError: must be type, not classobj,” especially when working with new-style classes. This error can be perplexing, but understanding its root cause and solutions can significantly streamline your Python development process. Let’s dive into the intricacies of this error, exploring its causes and providing clear solutions to help you navigate this common Python inheritance pitfall.

Understanding the “TypeError: must be type, not classobj”

This error typically arises when super() is called incorrectly within a new-style class. It indicates that you’re passing the class object itself to super() instead of the class type. In simpler terms, you’re telling super() “I want to operate on this specific instance of the class,” when it expects you to say “I want to operate on the blueprint of the class itself.” This subtle distinction is crucial for super() to correctly resolve the method resolution order (MRO).

One common scenario where this error occurs is when defining a metaclass. Metaclasses operate on classes, and inadvertently passing the class object within the metaclass’s __new__ or __init__ methods can trigger the TypeError. Another scenario involves diamond inheritance where multiple inheritance paths exist, potentially leading to confusion about which class super() should reference.

For example:

class MyClass: def __init__(self): super(MyClass, self).__init__() Incorrect usage 

Correctly Using super() with New-Style Classes

The solution to this TypeError is straightforward: ensure you are passing the correct arguments to super(). In Python 3, the recommended and often simplest way is to call super() without any arguments within a class method:

class MyClass: def __init__(self): super().__init__() Correct usage in Python 3 

This concise syntax lets Python automatically determine the correct class and instance. For Python 2, using super(MyClass, self).__init__() is still necessary.

When dealing with metaclasses, remember to pass the class object’s type (e.g., type(cls)) to super() within the metaclass methods.

Real-World Examples and Case Studies

Imagine building a web application using a framework like Django or Flask. You might encounter this error when defining model classes that inherit from base framework classes. Incorrectly using super() in your model’s __init__ method could prevent proper initialization and database interaction.

Another example could involve creating a custom exception class. Inheriting from a base exception class requires the correct use of super() to ensure the exception is properly initialized with relevant information.

Consider a library like SQLAlchemy, an Object-Relational Mapper (ORM). When defining model classes that inherit from SQLAlchemy’s base classes, correct usage of super() ensures that database table definitions are generated and managed properly.

Debugging and Troubleshooting

When faced with this TypeError, carefully examine the code where super() is called. Double-check that you are passing the class type and instance correctly. Print the type of the arguments passed to super() for clarity. Using a debugger can help step through the code and identify the exact point where the error occurs. Understanding the MRO of your classes can also be crucial in complex inheritance scenarios.

  • Verify super() arguments.
  • Use a debugger.
  1. Identify the erroring line.
  2. Check the types of arguments passed to super().
  3. Correct the arguments based on Python version and context.

Infographic Placeholder: Illustrating the correct usage of super() in different inheritance scenarios.

By understanding the nuances of super() and its interaction with new-style classes, you can effectively avoid the “TypeError: must be type, not classobj” and write more robust and maintainable Python code. Mastering inheritance is a key skill in object-oriented programming, allowing for code reuse and extensibility. Addressing this TypeError empowers you to leverage the full potential of inheritance in your Python projects.

For further reading on Python’s object model and inheritance, check out these resources:

Need to delve deeper into advanced Python concepts? Explore our advanced Python tutorials covering topics such as metaclasses, decorators, and more. These resources offer insights into building more sophisticated and powerful Python applications.

FAQ

Q: What is the difference between old-style and new-style classes in Python?

A: New-style classes, introduced in Python 2.2 and the default in Python 3, unify types and classes, offering a more consistent and flexible object model. Old-style classes lack this unification. The distinction is less relevant in Python 3 where all classes are new-style.

Question & Answer :
The following use of super() raises a TypeError: why?

>>> from HTMLParser import HTMLParser >>> class TextParser(HTMLParser): ... def __init__(self): ... super(TextParser, self).__init__() ... self.all_data = [] ... >>> TextParser() (...) TypeError: must be type, not classobj 

There is a similar question on StackOverflow: Python super() raises TypeError, where the error is explained by the fact that the user class is not a new-style class. However, the class above is a new-style class, as it inherits from object:

>>> isinstance(HTMLParser(), object) True 

What am I missing? How can I use super(), here?

Using HTMLParser.__init__(self) instead of super(TextParser, self).__init__() would work, but I would like to understand the TypeError.

PS: Joachim pointed out that being a new-style-class instance is not equivalent to being an object. I read the opposite many times, hence my confusion (example of new-style class instance test based on object instance test: https://stackoverflow.com/revisions/2655651/3).

Alright, it’s the usual “super() cannot be used with an old-style class”.

However, the important point is that the correct test for “is this a new-style instance (i.e. object)?” is

>>> class OldStyle: pass >>> instance = OldStyle() >>> issubclass(instance.__class__, object) False 

and not (as in the question):

>>> isinstance(instance, object) True 

For classes, the correct “is this a new-style class” test is:

>>> issubclass(OldStyle, object) # OldStyle is not a new-style class False >>> issubclass(int, object) # int is a new-style class True 

The crucial point is that with old-style classes, the class of an instance and its type are distinct. Here, OldStyle().__class__ is OldStyle, which does not inherit from object, while type(OldStyle()) is the instance type, which does inherit from object. Basically, an old-style class just creates objects of type instance (whereas a new-style class creates objects whose type is the class itself). This is probably why the instance OldStyle() is an object: its type() inherits from object (the fact that its class does not inherit from object does not count: old-style classes merely construct new objects of type instance). Partial reference: https://stackoverflow.com/a/9699961/42973.

PS: The difference between a new-style class and an old-style one can also be seen with:

>>> type(OldStyle) # OldStyle creates objects but is not itself a type classobj >>> isinstance(OldStyle, type) False >>> type(int) # A new-style class is a type type 

(old-style classes are not types, so they cannot be the type of their instances).