Reworking pretty namedtuples support, more defensive

This commit is contained in:
Darren Burns 2022-03-08 14:06:20 +00:00
parent 4febd6e4aa
commit 5d64431242
No known key found for this signature in database
GPG Key ID: B0939B45037DC345
1 changed files with 11 additions and 9 deletions

View File

@ -92,17 +92,13 @@ def _has_default_namedtuple_repr(obj: object) -> bool:
bool: True if the default repr is used, False if there's a custom repr.
"""
obj_file = None
default_repr_file = None
try:
obj_file = inspect.getfile(obj.__repr__)
except (OSError, TypeError):
# OSError handles case where object is defined in __main__ scope, e.g. REPL - no filename available.
# TypeError trapped defensively, in case of object without filename slips through.
pass
try:
default_repr_file = inspect.getfile(_dummy_namedtuple.__repr__)
except (OSError, TypeError):
pass
default_repr_file = inspect.getfile(_dummy_namedtuple.__repr__)
return obj_file == default_repr_file
@ -563,7 +559,11 @@ def _is_namedtuple(obj: Any) -> bool:
Returns:
bool: True if the object is a namedtuple. False otherwise.
"""
fields = getattr(obj, "_fields", None)
try:
fields = getattr(obj, "_fields", None)
except Exception:
# Being very defensive - if we cannot get the attr then its not a namedtuple
return False
return isinstance(obj, tuple) and isinstance(fields, tuple)
@ -775,16 +775,18 @@ def traverse(
pop_visited(obj_id)
elif _is_namedtuple(obj) and _has_default_namedtuple_repr(obj):
children = []
append = children.append
if reached_max_depth:
node = Node(value_repr="...")
else:
children = []
class_name = obj.__class__.__name__
node = Node(
open_brace=f"{obj.__class__.__name__}(",
open_brace=f"{class_name}(",
close_brace=")",
children=children,
empty=f"{class_name}()",
)
append = children.append
for last, (key, value) in loop_last(obj._asdict().items()):
child_node = _traverse(value, depth=depth + 1)
child_node.key_repr = key