Skip to content

Instantly share code, notes, and snippets.

@willmcgugan
Created October 6, 2021 09:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willmcgugan/0bc658abd13ad35f4c3f1d24ea7e2ea3 to your computer and use it in GitHub Desktop.
Save willmcgugan/0bc658abd13ad35f4c3f1d24ea7e2ea3 to your computer and use it in GitHub Desktop.

With dataclasses Rich will essentially replace the dataclass __repr__ by inspecting the dataclass fields. It does this so it can know how to expand the dataclass on to multiple lines with indentation.

For example, here is a dataclass

@dataclass
class DC:
    foo: str
    bar: int

Rich can inspect the fields and generate this:

DC(
    foo="hello",
    bar=5
)

However Rich will respect a custom rerpr. For example:

@dataclass
class DC:
    foo: str
    bar: int
    
    def __repr__(self):
        return "DC is better than Marvel"

In the above case, Rich will call repr(dc) rather than inspecting the fields.

So Rich needs to know if that custom __repr__ is present.

The problem is that the cases with or without the custom __repr__, the dataclass instances both contain a __repr__. And Rich needs to know if it is the default one generated by the @dataclass decorator OR one provided by the user.

Since there is no dataclass base class, I can't just compare it to the baseclasses (via __mro__). In both cases the mro is (DC, object).

Before Python3.10 the __qualname__ attribute was different in dataclass generated reprs, and I could use that. Now in Python3.10 the __qualname__ attribute is identical in both cases.

@henryiii
Copy link

henryiii commented Oct 6, 2021

Have you looked at the standard library implementation for pprint, specifically https://bugs.python.org/issue43080 and https://github.com/python/cpython/pull/24389/files ? That also checks for a custom repr, etc. Other than using "object" as a parameter name 😠, they use dataclasses.is_dataclass(item) to see if something is a dataclass, then they check if __wrapped__ is an attribute of the __repr__, followed by a check for "__create_fn__" in item.__repr__.__wrapped__.__qualname__.

@ptmcg
Copy link

ptmcg commented Oct 6, 2021

Is the reprlib module of any help? Or hindrance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment