Search code examples
pythonpython-attrs

stacking attrs attributes decorators


I am trying to reuse the validator function for two attributes. I know I can create the function outside and refer it in the validator, but would it be technically correct to stack the decorators like that:

In [6]: @attr.s 
   ...: class A: 
   ...:     a = attr.ib() 
   ...:     b = attr.ib() 
   ...:      
   ...:     @a.validator 
   ...:     @b.validator 
   ...:     def a_b_check(self, attribute, value): 
   ...:         assert value == 5 
   ...:                                                                                                                 

In [7]: A(5,5)                                                                                                          
Out[7]: A(a=5, b=5)

In [8]: A(5,6)                                                                                                          
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-8-ec475f254e70> in <module>
----> 1 A(5,6)

<attrs generated init 71300c05faf88cf49c2dcea04f8137146d4dac79> in __init__(self, a, b)
      4     if _config._run_validators is True:
      5         __attr_validator_a(self, __attr_a, self.a)
----> 6         __attr_validator_b(self, __attr_b, self.b)

<ipython-input-6-701125903dd2> in a_b_check(self, attribute, value)
      7     @b.validator
      8     def a_b_check(self, attribute, value):
----> 9         assert value == 5
     10 

AssertionError: 

In [9]: A(6,5)                                                                                                          
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-9-4582d95e8377> in <module>
----> 1 A(6,5)

<attrs generated init 71300c05faf88cf49c2dcea04f8137146d4dac79> in __init__(self, a, b)
      3     self.b = b
      4     if _config._run_validators is True:
----> 5         __attr_validator_a(self, __attr_a, self.a)
      6         __attr_validator_b(self, __attr_b, self.b)

<ipython-input-6-701125903dd2> in a_b_check(self, attribute, value)
      7     @b.validator
      8     def a_b_check(self, attribute, value):
----> 9         assert value == 5
     10 

AssertionError: 

The test shows that the validation works well, but not sure if something wrong happened under the hood.


Solution

  • I would expect it to work just fine, because the @-notation of validators doesn't change the method at all and just memorizes it.

    If you want to re-use validators, I'd suggest to use functions that are more versatile and work across class too.