Add utility to print source of attrs class.
I love this library. It lets me write classes without writing boilerplate that would take a lot of time. However, I am a very curious person, and I'd like to know what code attrs generated for my class. It can be useful to both debug unexpected behaviour and to get a feel for all the boilerplate attrs handles for me. In the docs there is an example that if I write:
@attrs.define
class SmartClass:
a = attrs.field()
b = attrs.field()
it will roughly be translated into:
class ArtisanalClass:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return f"ArtisanalClass(a={self.a}, b={self.b})"
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.a, self.b) == (other.a, other.b)
else:
return NotImplemented
def __ne__(self, other):
result = self.__eq__(other)
if result is NotImplemented:
return NotImplemented
else:
return not result
def __lt__(self, other):
if other.__class__ is self.__class__:
return (self.a, self.b) < (other.a, other.b)
else:
return NotImplemented
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.a, self.b) <= (other.a, other.b)
else:
return NotImplemented
def __gt__(self, other):
if other.__class__ is self.__class__:
return (self.a, self.b) > (other.a, other.b)
else:
return NotImplemented
def __ge__(self, other):
if other.__class__ is self.__class__:
return (self.a, self.b) >= (other.a, other.b)
else:
return NotImplemented
def __hash__(self):
return hash((self.__class__, self.a, self.b))
First of all, this example is weird since the class name has changed, and also, there are comparison methods despite the fact that order=True wasn't given. Also, __slots__ are missing. Ignoring, these issues it would still be nice to see the code generated by attrs.
I tried to write a simple class:
@attrs.define
class SmartClass:
a: int
b: str = "default"
def __repr__(self) -> str:
return f"<SmartClass(a={self.a})>"
and I tried to inspect its code using inspect.getsource:
import inspect
print(inspect.getsource(SmartClass))
However, I just got the original class definition without any attrs generated methods. The docs show that inspect.getsource can retrieve the generated code for individual methods. However, I would also like to be able to see the entire generated code with a regular class syntax. I think a utility function should be added to return the entire generated source code, so it can be inspected.
TBH I had no idea you can do that!
Given other outstanding issues, it's not something I'm gonna work with priority on, tho, because getting the source into the source cache already is kinda dark magic so this is gonna be hairy.
The inconsistencies in the Why chapter come from the fact that it used to use @attr.s which has different defaults. Thanks for noticing, I'll fix it right away.