Skip to content

Make this work with staticmethods / classmethods #1

@pganssle

Description

@pganssle

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions