GitHub - arvidma/dataclasses: Vibe coded backports of 3.8+ dataclass features to 3.6

GitHub

2 min read Original article ↗

Adds most dataclass features from Python versions after 3.7 to the excellent but long-since abandoned backport by Eric V. Smith (https://github.com/ericvsmith/dataclasses/).

For those of us still stuck writing Python for systems tied hard to the oldest LTS releases of Ubuntu and RedHat.

Matrix of backported and not-yet-backported features:

Python version Feature Status
3.8 InitVar[T] generic syntax Backported
3.8 replace() handling of InitVar fields with defaults Backported
3.10 kw_only parameter and KW_ONLY sentinel Backported
3.10 match_args parameter (__match_args__ generation) Backported
3.10 slots parameter (__slots__ generation) Backported
3.11 weakref_slot parameter Backported
3.11 Frozen+slots pickling (__getstate__/__setstate__) Backported
3.11 Slots with init=False default fields (bpo-44649) Backported
3.11–3.12 fields() traceback improvements Backported
3.11–3.12 Mutable default value validation Backported
3.12 Field named BUILTINS in frozen classes (gh-96151) Backported
3.12 Special underscore field names like _dflt_x (gh-98886) Backported
3.12 Inherited __dict__ slot handling Backported
3.12–3.13 Optimized __eq__ and __repr__ recursion guards Backported
3.12 asdict()/astuple() atomic-type fast paths (gh-91896) Backported
3.13 Single-exec method generation (_FuncBuilder, gh-107550) Backported
3.13 Non-frozen subclass of frozen: mutable attr set/delete Backported
3.14 decorator parameter for make_dataclass() Backported
3.12 module parameter for make_dataclass() Not backported
3.12 defaultdict support in asdict()/astuple() Not backported
3.13 __replace__() method (copy.replace() support) Not backported

Usage

Drop the single dataclasses.py file into your project (vendoring), or add it to your Python path. It is a drop-in replacement for the standard library module and can transparently replace the stdlib if running on a Python version that doesn't support some feature you like.

Supports Python 3.6 and later from a single codebase — the only version-sensitive code is the ClassVar detection, which adapts to the typing internals of the running interpreter. The test suite runs in CI on Python 3.6 through 3.13.

Note: don't mix this module with the stdlib dataclasses in the same class. InitVar, Field, field() and the KW_ONLY sentinel are compared by identity, so e.g. a stdlib InitVar annotation on a class decorated with this module's @dataclass will not be recognized. Import everything from one module, as in the example below.

try:
    from dataclasses import dataclass, field, KW_ONLY
except ImportError:
    from myproj.vendor.dataclasses import dataclass, field, KW_ONLY  # type: ignore[no-redef]

@dataclass(slots=True, kw_only=True)
class Point:
    x: float
    y: float
    z: float = 0.0

Full @dataclass decorator signature

@dataclass(
    init=True,           # 3.7
    repr=True,           # 3.7
    eq=True,             # 3.7
    order=False,         # 3.7
    unsafe_hash=False,   # 3.7
    frozen=False,        # 3.7
    match_args=True,     # 3.10
    kw_only=False,       # 3.10
    slots=False,         # 3.10
    weakref_slot=False,  # 3.11
)