rich icon indicating copy to clipboard operation
rich copied to clipboard

[REQUEST] Make classes pretty printable via __rich_repr__

Open jankatins opened this issue 2 years ago • 4 comments

How would you improve Rich?

Currently a class will not use __rich_repr__() as the code has it hard coded to ignore classes:

https://github.com/Textualize/rich/blob/720800e6930d85ad027b1e9bd0cbb96b5e994ce3/rich/pretty.py#L639-L643

It would be nice if there is a way to define a rich repr to print the class (e.g. using a metaclass). E.g. by marking the function ala __rich_repr__.use_on_class = True or using a class specific protocol __rich_repr_class__(cls).

What problem does it solve for you?

We use classes for defining some data structure (mostly because using the python editor really convenient). It would be nice to pretty print the data structure. I can imagine that pretty printing pydantic/sqlalachemy classes have a similar problem.

Example:

class Metadata: pass
class Attribute: pass
class BaseObject(): pass

class SomeDefinition(BaseObject):
    __metadata__ = Metadata(...)
   some_attribute = Attribute(...)
   some_other_attribute = Attribute(...)

With some hackery it is actually possible:

  • Use a metaclass in the base class definition which defines a __rich_repr__()
  • Patch rich.pretty.isclass to exclude that base class (return False if isinstance(obj, MetaClass) else orig_isclass(obj))

jankatins avatar Sep 01 '23 16:09 jankatins

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

github-actions[bot] avatar Sep 01 '23 16:09 github-actions[bot]

When you say "print the class" what kind of output are you expecting?

willmcgugan avatar Sep 01 '23 16:09 willmcgugan

Good question: in our case, I want to treat the class as every other object and print the class variables.

Example:

class Whatever:
    x = Attribute(...)
    y = Attribute(...)

    @classmethod
    def __rich_class_repr__(cls):
        yield "x", cls.x
        yield "y", cls.y

would print more or less as if would have instantiated the class and used the regular __rich_repr__(self) protocol.

jankatins avatar Sep 02 '23 16:09 jankatins

This would be of great use for us as well!

oelhammouchi avatar May 29 '25 07:05 oelhammouchi