def lazyproperty(fn):
    @property
    def _lazyproperty(self):
        attr = "_" + fn.__name__
        if not hasattr(self, attr):
            setattr(self, attr, fn(self))
        return getattr(self, attr)

    return _lazyproperty

from functools import wraps

def lazyproperty(fn):
    @property
    @wraps(fn)
    def _lazyproperty(self):
        attr = "_" + fn.__name__
        if not hasattr(self, attr):
            setattr(self, attr, fn(self))
        return getattr(self, attr)

    return _lazyproperty

Fix lazyproperty decorator to preserve property attribute
Fix lazyproperty decorator to preserve property attribute

+ from functools import wraps
+ 
  def lazyproperty(fn):
      @property
+     @wraps(fn)
      def _lazyproperty(self):
          attr = "_" + fn.__name__
          if not hasattr(self, attr):
              setattr(self, attr, fn(self))
          return getattr(self, attr)
  
      return _lazyproperty
  
Fix lazyproperty decorator to preserve property attribute
## Code Before:
def lazyproperty(fn):
    @property
    def _lazyproperty(self):
        attr = "_" + fn.__name__
        if not hasattr(self, attr):
            setattr(self, attr, fn(self))
        return getattr(self, attr)

    return _lazyproperty

## Instruction:
Fix lazyproperty decorator to preserve property attribute
## Code After:
from functools import wraps

def lazyproperty(fn):
    @property
    @wraps(fn)
    def _lazyproperty(self):
        attr = "_" + fn.__name__
        if not hasattr(self, attr):
            setattr(self, attr, fn(self))
        return getattr(self, attr)

    return _lazyproperty
