Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make sure subclasses are dataclasses?

I have a base class to provide functionality to a variety of classes, and I want to make sure classes that inherit from this one are decorated with @dataclass. The following definition results in the ValueError being raised:

from dataclasses import dataclass, is_dataclass


class Base:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        if not is_dataclass(cls):
            raise ValueError('Base subclasses should be dataclasses.')


@dataclass
class Child(Base):
    ...

As I understand, this is due to the inheritance happening (and therefore Base.__init_subclass__(Child) running) before the @dataclass has a chance to run. Is there a nice way to work around this?

like image 231
Dunya Degirmenci Avatar asked Sep 19 '25 21:09

Dunya Degirmenci


1 Answers

Perhaps you can decorate your classes. Here's the idea (adjust accordingly).

Given

import dataclasses as dc

Code

def verify_dataclass(kls):
    if not dc.is_dataclass(kls):
        print(f"'{kls.__name__}' is not a dataclass.")
        # Do something
    return kls

Demo

A dataclass is ok.

@verify_dataclass
@dc.dataclass
class Foo:
    pass

A subclass of a dataclass is ok.

@verify_dataclass
class Bar(Foo):
    pass

A regular class warns.

@verify_dataclass
class Baz:
    pass

# 'Baz' is not a dataclass.
like image 138
pylang Avatar answered Sep 21 '25 11:09

pylang