Skip to content

Support dataclass inheritance #287

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions