Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions ddtrace/contrib/asyncio/compat.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import sys
import asyncio


if hasattr(asyncio, "current_task"):

def asyncio_current_task():
try:
return asyncio.current_task()
except RuntimeError:
return None


# asyncio.Task.current_task method is deprecated and will be removed in Python
# 3.9. Instead use asyncio.current_task
if sys.version_info >= (3, 7, 0):
from asyncio import current_task as asyncio_current_task
else:
import asyncio

asyncio_current_task = asyncio.Task.current_task
def asyncio_current_task():
return asyncio.Task.current_task()
3 changes: 3 additions & 0 deletions releasenotes/notes/py39-5a422b73ba563189.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
prelude: >
Add support for Python 3.9
1 change: 1 addition & 0 deletions riotfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
3.6,
3.7,
3.8,
3.9,
],
pkgs=[("msgpack", [""])],
),
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def get_exts_for(name):
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
],
use_scm_version=True,
setup_requires=["setuptools_scm[toml]>=4", "cython"],
Expand Down
5 changes: 3 additions & 2 deletions tests/contrib/asyncio/test_tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from ddtrace.compat import CONTEXTVARS_IS_AVAILABLE
from ddtrace.contrib.asyncio.compat import asyncio_current_task

from .utils import AsyncioTestCase, mark_asyncio

Expand All @@ -16,7 +17,7 @@ class TestAsyncioTracer(AsyncioTestCase):
def test_get_call_context(self):
# it should return the context attached to the current Task
# or create a new one
task = asyncio.Task.current_task()
task = asyncio_current_task()
ctx = getattr(task, "__datadog_context", None)
assert ctx is None
# get the context from the loop creates a new one that
Expand Down Expand Up @@ -77,7 +78,7 @@ def test_context_task_none(self):
# it should handle the case where a Task is not available
# Note: the @mark_asyncio is missing to simulate an execution
# without a Task
task = asyncio.Task.current_task()
task = asyncio_current_task()
# the task is not available
assert task is None
# but a new Context is still created making the operation safe
Expand Down
4 changes: 3 additions & 1 deletion tests/contrib/asyncio/test_tracer_safety.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio

from ddtrace.provider import DefaultContextProvider
from ddtrace.contrib.asyncio.compat import asyncio_current_task
from .utils import AsyncioTestCase, mark_asyncio


Expand All @@ -22,7 +23,8 @@ def test_get_call_context(self):
ctx = self.tracer.get_call_context()
assert ctx is not None
# test that it behaves the wrong way
task = asyncio.Task.current_task()
task = asyncio_current_task()
assert task
task_ctx = getattr(task, "__datadog_context", None)
assert task_ctx is None

