diff --git a/rich/pretty.py b/rich/pretty.py index a3d1f7471..57f3e62e2 100644 --- a/rich/pretty.py +++ b/rich/pretty.py @@ -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 iter_attrs() -> Iterable[ 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