From 89d7604f2f4432b5dd8064edb3e8a22f4acdb63e Mon Sep 17 00:00:00 2001 From: Venkata Ramana Menda Date: Thu, 11 Dec 2025 21:37:56 +0530 Subject: [PATCH] Respect Custom Repr --- rich/pretty.py | 20 +++++++++++++++++++- tests/test_pretty.py | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/rich/pretty.py b/rich/pretty.py index 5c725c0c..ef58988e 100644 --- a/rich/pretty.py +++ b/rich/pretty.py @@ -67,6 +67,24 @@ def _get_attr_fields(obj: Any) -> Sequence["_attr_module.Attribute[Any]"]: return _attr_module.fields(type(obj)) if _has_attrs else [] +def _is_attr_repr(obj: object) -> bool: + """Check if an instance of an attrs class contains the default repr. + + Args: + obj (object): An attrs instance. + + Returns: + bool: True if the default repr is used, False if there is a custom repr. + """ + if not _has_attrs: + return False + try: + # attrs-generated repr methods have a source file containing " bool: """Check if an instance of a dataclass contains the default repr. @@ -711,7 +729,7 @@ def traverse( last=root, ) pop_visited(obj_id) - elif _is_attr_object(obj) and not fake_attributes: + elif _is_attr_object(obj) and not fake_attributes and _is_attr_repr(obj): push_visited(obj_id) children = [] append = children.append diff --git a/tests/test_pretty.py b/tests/test_pretty.py index 29331d9d..740b80e2 100644 --- a/tests/test_pretty.py +++ b/tests/test_pretty.py @@ -675,6 +675,27 @@ def test_attrs_broken_310() -> None: assert result == expected +def test_attrs_custom_repr() -> None: + @attr.define + class Foo: + x: int = 1 + + def __repr__(self) -> str: + return "CustomFoo" + + assert pretty_repr(Foo()) == "CustomFoo" + + +def test_attrs_default_repr() -> None: + @attr.define + class Bar: + x: int = 5 + y: str = "test" + + result = pretty_repr(Bar()) + assert result == "Bar(x=5, y='test')" + + def test_user_dict() -> None: class D1(UserDict): pass