bpo-32499: Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass or an instance of one. by ericvsmith · Pull Request #5113 · python/cpython

Expand Up @@ -16,6 +16,7 @@ 'astuple', 'make_dataclass', 'replace', 'is_dataclass', ]
# Raised when an attempt is made to modify a frozen class. Expand Down Expand Up @@ -615,11 +616,17 @@ def fields(class_or_instance): return tuple(f for f in fields.values() if f._field_type is _FIELD)

def _isdataclass(obj): def _is_dataclass_instance(obj): """Returns True if obj is an instance of a dataclass.""" return not isinstance(obj, type) and hasattr(obj, _MARKER)

def is_dataclass(obj): """Returns True if obj is a dataclass or an instance of a dataclass.""" return hasattr(obj, _MARKER)

def asdict(obj, *, dict_factory=dict): """Return the fields of a dataclass instance as a new dictionary mapping field names to field values. Expand All @@ -639,12 +646,12 @@ class C: dataclass instances. This will also look into built-in containers: tuples, lists, and dicts. """ if not _isdataclass(obj): if not _is_dataclass_instance(obj): raise TypeError("asdict() should be called on dataclass instances") return _asdict_inner(obj, dict_factory)
def _asdict_inner(obj, dict_factory): if _isdataclass(obj): if _is_dataclass_instance(obj): result = [] for f in fields(obj): value = _asdict_inner(getattr(obj, f.name), dict_factory) Expand Down Expand Up @@ -678,12 +685,12 @@ class C: tuples, lists, and dicts. """
if not _isdataclass(obj): if not _is_dataclass_instance(obj): raise TypeError("astuple() should be called on dataclass instances") return _astuple_inner(obj, tuple_factory)
def _astuple_inner(obj, tuple_factory): if _isdataclass(obj): if _is_dataclass_instance(obj): result = [] for f in fields(obj): value = _astuple_inner(getattr(obj, f.name), tuple_factory) Expand Down Expand Up @@ -751,7 +758,7 @@ class C: # We're going to mutate 'changes', but that's okay because it's a new # dict, even if called with 'replace(obj, **my_changes)'.
if not _isdataclass(obj): if not _is_dataclass_instance(obj): raise TypeError("replace() should be called on dataclass instances")
# It's an error to have init=False fields in 'changes'. Expand Down