Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorator API with auto_attribs=True doesn't work. #466

Closed
ckutlu opened this issue Nov 16, 2018 · 5 comments
Closed

Decorator API with auto_attribs=True doesn't work. #466

ckutlu opened this issue Nov 16, 2018 · 5 comments

Comments

@ckutlu
Copy link
Contributor

ckutlu commented Nov 16, 2018

When I try to use attribute decorators via auto attributes style, I get an error saying that the name doesn't exist. This doesn't happen if I initiate attributes with attr.ib(). Is this expected behavior?

Here is an example that fails:

@attr.s(auto_attribs=True)
class A:
    x: float

    @x.validator
    def _check_x(self, attrib, value):
        print("Validator called.")
        print(self, attrib, value)
a = A(5)

gives

Traceback (most recent call last):
  File "test.py", line 5, in first
    @attr.s(auto_attribs=True)
  File "test.py", line 9, in A
    @x.validator
NameError: name 'x' is not defined
@hynek
Copy link
Member

hynek commented Nov 16, 2018

Yes, unfortunately this is to be expected. There is no way for us to cheat x into the class namespace. It's just type declared but doesn't exist until @attr.s runs over it.

This should be documented in http://www.attrs.org/en/stable/types.html

@ckutlu
Copy link
Contributor Author

ckutlu commented Nov 16, 2018

I understand, thanks for the prompt response. That's a bummer, but I guess using attr.ib() for only attributes with validators isn't that much of an ugly workaround.

@AndydeCleyre
Copy link

This should be mentioned in the Validators section of the examples page, and in my opinion the existing notice in the Validators section of the init page is insufficiently clear, and should explicitly mention that it won't work when using the @attrs(auto_attribs=True... decorator.

@jimcushing-natgeo
Copy link

It might help to note that this still works:

@attr.s(auto_attribs=True)
class A:
    x: float = attr.ib()

So you still can use type annotations, validators, and auto_attribs.

@alexchandel
Copy link

attrs should provide a workaround for this. Like

@attr.s(auto_attribs=True)
class A:
    x: float

    @attr.validator
    def _check_x(self, attrib, value):
        print("Validator x called.")
        print(self, attrib, value)

    y: float
    z: float

    @attr.validator_for('y')
    def _check_y(self, attrib, value):
        print("Validator y called.")
        print(self, attrib, value)


a = A(5, 6, 7)

I think the first case requires python >= 3.7 dicts remembering order insertion.

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

No branches or pull requests

5 participants