I have some base class like:
class Auto(object):
_year = None
_base_price = None
@classmethod
def calculate_price(cls):
return cls._base_price + 5000 * (2016 - cls._year)
class BMW(Auto):
_year = 2015
_base_price = 40000
@celery.task(filter=task_method,
name='queue_name',
base=basetask(), bind=True)
def calculate_price(self):
super(BMW, self).calculate_price()
So, my problem is with the last line of code, it raises:
TypeError: super(type, obj): obj must be an instance or subtype of type
I was trying to remove bind=True and play a little with it, but with no results. Any ideas how to fix this issue?
UPDATE: where
celery = Celery(...)
so, I'm using decorator like app.task
You are mixing two styles of methods: Class methods (
@classmethod), and instance methods (def calculate_price(self):).I haven't really tried this in code, but what about:
So the
@classmethoddecorator is applied first todef calculate_price(...):, and then the@celery.taskis applied to the class method.If you do need
calculate_price()to be an instance method, then the signature could bedef calculate_price(self, task_self):but you need to apply the decorator when you already have an instance, like:When you access a method using
instance<dot>methodyou don't get the function you wrote, you get a method descriptor that when called, it will take care of fill out the first argument (self) leaving to you filling the remaining arguments. In this case, is only thetask_selfargument, and the@celery.taskdecorator will take care of that one.In any case, I think you should step back, and rethink your problem in a more generic way instead of figuring out how to tie class/instance methods to Celery. In general, Celery tasks should be just functions living in a module inside your application, which accept parameters that can be easily serialized using JSON.