9

I am trying to call a a superclass method from a dataclass with slots=True in Python 3.10.5.

from dataclasses import dataclass


@dataclass(slots=True)
class Base:
    def hi(self):
        print("Hi")


@dataclass(slots=True)
class Sub(Base):
    def hi(self):
        super().hi()


Sub().hi()

I get the following error.

Traceback (most recent call last):
  File "...", line 16, in <module>
    Sub().hi()
  File "...", line 13, in hi
    super().hi()
TypeError: super(type, obj): obj must be an instance or subtype of type

It works fine if I remove slots=True from Sub, or make it a non-dataclass with __slots__ manually. The error remains if I instead do these to Base.

Sub.__mro__ is (<class '__main__.Sub'>, <class '__main__.Base'>, <class 'object'>) and isinstance(Sub(), Base) is True.

LeopardShark
  • 3,820
  • 2
  • 19
  • 33
  • 2
    You may have the same issue as [this question](https://stackoverflow.com/questions/46159210/what-is-the-difference-between-super-and-explicit-supercl-self-with-slots) using the 0-argument form of `super()`. – sj95126 Aug 07 '22 at 16:18

1 Answers1

10

As seen here, the dataclass decorator creates a new class object, and so the __closure__ attached to hi() is different to the one attached to the decorated class, and therefore the super() call cannot work without arguments due to relying on the __closure__.

Therefore, you need to change super().hi() to super(Sub, self).hi().

henry groves
  • 710
  • 4
  • 19