- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 407
 
Description
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.