Skip to content

Support dataclass inheritance #287

@gautiervarjo

Description

@gautiervarjo

🚀 Feature request

The documentation describes how dataclass-like classes are "not expected to have subclasses", and therefore do not accept specifying a class_path. However dataclasses.dataclass does support inheritance: python docs

Would it be feasible to add support for this? I can't say whether this makes sense for all dataclass-like objects, or just the plain python ones.

My use-case for dataclass+inheritance is pretty basic, my main reason for using dataclasses is reducing boilerplate of writing __init__/__str__/etc functions.

To reproduce

A working example with plain classes

import dataclasses
import jsonargparse

class Base:
    def __init__(self, name: str) -> None:
        self.name = name

class Derived(Base):
    def __init__(self) -> None:
        super().__init__(name="derived plain")

parser = jsonargparse.ArgumentParser()
parser.add_subclass_arguments(Base, "thing")
print(parser.parse_args(["--thing.class_path=Derived"]))

A failing example with dataclasses

import dataclasses
import jsonargparse

@dataclasses.dataclass
class DataclassBase:
    name: str

@dataclasses.dataclass
class DataclassDerived(DataclassBase):
    def __init__(self) -> None:
        super().__init__(name="derived dataclass")

# Does not work, jsonargparse assumes no inheritance for dataclass-like types.
parser = jsonargparse.ArgumentParser()

parser.add_subclass_arguments(DataclassBase, "thing")
# ^ this raises: "ValueError: Not allowed for dataclass-like classes."

print(parser.parse_args(["--thing.class_path=DataclassDerived"]))

A failing example with CLI + config

# Config
thing:
  class_path: Derived
# ... snip ...: same definition of DataclassBase and DataclassDerived.

def main(thing: DataclassBase) -> None:
    pass

jsonargparse.CLI(main)
# Passing the config above to this CLI produces:
# usage: parser.py [-h] [--config CONFIG] [--print_config[=flags]] [--thing CONFIG] --thing.name NAME
# parser.py: error: Configuration check failed :: Key "thing.name" is required but not included in config object or its value is None.

Expected behavior

The failing dataclass snippet should behave exactly like the working plain-class one.

Environment

  • jsonargparse version: 4.21.1
  • Python version: 3.8
  • How jsonargparse was installed: installed via Pants/PEX, using the requirement line jsonargparse[signatures]==4.21.1.
  • OS: Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions