-
Notifications
You must be signed in to change notification settings - Fork 3
Description
TL;DR: We should probably support either @primary as the outer decorator and/or add a @primary.classmethod variant.
There's two ways this could compose with the staticmethod / classmethod decorator, and they have different failure modes:
class DivisionBase:
@classmethod
@primary
def divide(cls, x, y):
return x / y
@divide.variant('round')
def divide(cls, x, y):
return round(x / y)@classmethod as outer decorator fails because divide becomes a classmethod, not a VariantFunction, and doesn't have its fancy variant decorator anymore:
----> 7 @divide.variant('round')
8 def divide(cls, x, y):
9 return round(x / y)
AttributeError: 'classmethod' object has no attribute 'variant'
I think there's no obvious way around that. The other way is with primary as the outer decorator:
class DivisionBase:
@primary
@classmethod
def divide(cls, x, y):
return x / y
@divide.variant('round')
def divide(cls, x, y):
return round(x / y)This one will succeed, but the way it's implemented now I think it's being called incorrectly:
In [12]: DivisionBase.divide(3, 4)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-38b40b30b265> in <module>()
----> 1 DivisionBase.divide(3, 4)
37
38 def __call__(self, *args, **kwargs):
---> 39 return self.__main_form__(*args, **kwargs)
40
41 def _add_variant(self, var_name, vfunc):
TypeError: 'classmethod' object is not callable
I think that this one we can get working, it's just a matter of playing with it in the descriptor or something. Alternatively, we can specifically support a classmethod and staticmethod variant for the @primary and @x.variant variants. The disadvantage to both of these is that it's counter-intuitive for the order of decorators to matter like this, so no matter what happens we'll probably get questions.