I had an interesting problem this morning. I had a base class that looked like this:
# base.py
class Base(object):
@classmethod
def exists(cls, **kwargs):
# do some work
pass
And a decorator module that looked like this:
# caching.py
# actual caching decorator
def cached(ttl):
# complicated
def cached_model(ttl=300):
def closure(model_class):
# ...
# eventually:
exists_decorator = cached(ttl=ttl)
model_class.exists = exists_decorator(model_class.exists))
return model_class
return closure
Here's my subclass model:
@cached_model(ttl=300)
class Model(Base):
pass
Thing is, when I actually call Model.exists, I get complaints about the wrong number of arguments! Inspecting the arguments in the decorator shows nothing weird going on - the arguments are exactly what I expect, and they match up with the method signature. How can I add further decorators to a method that's already decorated with classmethod
?
Not all models are cached, but the exists() method is present on every model as a classmethod, so re-ordering the decorators isn't an option: cached_model
can add classmethod to exists(), but then what makes exists() a classmethod on uncached models?