-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Open
Labels
Description
When @auto is representing an attribute (__init__() arg) which is emitted as positional (rather than with the attribute name), the implementation yields the value directly. If that value is a tuple, it will be misinterpreted as a (name, value, ...) group, causing TypeErrors later when rendering.
Fixed by pull request #4014.
An example of #4015.
Reproduction code:
from __future__ import annotations
import rich
import rich.repr
class ClassA:
"This class is not a `str` and doesn't have a `__len__()` method"
@rich.repr.auto
class ClassB:
pair_of_a_instances: tuple[ClassA, ClassA]
def __init__(self, pair_of_a_instances: tuple[ClassA, ClassA], /) -> None:
self.pair_of_a_instances = pair_of_a_instances
def test_textualize_rich_4014() -> None:
a1 = ClassA()
a2 = ClassA()
pair_of_a_instances = (a1, a2)
b = ClassB(pair_of_a_instances)
rich.print(b) # XXX raises a `TypeError`!Traceback:
def test_textualize_rich_4014() -> None:
a1 = ClassA()
a2 = ClassA()
pair_of_a_instances = (a1, a2)
b = ClassB(pair_of_a_instances)
> rich.print(b) # XXX raises a `TypeError`!
^^^^^^^^^^^^^
rich_bug_example.py:25:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
……/python3.14/site-packages/rich/__init__.py:74: in print
return write_console.print(*objects, sep=sep, end=end)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
……/python3.14/site-packages/rich/console.py:1724: in print
extend(render(renderable, render_options))
……/python3.14/site-packages/rich/console.py:1345: in render
for render_output in iter_render:
^^^^^^^^^^^
……/python3.14/site-packages/rich/pretty.py:307: in __rich_console__
pretty_str = pretty_repr(
……/python3.14/site-packages/rich/pretty.py:912: in pretty_repr
repr_str: str = node.render(
……/python3.14/site-packages/rich/pretty.py:485: in render
if expand_all or not line.check_length(max_width):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
……/python3.14/site-packages/rich/pretty.py:517: in check_length
return self.node.check_length(start_length, max_length)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
……/python3.14/site-packages/rich/pretty.py:458: in check_length
total_length += cell_len(token)
^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
text = <rich_bug_example.ClassA object at 0x10839b770>, unicode_version = 'auto'
def cell_len(text: str, unicode_version: str = "auto") -> int:
"""Get the cell length of a string (length as it appears in the terminal).
Args:
text: String to measure.
unicode_version: Unicode version, `"auto"` to auto detect, `"latest"` for the latest unicode version.
Returns:
Length of string in terminal cells.
"""
> if len(text) < 512:
^^^^^^^^^
E TypeError: object of type 'ClassA' has no len()
……/python3.14/site-packages/rich/cells.py:108: TypeError
Reactions are currently unavailable