diff --git a/.riot/requirements/164da27.txt b/.riot/requirements/164da27.txt new file mode 100644 index 00000000000..25c25b2695f --- /dev/null +++ b/.riot/requirements/164da27.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --no-annotate --resolver=backtracking .riot/requirements/164da27.in +# +amqp==5.2.0 +attrs==23.1.0 +billiard==4.2.0 +celery==5.3.4 +click==8.1.7 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 +coverage[toml]==7.3.2 +hypothesis==6.45.0 +iniconfig==2.0.0 +kombu==5.3.3 +mock==5.1.0 +more-itertools==8.10.0 +opentracing==2.4.0 +packaging==23.2 +pluggy==1.3.0 +prompt-toolkit==3.0.39 +pytest==7.4.3 +pytest-cov==4.1.0 +pytest-mock==3.12.0 +python-dateutil==2.8.2 +redis==3.5.3 +six==1.16.0 +sortedcontainers==2.4.0 +tzdata==2023.3 +vine==5.1.0 +wcwidth==0.2.9 diff --git a/.riot/requirements/23133eb.txt b/.riot/requirements/23133eb.txt index b811d0fcc33..e12998b7c65 100644 --- a/.riot/requirements/23133eb.txt +++ b/.riot/requirements/23133eb.txt @@ -5,31 +5,30 @@ # pip-compile --no-annotate --resolver=backtracking .riot/requirements/23133eb.in # amqp==5.1.1 -attrs==22.2.0 -billiard==3.6.4.0 -celery==5.2.7 -click==8.1.3 +attrs==23.1.0 +billiard==4.1.0 +celery==5.3.1 +click==8.1.5 click-didyoumean==0.3.0 click-plugins==1.1.1 -click-repl==0.2.0 -coverage[toml]==7.2.2 -exceptiongroup==1.1.1 +click-repl==0.3.0 +coverage[toml]==7.2.7 hypothesis==6.45.0 iniconfig==2.0.0 -kombu==5.2.4 -mock==5.0.1 +kombu==5.3.1 +mock==5.1.0 more-itertools==8.10.0 opentracing==2.4.0 -packaging==23.0 -pluggy==1.0.0 -prompt-toolkit==3.0.38 -pytest==7.2.2 -pytest-cov==4.0.0 -pytest-mock==3.10.0 -pytz==2022.7.1 +packaging==23.1 +pluggy==1.2.0 +prompt-toolkit==3.0.39 +pytest==7.4.0 +pytest-cov==4.1.0 +pytest-mock==3.11.1 +python-dateutil==2.8.2 redis==3.5.3 six==1.16.0 sortedcontainers==2.4.0 -tomli==2.0.1 +tzdata==2023.3 vine==5.0.0 wcwidth==0.2.6 diff --git a/.riot/requirements/2b4f039.txt b/.riot/requirements/2b4f039.txt new file mode 100644 index 00000000000..f787eebbf13 --- /dev/null +++ b/.riot/requirements/2b4f039.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --no-annotate .riot/requirements/2b4f039.in +# +amqp==5.2.0 +attrs==23.1.0 +billiard==4.2.0 +celery==5.3.4 +click==8.1.7 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 +coverage[toml]==7.3.2 +hypothesis==6.45.0 +iniconfig==2.0.0 +kombu==5.3.3 +mock==5.1.0 +more-itertools==8.10.0 +opentracing==2.4.0 +packaging==23.2 +pluggy==1.3.0 +prompt-toolkit==3.0.39 +pytest==7.4.3 +pytest-cov==4.1.0 +pytest-mock==3.12.0 +python-dateutil==2.8.2 +redis==3.5.3 +six==1.16.0 +sortedcontainers==2.4.0 +tzdata==2023.3 +vine==5.1.0 +wcwidth==0.2.9 diff --git a/.riot/requirements/b70a077.txt b/.riot/requirements/b70a077.txt new file mode 100644 index 00000000000..d87d46d8df9 --- /dev/null +++ b/.riot/requirements/b70a077.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --no-annotate --resolver=backtracking .riot/requirements/b70a077.in +# +amqp==5.1.1 +attrs==23.1.0 +billiard==4.1.0 +celery==5.3.1 +click==8.1.5 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 +coverage[toml]==7.2.7 +hypothesis==6.45.0 +iniconfig==2.0.0 +kombu==5.3.1 +mock==5.1.0 +more-itertools==8.10.0 +opentracing==2.4.0 +packaging==23.1 +pluggy==1.2.0 +prompt-toolkit==3.0.39 +pytest==7.4.0 +pytest-cov==4.1.0 +pytest-mock==3.11.1 +python-dateutil==2.8.2 +redis==3.5.3 +six==1.16.0 +sortedcontainers==2.4.0 +tzdata==2023.3 +vine==5.0.0 +wcwidth==0.2.6 diff --git a/ddtrace/contrib/celery/signals.py b/ddtrace/contrib/celery/signals.py index fe29f7bc4e0..e16f5ecace9 100644 --- a/ddtrace/contrib/celery/signals.py +++ b/ddtrace/contrib/celery/signals.py @@ -189,8 +189,16 @@ def trace_failure(*args, **kwargs): ex = kwargs.get("einfo") if ex is None: return - if hasattr(task, "throws") and isinstance(ex.exception, task.throws): - return + + if hasattr(task, "throws"): + original_exception = ex.exception + if hasattr(original_exception, "exc"): + # Python 3.11+ support: The original exception is wrapped in an `exc` attribute + original_exception = original_exception.exc + + if isinstance(original_exception, task.throws): + return + span.set_exc_info(ex.type, ex.exception, ex.tb) diff --git a/releasenotes/notes/support-3-11-celery-39053a6ccb7de942.yaml b/releasenotes/notes/support-3-11-celery-39053a6ccb7de942.yaml new file mode 100644 index 00000000000..53b630d21ba --- /dev/null +++ b/releasenotes/notes/support-3-11-celery-39053a6ccb7de942.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + celery: Adds Python 3.11 and 3.12 support for the celery integration. diff --git a/riotfile.py b/riotfile.py index 5881457b9bf..1cc6e72878a 100644 --- a/riotfile.py +++ b/riotfile.py @@ -560,10 +560,7 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION): }, ), Venv( - # celery added support for Python 3.10 in 5.2, no official support for 3.11 yet - # Billiard dependency is incompatible with Python 3.11 - # https://github.com/celery/billiard/issues/377 - pys="3.10", + pys=select_pys(min_version="3.10"), env={ # https://docs.celeryproject.org/en/v5.0.5/userguide/testing.html#enabling "PYTEST_PLUGINS": "celery.contrib.pytest", diff --git a/tests/contrib/celery/test_integration.py b/tests/contrib/celery/test_integration.py index 727e8c655f9..855479e5109 100644 --- a/tests/contrib/celery/test_integration.py +++ b/tests/contrib/celery/test_integration.py @@ -277,7 +277,7 @@ def fn_exception(): assert span.error == 1 assert span.get_tag("component") == "celery" assert span.get_tag("span.kind") == "consumer" - assert span.get_tag(ERROR_MSG) == "Task class is failing" + assert "Task class is failing" in span.get_tag(ERROR_MSG) assert "Traceback (most recent call last)" in span.get_tag("error.stack") assert "Task class is failing" in span.get_tag("error.stack") @@ -400,7 +400,7 @@ def run(self): assert span.get_tag("celery.state") == "FAILURE" assert span.error == 1 assert span.get_tag("component") == "celery" - assert span.get_tag(ERROR_MSG) == "Task class is failing" + assert "Task class is failing" in span.get_tag(ERROR_MSG) assert "Traceback (most recent call last)" in span.get_tag("error.stack") assert "Task class is failing" in span.get_tag("error.stack") assert span.get_tag("span.kind") == "consumer"