attrs icon indicating copy to clipboard operation
attrs copied to clipboard

AttributeError propagation is broken in cached_property with slots=True

Open n-splv opened this issue 1 year ago • 3 comments

Let's start with a regular class:

class A:

    @cached_property
    def x(self):
        return self.y

    @property
    def y(self):
        raise AttributeError("Message")
        
a = A()
print(a.x)  # AttributeError: Message

Just as expected. Now let's use attrs with __dict__:

@define(slots=False)
class A:
    ...

print(a.x)  # AttributeError: Message

So far so good. But:

@define  # slots=True by default
class A:
    ...

print(a.x)  # AttributeError: 'A' object has no attribute 'y'

This made me spend quite some time wondering where did my attribute go :)

n-splv avatar Jan 31 '24 09:01 n-splv

I'm a little confused about what's going on here – are we somehow rewriting AttributErrors?

ping @diabolo-dan 😇

hynek avatar Jan 31 '24 10:01 hynek

Yeah, as I recall there's some rewriting there to avoid a confusing __getattr__ attribute error.

I think there's a try/except that could be rewritten as an if hasatr, which would probably resolve this. There are some performance implications to the change, but it's probably a reasonable tradeoff for optimising the more common case.

I won't be able to look at it this week, as I'm on holiday, but might be able to take a look when I'm back next week.

diabolo-dan avatar Jan 31 '24 14:01 diabolo-dan

Thanks, and enjoy your holiday!

hynek avatar Jan 31 '24 14:01 hynek