How do you use Sentry?
Sentry Saas (sentry.io)
Version
2.60.0 (and 1.x)
Steps to Reproduce
import inspect
from celery import Celery
from celery.app.task import Task
import sentry_sdk
from sentry_sdk.integrations.celery import CeleryIntegration
sentry_sdk.init(integrations=[CeleryIntegration()])
app = Celery("repro")
@app.task
def add(x, y):
return x + y
print(inspect.getcallargs(Task.apply_async, None, (1, 2), {}))
Expected Result
Args bind to self, args, kwargs, ... matching the real apply_async signature.
Actual Result
{'args': (None, (1, 2), {}), 'kwargs': {}}
_wrap_task_run replaces apply_async with a wrapper declared def apply_async(*args, **kwargs). functools.wraps sets __wrapped__, so inspect.signature follows through and is fine, but inspect.getcallargs and mock.patch(autospec=True) read the wrapper's own __code__ and see the bare signature.
Same root cause as #3177; fixed there in #3178 by setting __signature__ on the wrapper. The same fix would apply to _wrap_task_run.
How do you use Sentry?
Sentry Saas (sentry.io)
Version
2.60.0 (and 1.x)
Steps to Reproduce
Expected Result
Args bind to
self,args,kwargs, ... matching the realapply_asyncsignature.Actual Result
_wrap_task_runreplacesapply_asyncwith a wrapper declareddef apply_async(*args, **kwargs).functools.wrapssets__wrapped__, soinspect.signaturefollows through and is fine, butinspect.getcallargsandmock.patch(autospec=True)read the wrapper's own__code__and see the bare signature.Same root cause as #3177; fixed there in #3178 by setting
__signature__on the wrapper. The same fix would apply to_wrap_task_run.