Expand Down
108 changes: 54 additions & 54 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,31 @@ envlist =
wait
{py27,py35,py36,py37,py38,py39}-profile{,-gevent}
{py27,py35,py36,py37,py38,py39}-profile-minreqs{,-gevent}
{py27,py35,py36,py37,py38}-integration
py{27,35,36,37,38}-vendor
{py27,py35,py36,py37,py38}-ddtracerun
{py27,py35,py36,py37,py38}-test_logging
py{27,35,36,37,38,39}-integration
py{27,35,36,37,38,39}-vendor
py{27,35,36,37,38,39}-ddtracerun
py{27,35,36,37,38,39}-test_logging
# Integrations environments
# aiobotocore dropped Python 3.5 support in 0.12
aiobotocore_contrib-{py35}-aiobotocore{02,03,04,05,07,08,09,010,011}
aiobotocore_contrib-{py36}-aiobotocore{02,03,04,05,07,08,09,010,011,012}
# aiobotocore 0.2 and 0.4 do not work because they use async as a reserved keyword
aiobotocore_contrib-py{37,38}-aiobotocore{03,05,07,08,09,010,011,012}
aiobotocore_contrib-py{37,38,39}-aiobotocore{03,05,07,08,09,010,011,012}
# Python 3.7 needs at least aiohttp 2.3
aiohttp_contrib-{py35,py36}-aiohttp{12,13,20,21,22}-aiohttp_jinja{012,013}-yarl
aiohttp_contrib-{py35,py36,py37,py38}-aiohttp23-aiohttp_jinja015-yarl10
aiohttp_contrib-{py35,py36,py37}-aiohttp{30,31,32,33,35,36}-aiohttp_jinja{015}-yarl10
aiohttp_contrib-py38-aiohttp{30,31,32,33,36}-aiohttp_jinja015-yarl10
aiopg_contrib-{py35,py36}-aiopg{012,015}
aiopg_contrib-py{37,38}-aiopg015
algoliasearch_contrib-py{27,35,36,37,38}-algoliasearch{1,2,}
asgi_contrib-{py36,py37,py38}-asgiref{min,}
asyncio_contrib-{py35,py36,py37,py38}
aiopg_contrib-py{37,38,39}-aiopg015
algoliasearch_contrib-py{27,35,36,37,38,39}-algoliasearch{1,2,}
asgi_contrib-py{36,37,38,39}-asgiref{min,}
asyncio_contrib-py{35,36,37,38,39}
# boto needs moto<1 and moto<1 does not support Python >= 3.7
boto_contrib-{py27,py35,py36}-boto
botocore_contrib-{py27,py35,py36,py37,py38}-botocore
bottle_contrib{,_autopatch}-py{27,35,36,37,38}-bottle{11,12,}-webtest
cassandra_contrib-{py27,py35,py36,py37,py38}-cassandra{35,36,37,38,315}
botocore_contrib-py{27,35,36,37,38,39}-botocore
bottle_contrib{,_autopatch}-py{27,35,36,37,38,39}-bottle{11,12,}-webtest
cassandra_contrib-py{27,35,36,37,38,39}-cassandra{35,36,37,38,315}
# Non-4.x celery should be able to use the older redis lib, since it locks to an older kombu
celery_contrib-py{27,35,36}-celery31-redis210
# 4.x celery bumps kombu to 4.4+, which requires redis 3.2 or later, this tests against
Expand All @@ -56,9 +56,9 @@ envlist =
celery_contrib-py{27,35,36}-celery42-redis210-kombu43
# Celery 4.3 wants Kombu >= 4.4 and Redis >= 3.2
# Python 3.7 needs Celery 4.3
celery_contrib-py{27,35,36,37,38}-celery43-redis32-kombu44
consul_contrib-py{27,35,36,37,38}-consul{07,10,11,}
dbapi_contrib-py{27,35,36,37,38}
celery_contrib-py{27,35,36,37,38,39}-celery43-redis32-kombu44
consul_contrib-py{27,35,36,37,38,39}-consul{07,10,11,}
dbapi_contrib-py{27,35,36,37,38,39}
# Django Python version support
# 1.11 2.7, 3.4, 3.5, 3.6, 3.7 (added in 1.11.17)
# 2.0 3.4, 3.5, 3.6, 3.7
Expand All @@ -69,14 +69,14 @@ envlist =
# Source: https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
django_contrib{,_migration}-py{27,35,36}-django{18,111}-djangopylibmc06-djangoredis45-pylibmc-redis{210}-memcached-test_django
django_contrib{,_migration}-py35-django{20,21,22}-djangopylibmc06-djangoredis45-pylibmc-redis{210}-memcached-test_django
django_contrib{,_migration}-py{36,37,38}-django{20,21,22,30,}-djangopylibmc06-djangoredis45-pylibmc-redis{210}-memcached-test_django
django_contrib{,_migration}-py{36,37,38,39}-django{20,21,22,30,}-djangopylibmc06-djangoredis45-pylibmc-redis{210}-memcached-test_django
django_drf_contrib-py{27,35,36}-django{111}-djangorestframework{34,37}-test_django
django_drf_contrib-py35-django{22}-djangorestframework{38,310,}-test_django
django_drf_contrib-py{36,37}-django{22}-djangorestframework{38,310,}-test_django
django_drf_contrib-py{36,37,38}-django30-djangorestframework310-test_django
django_drf_contrib-py{36,37,38}-django-djangorestframework311-test_django
django_drf_contrib-py{36,37,38,39}-django30-djangorestframework310-test_django
django_drf_contrib-py{36,37,38,39}-django-djangorestframework311-test_django
dogpile_contrib-py{27,35}-dogpilecache{06,07,08,09}
dogpile_contrib-py{36,37,38}-dogpilecache{06,07,08,09,10,}
dogpile_contrib-py{36,37,38,39}-dogpilecache{06,07,08,09,10,}
elasticsearch_contrib-{py27,py35,py36}-elasticsearch{16,17,18,23,24,51,52,53,54,63,64}
elasticsearch_contrib-{py27,py35,py36}-elasticsearch1{100}
elasticsearch_contrib-{py27,py35,py36}-elasticsearch2{50}
Expand All @@ -87,10 +87,10 @@ envlist =
flask_contrib{,_autopatch}-{py27,py35,py36}-flask{010,011,012,10}-blinker
# Flask <=0.9 does not support Python 3
flask_contrib{,_autopatch}-{py27}-flask{09}-blinker
flask_cache_contrib-{py27,py35,py36,py37,py38}-flask{010,011,012}-flaskcache{013}-memcached-redis{210}-blinker
flask_cache_contrib-{py27}-flask{010,011}-flaskcache{012}-memcached-redis{210}-blinker
flask_cache_contrib-py{27,35,36,37,38,39}-flask{010,011,012}-flaskcache{013}-memcached-redis{210}-blinker
flask_cache_contrib-py27-flask{010,011}-flaskcache{012}-memcached-redis{210}-blinker
futures_contrib-py27-futures{30,31,32,}
futures_contrib-py{35,36,37,38}
futures_contrib-py{35,36,37,38,39}
gevent_contrib-py27-gevent{11,12,13}-sslmodules
gevent_contrib-py{35,36}-gevent{11,12,13}-sslmodules3-sslmodules
gevent_contrib-py{37,38}-gevent{13,14}-sslmodules3-sslmodules
Expand All @@ -103,56 +103,56 @@ envlist =
grpc_contrib-py{27,35,36}-grpc{112,114,118,120,121,122}-googleapis-common-protos
grpc_contrib-py{37}-grpc{114,118,120,121,122,124,126,128,}-googleapis-common-protos
grpc_contrib-py{38}-grpc{124,126,128,}-googleapis-common-protos
httplib_contrib-py{27,35,36,37,38}
jinja2_contrib-py{27,35,36,37,38}-jinja{27,28,29,210,211,}
httplib_contrib-py{27,35,36,37,38,39}
jinja2_contrib-py{27,35,36,37,38,39}-jinja{27,28,29,210,211,}
kombu_contrib-py{27,35,36}-kombu{40,41,42,43,44,45,46,}
# Kombu >= 4.2 only supports Python 3.7+
kombu_contrib-py{37,38}-kombu{42,43,44,45,46,}
mako_contrib-py{27,35,36,37,38}-mako{010,100,110,}
molten_contrib-py{36,37,38}-molten{06,07,10,}
mongoengine_contrib-py{27,35,36,37,38}-mongoengine{015,016,017,018,}-pymongo
mysql_contrib-py{27,35,36,37,38}-mysqlconnector{80,}
kombu_contrib-py{37,38,39}-kombu{42,43,44,45,46,}
mako_contrib-py{27,35,36,37,38,39}-mako{010,100,110,}
molten_contrib-py{36,37,38,39}-molten{06,07,10,}
mongoengine_contrib-py{27,35,36,37,38,39}-mongoengine{015,016,017,018,}-pymongo
mysql_contrib-py{27,35,36,37,38,39}-mysqlconnector{80,}
mysqldb_contrib-py27-mysqldb{12,}
mysqldb_contrib-py{27,35,36,37,38}-mysqlclient{13,14,}
mysqldb_contrib-py{27,35,36,37,38,39}-mysqlclient{13,14,}
psycopg_contrib-py{27,35,36}-psycopg2{24,25,26,27,28}
psycopg_contrib-py37-psycopg2{27,28}
# psycopg <2.7 doesn't support Python 3.8: https://github.com/psycopg/psycopg2/issues/854
psycopg_contrib-py{38}-psycopg2{28}
pylibmc_contrib-py{27,35,36,37,38}-pylibmc{140,150,}
psycopg_contrib-py{38,39}-psycopg2{28}
pylibmc_contrib-py{27,35,36,37,38,39}-pylibmc{140,150,}
pylons_contrib-py27-pylons{096,097,010,10,}
pymemcache_contrib{,_autopatch}-{py27,py35,py36,py37,py38}-pymemcache{130,140}
pymemcache_contrib{,_autopatch}-py{27,35,36,37,38,39}-pymemcache{130,140}
pymongo_contrib-py{27,35,36,37}-pymongo{30,31,32,33,34,35,36,37,38,39,310,}-mongoengine
# pymongo does not yet support Python 3.8: https://github.com/pymssql/pymssql/issues/586
# but these tests still work.
pymongo_contrib-py38-pymongo{30,31,32,33,35,36,37,38,39,310,}-mongoengine
pymysql_contrib-py{27,35,36,37,38}-pymysql{07,08,09,}
pynamodb_contrib-{py27,py35,py36,py37,py38}-pynamodb{40,41,42,43,}-moto1
pyodbc_contrib-py{27,35,36,37,38}-pyodbc{3,4}
pyramid_contrib{,_autopatch}-py{27,35,36,37,38}-pyramid{17,18,19,110,}-webtest
redis_contrib-py{27,35,36,37,38}-redis{210,30,32,33,34,35,}
rediscluster_contrib-py{27,35,36,37,38}-rediscluster{135,136,200,}-redis210
requests_contrib{,_autopatch}-{py27,py35,py36,py37,py38}-requests{208,209,210,211,212,213,219}
pymongo_contrib-py{38,39}-pymongo{30,31,32,33,35,36,37,38,39,310,}-mongoengine
pymysql_contrib-py{27,35,36,37,38,39}-pymysql{07,08,09,}
pynamodb_contrib-py{27,35,36,37,38,39}-pynamodb{40,41,42,43,}-moto1
pyodbc_contrib-py{27,35,36,37,38,39}-pyodbc{3,4}
pyramid_contrib{,_autopatch}-py{27,35,36,37,38,39}-pyramid{17,18,19,110,}-webtest
redis_contrib-py{27,35,36,37,38,39}-redis{210,30,32,33,34,35,}
rediscluster_contrib-py{27,35,36,37,38,39}-rediscluster{135,136,200,}-redis210
requests_contrib{,_autopatch}-py{27,35,36,37,38,39}-requests{208,209,210,211,212,213,219}
# python 3.6 requests + gevent regression test
# DEV: This is a known issue for gevent 1.1, suggestion is to upgrade to gevent > 1.2
# https://github.com/gevent/gevent/issues/903
requests_gevent_contrib-{py36}-requests{208,209,210,211,212,213,219}-gevent{12,13}
requests_gevent_contrib-py{37,38}-requests{208,209,210,211,212,213,219}-gevent13
sanic_contrib-py{36,37,38}-sanic{1906,1909,1912,2003,2006}
sqlalchemy_contrib-py{27,35,36,37,38}-sqlalchemy{10,11,12,13,}-psycopg228-mysqlconnector
sqlite3_contrib-{py27,py35,py36,py37,py38}-sqlite3
starlette_contrib-{py36,py37,py38}-starlette{13,}
tornado_contrib-py{27,35,36,37,38}-tornado{44,45}
tornado_contrib-py{37,38}-tornado{50,51,60,}
sanic_contrib-py{36,37,38,39}-sanic{1906,1909,1912,2003,2006}
sqlalchemy_contrib-py{27,35,36,37,38,39}-sqlalchemy{10,11,12,13,}-psycopg228-mysqlconnector
sqlite3_contrib-py{27,35,36,37,38,39}-sqlite3
starlette_contrib-py{36,37,38,39}-starlette{13,}
tornado_contrib-py{27,35,36,37,38,39}-tornado{44,45}
tornado_contrib-py{37,38,39}-tornado{50,51,60,}
tornado_contrib-py27-tornado{44,45}-futures{30,31,32,}
vertica_contrib-{py27,py35,py36,py37,py38}-vertica{060,070}
vertica_contrib-py{27,35,36,37,38,39}-vertica{060,070}
# Opentracer
{py27,py35,py36,py37,py38}-opentracer
{py35,py36,py37,py38}-opentracer_asyncio
py{35,36,37,38}-opentracer_tornado-tornado{44,45,50,60,}
{py27}-opentracer_gevent-gevent{10}
{py27,py35,py36}-opentracer_gevent-gevent{11,12}
py{27,35,36,37,38,39}-opentracer
py{35,36,37,38}-opentracer_asyncio
py{35,36,37,38,39}-opentracer_tornado-tornado{44,45,50,60,}
py27-opentracer_gevent-gevent{10}
py{27,35,36}-opentracer_gevent-gevent{11,12}
py{37,38}-opentracer_gevent-gevent{13,14}
benchmarks-{py27,py35,py36,py37,py38}
benchmarks-py{27,35,36,37,38,39}

isolated_build = true

Expand Down