From ac985c9d0545109baaa248960011ff5e117196f3 Mon Sep 17 00:00:00 2001 From: kaztral Date: Tue, 24 Feb 2026 12:30:01 +0530 Subject: [PATCH] Fix @auto rich repr handling of tuple positional-only args --- rich/repr.py | 2 +- tests/test_pretty.py | 15 +++++++++++++++ tests/test_repr.py | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/rich/repr.py b/rich/repr.py index 95331006ee..cf01aac381 100644 --- a/rich/repr.py +++ b/rich/repr.py @@ -71,7 +71,7 @@ def auto_rich_repr(self: Type[T]) -> Result: signature = inspect.signature(self.__init__) for name, param in signature.parameters.items(): if param.kind == param.POSITIONAL_ONLY: - yield getattr(self, name) + yield None, getattr(self, name) elif param.kind in ( param.POSITIONAL_OR_KEYWORD, param.KEYWORD_ONLY, diff --git a/tests/test_pretty.py b/tests/test_pretty.py index 29331d9d5c..15753db1e1 100644 --- a/tests/test_pretty.py +++ b/tests/test_pretty.py @@ -9,6 +9,7 @@ import attr import pytest +import rich.repr from rich.console import Console from rich.measure import Measurement from rich.pretty import Node, Pretty, _ipy_display_hook, install, pprint, pretty_repr @@ -739,6 +740,20 @@ def __rich_repr__(self): assert pretty_repr(Foo()) == "Foo()" +def test_auto_tuple_positional_only_repr() -> None: + class ClassA: + pass + + @rich.repr.auto + class PosOnlyTuple: + def __init__(self, pair, /): + self.pair = pair + + result = pretty_repr(PosOnlyTuple((ClassA(), ClassA()))) + assert result.startswith("PosOnlyTuple(") + assert "ClassA object" in result + + def test_dataclass_no_attribute() -> None: """Regression test for https://github.com/Textualize/rich/issues/3417""" from dataclasses import dataclass, field diff --git a/tests/test_repr.py b/tests/test_repr.py index 94fd6da1f6..e77f964233 100644 --- a/tests/test_repr.py +++ b/tests/test_repr.py @@ -110,6 +110,27 @@ def __init__(self, foo, /): assert repr(p) == "PosOnly(1)" +def test_rich_repr_positional_only_tuple() -> None: + class ClassA: + pass + + _locals = locals().copy() + exec( + """\ +@rich.repr.auto +class PosOnlyTuple: + def __init__(self, pair, /): + self.pair = pair + """, + globals(), + _locals, + ) + p = _locals["PosOnlyTuple"]((ClassA(), ClassA())) + result = repr(p) + assert result.startswith("PosOnlyTuple((") + assert "ClassA object" in result + + def test_rich_angular() -> None: assert (repr(Bar("hello"))) == "" assert (repr(Bar("hello", bar=3))) == ""