mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-32499: Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass or an instance of one. (#5113)
This commit is contained in:
parent
3cd7c6e6eb
commit
e7ba013d87
3 changed files with 36 additions and 22 deletions
|
@ -16,6 +16,7 @@ __all__ = ['dataclass',
|
|||
'astuple',
|
||||
'make_dataclass',
|
||||
'replace',
|
||||
'is_dataclass',
|
||||
]
|
||||
|
||||
# Raised when an attempt is made to modify a frozen class.
|
||||
|
@ -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.
|
||||
|
@ -639,12 +646,12 @@ def asdict(obj, *, dict_factory=dict):
|
|||
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)
|
||||
|
@ -678,12 +685,12 @@ def astuple(obj, *, tuple_factory=tuple):
|
|||
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)
|
||||
|
@ -751,7 +758,7 @@ def replace(obj, **changes):
|
|||
# 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'.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue