diff --git a/.riot/requirements/106dceb.txt b/.riot/requirements/106dceb.txt new file mode 100644 index 00000000000..dac65db0bad --- /dev/null +++ b/.riot/requirements/106dceb.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/106dceb.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +wrapt==1.17.3 +zope-event==6.0 +zope-interface==8.0.1 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/1cf83ae.txt b/.riot/requirements/12ac950.txt similarity index 86% rename from .riot/requirements/1cf83ae.txt rename to .riot/requirements/12ac950.txt index d03f9ffadf2..657a81fdb5c 100644 --- a/.riot/requirements/1cf83ae.txt +++ b/.riot/requirements/12ac950.txt @@ -2,21 +2,21 @@ # This file is autogenerated by pip-compile with Python 3.13 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1cf83ae.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/12ac950.in # -attrs==25.3.0 -coverage[toml]==7.10.6 +attrs==25.4.0 +coverage[toml]==7.11.0 gevent==25.9.1 greenlet==3.2.4 httpretty==1.1.4 hypothesis==6.45.0 -iniconfig==2.1.0 +iniconfig==2.3.0 mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 py-cpuinfo==9.0.0 -pyfakefs==5.9.3 +pyfakefs==5.10.0 pygments==2.19.2 pytest==8.4.2 pytest-asyncio==0.23.8 @@ -26,6 +26,7 @@ pytest-mock==3.15.1 pytest-randomly==4.0.1 python-json-logger==2.0.7 sortedcontainers==2.4.0 +wrapt==2.0.0 zope-event==5.0 zope-interface==7.2 diff --git a/.riot/requirements/188dfd0.txt b/.riot/requirements/188dfd0.txt new file mode 100644 index 00000000000..54cdaa41068 --- /dev/null +++ b/.riot/requirements/188dfd0.txt @@ -0,0 +1,39 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/188dfd0.in +# +attrs==25.4.0 +coverage[toml]==7.10.7 +exceptiongroup==1.3.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +importlib-metadata==8.7.0 +iniconfig==2.1.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +tomli==2.3.0 +typing-extensions==4.15.0 +wrapt==1.17.3 +zipp==3.23.0 +zope-event==6.0 +zope-interface==8.0.1 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/1ae8364.txt b/.riot/requirements/1aa6774.txt similarity index 50% rename from .riot/requirements/1ae8364.txt rename to .riot/requirements/1aa6774.txt index d4fa9e46087..863c7eab304 100644 --- a/.riot/requirements/1ae8364.txt +++ b/.riot/requirements/1aa6774.txt @@ -2,13 +2,13 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --no-annotate .riot/requirements/1ae8364.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1aa6774.in # -attrs==25.3.0 -coverage[toml]==7.8.0 -exceptiongroup==1.2.2 -gevent==25.4.2 -greenlet==3.2.1 +attrs==25.4.0 +coverage[toml]==7.10.7 +exceptiongroup==1.3.0 +gevent==25.9.1 +greenlet==3.2.4 httpretty==1.1.4 hypothesis==6.45.0 importlib-metadata==8.7.0 @@ -16,21 +16,24 @@ iniconfig==2.1.0 mock==5.2.0 opentracing==2.4.0 packaging==25.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 -pyfakefs==5.8.0 -pytest==8.3.5 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 pytest-asyncio==0.23.8 pytest-benchmark==5.1.0 -pytest-cov==6.1.1 -pytest-mock==3.14.0 -pytest-randomly==3.16.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 python-json-logger==2.0.7 sortedcontainers==2.4.0 -tomli==2.2.1 -zipp==3.21.0 -zope-event==5.0 -zope-interface==7.2 +tomli==2.3.0 +typing-extensions==4.15.0 +wrapt==2.0.0 +zipp==3.23.0 +zope-event==6.0 +zope-interface==8.0.1 # The following packages are considered to be unsafe in a requirements file: -# setuptools +setuptools==80.9.0 diff --git a/.riot/requirements/1ae87da.txt b/.riot/requirements/1b6e144.txt similarity index 86% rename from .riot/requirements/1ae87da.txt rename to .riot/requirements/1b6e144.txt index 61ea39cf697..d5441dae5d0 100644 --- a/.riot/requirements/1ae87da.txt +++ b/.riot/requirements/1b6e144.txt @@ -2,21 +2,21 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/1ae87da.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1b6e144.in # -attrs==25.3.0 -coverage[toml]==7.10.6 +attrs==25.4.0 +coverage[toml]==7.11.0 gevent==25.9.1 greenlet==3.2.4 httpretty==1.1.4 hypothesis==6.45.0 -iniconfig==2.1.0 +iniconfig==2.3.0 mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 py-cpuinfo==9.0.0 -pyfakefs==5.9.3 +pyfakefs==5.10.0 pygments==2.19.2 pytest==8.4.2 pytest-asyncio==0.23.8 @@ -26,6 +26,7 @@ pytest-mock==3.15.1 pytest-randomly==4.0.1 python-json-logger==2.0.7 sortedcontainers==2.4.0 +wrapt==2.0.0 zope-event==5.0 zope-interface==7.2 diff --git a/.riot/requirements/1f9c58a.txt b/.riot/requirements/1f9c58a.txt new file mode 100644 index 00000000000..141f6723214 --- /dev/null +++ b/.riot/requirements/1f9c58a.txt @@ -0,0 +1,38 @@ +# +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/1f9c58a.in +# +attrs==25.3.0 +coverage[toml]==7.6.1 +exceptiongroup==1.3.0 +gevent==24.2.1 +greenlet==3.1.1 +httpretty==1.1.4 +hypothesis==6.45.0 +importlib-metadata==8.5.0 +iniconfig==2.1.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.5.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pytest==8.3.5 +pytest-asyncio==0.23.8 +pytest-benchmark==4.0.0 +pytest-cov==5.0.0 +pytest-mock==3.14.1 +pytest-randomly==3.15.0 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +tomli==2.3.0 +typing-extensions==4.13.2 +wrapt==1.17.3 +zipp==3.20.2 +zope-event==5.0 +zope-interface==7.2 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==75.3.2 diff --git a/.riot/requirements/2b85fce.txt b/.riot/requirements/2b85fce.txt deleted file mode 100644 index 7477453f20c..00000000000 --- a/.riot/requirements/2b85fce.txt +++ /dev/null @@ -1,34 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile --no-annotate .riot/requirements/2b85fce.in -# -attrs==25.3.0 -coverage[toml]==7.8.0 -exceptiongroup==1.2.2 -gevent==25.4.2 -greenlet==3.2.1 -httpretty==1.1.4 -hypothesis==6.45.0 -iniconfig==2.1.0 -mock==5.2.0 -opentracing==2.4.0 -packaging==25.0 -pluggy==1.5.0 -py-cpuinfo==9.0.0 -pyfakefs==5.8.0 -pytest==8.3.5 -pytest-asyncio==0.23.8 -pytest-benchmark==5.1.0 -pytest-cov==6.1.1 -pytest-mock==3.14.0 -pytest-randomly==3.16.0 -python-json-logger==2.0.7 -sortedcontainers==2.4.0 -tomli==2.2.1 -zope-event==5.0 -zope-interface==7.2 - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/.riot/requirements/319942e.txt b/.riot/requirements/319942e.txt new file mode 100644 index 00000000000..3773278175a --- /dev/null +++ b/.riot/requirements/319942e.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/319942e.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +wrapt==1.17.3 +zope-event==5.0 +zope-interface==7.2 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/4de151d.txt b/.riot/requirements/4de151d.txt new file mode 100644 index 00000000000..67fb00c6d97 --- /dev/null +++ b/.riot/requirements/4de151d.txt @@ -0,0 +1,37 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/4de151d.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +exceptiongroup==1.3.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +tomli==2.3.0 +typing-extensions==4.15.0 +wrapt==2.0.0 +zope-event==6.0 +zope-interface==8.0.1 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/84112c9.txt b/.riot/requirements/57b4529.txt similarity index 51% rename from .riot/requirements/84112c9.txt rename to .riot/requirements/57b4529.txt index 5160f9a2be4..af1c02e5bd6 100644 --- a/.riot/requirements/84112c9.txt +++ b/.riot/requirements/57b4529.txt @@ -2,31 +2,33 @@ # This file is autogenerated by pip-compile with Python 3.11 # by the following command: # -# pip-compile --no-annotate .riot/requirements/84112c9.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/57b4529.in # -attrs==25.3.0 -coverage[toml]==7.8.0 -gevent==25.4.2 -greenlet==3.2.1 +attrs==25.4.0 +coverage[toml]==7.11.0 +gevent==25.9.1 +greenlet==3.2.4 httpretty==1.1.4 hypothesis==6.45.0 -iniconfig==2.1.0 +iniconfig==2.3.0 mock==5.2.0 opentracing==2.4.0 packaging==25.0 -pluggy==1.5.0 +pluggy==1.6.0 py-cpuinfo==9.0.0 -pyfakefs==5.8.0 -pytest==8.3.5 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 pytest-asyncio==0.23.8 pytest-benchmark==5.1.0 -pytest-cov==6.1.1 -pytest-mock==3.14.0 -pytest-randomly==3.16.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 python-json-logger==2.0.7 sortedcontainers==2.4.0 -zope-event==5.0 -zope-interface==7.2 +wrapt==2.0.0 +zope-event==6.0 +zope-interface==8.0.1 # The following packages are considered to be unsafe in a requirements file: -# setuptools +setuptools==80.9.0 diff --git a/.riot/requirements/5d37fda.txt b/.riot/requirements/5d37fda.txt new file mode 100644 index 00000000000..a84e7c71ad8 --- /dev/null +++ b/.riot/requirements/5d37fda.txt @@ -0,0 +1,37 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/5d37fda.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +exceptiongroup==1.3.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +tomli==2.3.0 +typing-extensions==4.15.0 +wrapt==1.17.3 +zope-event==6.0 +zope-interface==8.0.1 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/7581061.txt b/.riot/requirements/7581061.txt new file mode 100644 index 00000000000..51d7c23076e --- /dev/null +++ b/.riot/requirements/7581061.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/7581061.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +wrapt==1.17.3 +zope-event==5.0 +zope-interface==7.2 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/ed1ebcd.txt b/.riot/requirements/8733595.txt similarity index 74% rename from .riot/requirements/ed1ebcd.txt rename to .riot/requirements/8733595.txt index 09987eccaf9..e921c950132 100644 --- a/.riot/requirements/ed1ebcd.txt +++ b/.riot/requirements/8733595.txt @@ -2,11 +2,11 @@ # This file is autogenerated by pip-compile with Python 3.8 # by the following command: # -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/ed1ebcd.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/8733595.in # attrs==25.3.0 coverage[toml]==7.6.1 -exceptiongroup==1.2.2 +exceptiongroup==1.3.0 gevent==24.2.1 greenlet==3.1.1 httpretty==1.1.4 @@ -18,19 +18,21 @@ opentracing==2.4.0 packaging==25.0 pluggy==1.5.0 py-cpuinfo==9.0.0 -pyfakefs==5.8.0 +pyfakefs==5.10.0 pytest==8.3.5 pytest-asyncio==0.23.8 pytest-benchmark==4.0.0 pytest-cov==5.0.0 -pytest-mock==3.14.0 +pytest-mock==3.14.1 pytest-randomly==3.15.0 python-json-logger==2.0.7 sortedcontainers==2.4.0 -tomli==2.2.1 +tomli==2.3.0 +typing-extensions==4.13.2 +wrapt==2.0.0 zipp==3.20.2 zope-event==5.0 zope-interface==7.2 # The following packages are considered to be unsafe in a requirements file: -# setuptools +setuptools==75.3.2 diff --git a/.riot/requirements/a0466a2.txt b/.riot/requirements/a0466a2.txt new file mode 100644 index 00000000000..8b7f029b741 --- /dev/null +++ b/.riot/requirements/a0466a2.txt @@ -0,0 +1,34 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/a0466a2.in +# +attrs==25.4.0 +coverage[toml]==7.11.0 +gevent==25.9.1 +greenlet==3.2.4 +httpretty==1.1.4 +hypothesis==6.45.0 +iniconfig==2.3.0 +mock==5.2.0 +opentracing==2.4.0 +packaging==25.0 +pluggy==1.6.0 +py-cpuinfo==9.0.0 +pyfakefs==5.10.0 +pygments==2.19.2 +pytest==8.4.2 +pytest-asyncio==0.23.8 +pytest-benchmark==5.1.0 +pytest-cov==7.0.0 +pytest-mock==3.15.1 +pytest-randomly==4.0.1 +python-json-logger==2.0.7 +sortedcontainers==2.4.0 +wrapt==1.17.3 +zope-event==5.0 +zope-interface==7.2 + +# The following packages are considered to be unsafe in a requirements file: +setuptools==80.9.0 diff --git a/.riot/requirements/499f4fa.txt b/.riot/requirements/cccee00.txt similarity index 86% rename from .riot/requirements/499f4fa.txt rename to .riot/requirements/cccee00.txt index a6d29e55d2b..e7a82c76881 100644 --- a/.riot/requirements/499f4fa.txt +++ b/.riot/requirements/cccee00.txt @@ -2,21 +2,21 @@ # This file is autogenerated by pip-compile with Python 3.14 # by the following command: # -# pip-compile --allow-unsafe --no-annotate .riot/requirements/499f4fa.in +# pip-compile --allow-unsafe --no-annotate .riot/requirements/cccee00.in # -attrs==25.3.0 -coverage[toml]==7.10.6 +attrs==25.4.0 +coverage[toml]==7.11.0 gevent==25.9.1 greenlet==3.2.4 httpretty==1.1.4 hypothesis==6.45.0 -iniconfig==2.1.0 +iniconfig==2.3.0 mock==5.2.0 opentracing==2.4.0 packaging==25.0 pluggy==1.6.0 py-cpuinfo==9.0.0 -pyfakefs==5.9.3 +pyfakefs==5.10.0 pygments==2.19.2 pytest==8.4.2 pytest-asyncio==0.23.8 @@ -26,6 +26,7 @@ pytest-mock==3.15.1 pytest-randomly==4.0.1 python-json-logger==2.0.7 sortedcontainers==2.4.0 +wrapt==2.0.0 zope-event==5.0 zope-interface==7.2 diff --git a/ddtrace/_trace/pin.py b/ddtrace/_trace/pin.py index f5100e5557d..2850adb4896 100644 --- a/ddtrace/_trace/pin.py +++ b/ddtrace/_trace/pin.py @@ -2,9 +2,8 @@ from typing import Dict from typing import Optional -import wrapt - import ddtrace +from ddtrace.internal.compat import is_wrapted from ddtrace.settings.asm import config as asm_config from ..internal.logger import get_logger @@ -104,7 +103,7 @@ def get_from(obj: Any) -> Optional["Pin"]: if hasattr(obj, "__getddpin__"): return obj.__getddpin__() - pin_name = _DD_PIN_PROXY_NAME if isinstance(obj, wrapt.ObjectProxy) else _DD_PIN_NAME + pin_name = _DD_PIN_PROXY_NAME if is_wrapted(obj) else _DD_PIN_NAME pin = getattr(obj, pin_name, None) # detect if the PIN has been inherited from a class if pin is not None and pin._target != id(obj): @@ -167,7 +166,7 @@ def onto(self, obj: Any, send: bool = True) -> None: if hasattr(obj, "__setddpin__"): return obj.__setddpin__(self) - pin_name = _DD_PIN_PROXY_NAME if isinstance(obj, wrapt.ObjectProxy) else _DD_PIN_NAME + pin_name = _DD_PIN_PROXY_NAME if is_wrapted(obj) else _DD_PIN_NAME # set the target reference; any get_from, clones and retarget the new PIN self._target = id(obj) @@ -180,7 +179,7 @@ def onto(self, obj: Any, send: bool = True) -> None: def remove_from(self, obj: Any) -> None: # Remove pin from the object. try: - pin_name = _DD_PIN_PROXY_NAME if isinstance(obj, wrapt.ObjectProxy) else _DD_PIN_NAME + pin_name = _DD_PIN_PROXY_NAME if is_wrapted(obj) else _DD_PIN_NAME pin = Pin.get_from(obj) if pin is not None: diff --git a/ddtrace/contrib/internal/aiopg/patch.py b/ddtrace/contrib/internal/aiopg/patch.py index da26f02ca01..b508c36acef 100644 --- a/ddtrace/contrib/internal/aiopg/patch.py +++ b/ddtrace/contrib/internal/aiopg/patch.py @@ -10,6 +10,7 @@ from ddtrace.contrib.internal.psycopg.connection import patch_conn as psycopg_patch_conn from ddtrace.contrib.internal.psycopg.extensions import _patch_extensions from ddtrace.contrib.internal.psycopg.extensions import _unpatch_extensions +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils.wrappers import unwrap as _u @@ -63,7 +64,7 @@ def _unroll_args(obj, scope=None): # register_type performs a c-level check of the object # type so we must be sure to pass in the actual db connection - if scope and isinstance(scope, wrapt.ObjectProxy): + if scope and is_wrapted(scope): scope = scope.__wrapped__._conn return func(obj, scope) if scope else func(obj) diff --git a/ddtrace/contrib/internal/django/database.py b/ddtrace/contrib/internal/django/database.py index ab7b9045de7..1f9eec5a0fa 100644 --- a/ddtrace/contrib/internal/django/database.py +++ b/ddtrace/contrib/internal/django/database.py @@ -8,8 +8,6 @@ from typing import Type from typing import cast -import wrapt - import ddtrace from ddtrace import config from ddtrace._trace.pin import Pin @@ -18,6 +16,7 @@ from ddtrace.ext import db from ddtrace.ext import net from ddtrace.ext import sql as sqlx +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils.cache import cached @@ -68,7 +67,7 @@ def cursor(func: FunctionType, args: Tuple[Any], kwargs: Dict[str, Any]) -> Any: # Don't double wrap Django database cursors: # If the underlying cursor is already wrapped (e.g. by another library), # we just add the Django tags to the existing Pin (if any) and return - if isinstance(cursor.cursor, wrapt.ObjectProxy) and not config_django.always_create_database_spans: + if is_wrapted(cursor.cursor) and not config_django.always_create_database_spans: instance = args[0] tags = { "django.db.vendor": getattr(instance, "vendor", "db"), diff --git a/ddtrace/contrib/internal/django/patch.py b/ddtrace/contrib/internal/django/patch.py index fc9e0358167..84de239fcc6 100644 --- a/ddtrace/contrib/internal/django/patch.py +++ b/ddtrace/contrib/internal/django/patch.py @@ -21,6 +21,7 @@ from ddtrace.contrib import trace_utils from ddtrace.contrib.internal.django.user import _DjangoUserInfoRetriever from ddtrace.internal import core +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.constants import COMPONENT from ddtrace.internal.core.event_hub import ResultType from ddtrace.internal.endpoints import endpoint_collection @@ -252,7 +253,7 @@ def _instrument_view(django, view, path=None): for name in list(request_method_list or _DEFAULT_METHODS) + list(lifecycle_methods): try: func = getattr(view, name, None) - if not func or isinstance(func, wrapt.ObjectProxy): + if not func or is_wrapted(func): continue resource = "{0}.{1}".format(func_name(view), name) @@ -269,7 +270,7 @@ def _instrument_view(django, view, path=None): try: func = getattr(response_cls, name, None) # Do not wrap if the method does not exist or is already wrapped - if not func or isinstance(func, wrapt.ObjectProxy): + if not func or is_wrapted(func): continue resource = "{0}.{1}".format(func_name(response_cls), name) @@ -279,7 +280,7 @@ def _instrument_view(django, view, path=None): log.debug("Failed to instrument Django response %r function %s", response_cls, name, exc_info=True) # If the view itself is not wrapped, wrap it - if not isinstance(view, wrapt.ObjectProxy): + if not is_wrapted(view): view = utils.DjangoViewProxy( view, traced_func(django, "django.view", resource=func_name(view), ignored_excs=[django.http.Http404]) ) diff --git a/ddtrace/contrib/internal/fastapi/patch.py b/ddtrace/contrib/internal/fastapi/patch.py index 2b3913953c2..d10678f53a9 100644 --- a/ddtrace/contrib/internal/fastapi/patch.py +++ b/ddtrace/contrib/internal/fastapi/patch.py @@ -3,7 +3,6 @@ import fastapi import fastapi.routing -from wrapt import ObjectProxy from wrapt import wrap_function_wrapper as _w from ddtrace import config @@ -12,6 +11,7 @@ from ddtrace.contrib.internal.starlette.patch import _trace_background_tasks from ddtrace.contrib.internal.starlette.patch import traced_handler from ddtrace.contrib.internal.starlette.patch import traced_route_init +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.telemetry import get_config as _get_config @@ -93,16 +93,16 @@ def patch(): _w("fastapi.applications", "FastAPI.build_middleware_stack", wrap_middleware_stack) _w("fastapi.routing", "serialize_response", traced_serialize_response) - if not isinstance(fastapi.BackgroundTasks.add_task, ObjectProxy): + if not is_wrapted(fastapi.BackgroundTasks.add_task): _w("fastapi", "BackgroundTasks.add_task", _trace_background_tasks(fastapi)) # We need to check that Starlette instrumentation hasn't already patched these - if not isinstance(fastapi.routing.APIRoute.__init__, ObjectProxy): + if not is_wrapted(fastapi.routing.APIRoute.__init__): _w("fastapi.routing", "APIRoute.__init__", traced_route_init) - if not isinstance(fastapi.routing.APIRoute.handle, ObjectProxy): + if not is_wrapted(fastapi.routing.APIRoute.handle): _w("fastapi.routing", "APIRoute.handle", traced_handler) - if not isinstance(fastapi.routing.Mount.handle, ObjectProxy): + if not is_wrapted(fastapi.routing.Mount.handle): _w("starlette.routing", "Mount.handle", traced_handler) if asm_config._iast_enabled: @@ -121,11 +121,11 @@ def unpatch(): _u(fastapi.routing, "serialize_response") # We need to check that Starlette instrumentation hasn't already unpatched these - if isinstance(fastapi.routing.APIRoute.handle, ObjectProxy): + if is_wrapted(fastapi.routing.APIRoute.handle): _u(fastapi.routing.APIRoute, "handle") - if isinstance(fastapi.routing.Mount.handle, ObjectProxy): + if is_wrapted(fastapi.routing.Mount.handle): _u(fastapi.routing.Mount, "handle") - if isinstance(fastapi.BackgroundTasks.add_task, ObjectProxy): + if is_wrapted(fastapi.BackgroundTasks.add_task): _u(fastapi.BackgroundTasks, "add_task") diff --git a/ddtrace/contrib/internal/langchain/patch.py b/ddtrace/contrib/internal/langchain/patch.py index 78738e11281..971c6dff52f 100644 --- a/ddtrace/contrib/internal/langchain/patch.py +++ b/ddtrace/contrib/internal/langchain/patch.py @@ -5,7 +5,6 @@ from typing import Tuple import langchain_core -import wrapt from ddtrace import config from ddtrace._trace.pin import Pin @@ -14,6 +13,7 @@ from ddtrace.contrib.internal.trace_utils import with_traced_module from ddtrace.contrib.internal.trace_utils import wrap from ddtrace.internal import core +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.logger import get_logger from ddtrace.internal.utils import ArgumentError from ddtrace.internal.utils import get_argument_value @@ -587,11 +587,11 @@ def patched_embeddings_init_subclass(func, instance, args, kwargs): try: embed_documents = getattr(cls, "embed_documents", None) - if embed_documents and not isinstance(embed_documents, wrapt.ObjectProxy): + if embed_documents and not is_wrapted(embed_documents): wrap(cls, "embed_documents", traced_embedding(langchain_core)) embed_query = getattr(cls, "embed_query", None) - if embed_query and not isinstance(embed_query, wrapt.ObjectProxy): + if embed_query and not is_wrapted(embed_query): wrap(cls, "embed_query", traced_embedding(langchain_core)) except Exception: log.warning("Unable to patch LangChain Embeddings class %s", str(cls)) @@ -603,7 +603,7 @@ def patched_vectorstore_init_subclass(func, instance, args, kwargs): try: method = getattr(cls, "similarity_search", None) - if method and not isinstance(method, wrapt.ObjectProxy): + if method and not is_wrapted(method): wrap(cls, "similarity_search", traced_similarity_search(langchain_core)) except Exception: log.warning("Unable to patch LangChain VectorStore class %s", str(cls)) diff --git a/ddtrace/contrib/internal/mysql/patch.py b/ddtrace/contrib/internal/mysql/patch.py index 34f0344777f..557f3fb93c3 100644 --- a/ddtrace/contrib/internal/mysql/patch.py +++ b/ddtrace/contrib/internal/mysql/patch.py @@ -10,6 +10,7 @@ from ddtrace.contrib.internal.trace_utils import _convert_to_string from ddtrace.ext import db from ddtrace.ext import net +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.schema import schematize_database_operation from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils.formats import asbool @@ -62,7 +63,7 @@ def patch(): def unpatch(): - if isinstance(mysql.connector.connect, wrapt.ObjectProxy): + if is_wrapted(mysql.connector.connect): mysql.connector.connect = mysql.connector.connect.__wrapped__ if hasattr(mysql.connector, "Connect"): mysql.connector.Connect = mysql.connector.connect diff --git a/ddtrace/contrib/internal/psycopg/extensions.py b/ddtrace/contrib/internal/psycopg/extensions.py index 4f5b772e0c3..3525c29f053 100644 --- a/ddtrace/contrib/internal/psycopg/extensions.py +++ b/ddtrace/contrib/internal/psycopg/extensions.py @@ -1,5 +1,7 @@ import wrapt +from ddtrace.internal.compat import is_wrapted + def get_psycopg2_extensions(psycopg_module): _extensions = [ @@ -36,7 +38,7 @@ def _unroll_args(obj, scope=None): # register_type performs a c-level check of the object # type so we must be sure to pass in the actual db connection - if scope and isinstance(scope, wrapt.ObjectProxy): + if scope and is_wrapted(scope): scope = scope.__wrapped__ return func(obj, scope) if scope else func(obj) @@ -50,7 +52,7 @@ def _unroll_args(obj, scope=None): # register_type performs a c-level check of the object # type so we must be sure to pass in the actual db connection - if scope and isinstance(scope, wrapt.ObjectProxy): + if scope and is_wrapted(scope): scope = scope.__wrapped__ return func(obj, scope) if scope else func(obj) @@ -72,7 +74,7 @@ def prepare(self, *args, **kwargs): # prepare performs a c-level check of the object type so # we must be sure to pass in the actual db connection - if isinstance(conn, wrapt.ObjectProxy): + if is_wrapted(conn): conn = conn.__wrapped__ return func(conn, *args[1:], **kwargs) @@ -82,7 +84,7 @@ def _patch_extensions(_extensions): # we must patch extensions all the time (it's pretty harmless) so split # from global patching of connections. must be idempotent. for _, module, func, wrapper in _extensions: - if not hasattr(module, func) or isinstance(getattr(module, func), wrapt.ObjectProxy): + if not hasattr(module, func) or is_wrapted(getattr(module, func)): continue wrapt.wrap_function_wrapper(module, func, wrapper) diff --git a/ddtrace/contrib/internal/pymysql/patch.py b/ddtrace/contrib/internal/pymysql/patch.py index 290c6f1fad6..4e3c9900f05 100644 --- a/ddtrace/contrib/internal/pymysql/patch.py +++ b/ddtrace/contrib/internal/pymysql/patch.py @@ -10,6 +10,7 @@ from ddtrace.contrib.internal.trace_utils import _convert_to_string from ddtrace.ext import db from ddtrace.ext import net +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.schema import schematize_database_operation from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils.formats import asbool @@ -52,7 +53,7 @@ def patch(): def unpatch(): - if isinstance(pymysql.connect, wrapt.ObjectProxy): + if is_wrapted(pymysql.connect): pymysql.connect = pymysql.connect.__wrapped__ pymysql._datadog_patch = False diff --git a/ddtrace/contrib/internal/pyramid/trace.py b/ddtrace/contrib/internal/pyramid/trace.py index 81ae0bae953..e8493d0e104 100644 --- a/ddtrace/contrib/internal/pyramid/trace.py +++ b/ddtrace/contrib/internal/pyramid/trace.py @@ -8,6 +8,7 @@ from ddtrace import config from ddtrace.ext import SpanTypes from ddtrace.internal import core +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.constants import COMPONENT from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name @@ -34,7 +35,7 @@ def includeme(config): # Add our tween just before the default exception handler config.add_tween(DD_TWEEN_NAME, over=pyramid.tweens.EXCVIEW) # ensure we only patch the renderer once. - if not isinstance(pyramid.renderers.RendererHelper.render, wrapt.ObjectProxy): + if not is_wrapted(pyramid.renderers.RendererHelper.render): wrapt.wrap_function_wrapper("pyramid.renderers", "RendererHelper.render", trace_render) diff --git a/ddtrace/contrib/internal/starlette/patch.py b/ddtrace/contrib/internal/starlette/patch.py index 6739c0e8a37..1a02f8981e8 100644 --- a/ddtrace/contrib/internal/starlette/patch.py +++ b/ddtrace/contrib/internal/starlette/patch.py @@ -9,7 +9,6 @@ from starlette import requests as starlette_requests from starlette.concurrency import run_in_threadpool from starlette.middleware import Middleware -from wrapt import ObjectProxy from wrapt import wrap_function_wrapper as _w from ddtrace import config @@ -20,6 +19,7 @@ from ddtrace.ext import http from ddtrace.internal import core from ddtrace.internal._exceptions import BlockingException +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.endpoints import endpoint_collection from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name @@ -108,14 +108,14 @@ def patch(): Pin().onto(starlette) # We need to check that Fastapi instrumentation hasn't already patched these - if not isinstance(starlette.routing.Route.__init__, ObjectProxy): + if not is_wrapted(starlette.routing.Route.__init__): _w("starlette.routing", "Route.__init__", traced_route_init) - if not isinstance(starlette.routing.Route.handle, ObjectProxy): + if not is_wrapted(starlette.routing.Route.handle): _w("starlette.routing", "Route.handle", traced_handler) - if not isinstance(starlette.routing.Mount.handle, ObjectProxy): + if not is_wrapted(starlette.routing.Mount.handle): _w("starlette.routing", "Mount.handle", traced_handler) - if not isinstance(starlette.background.BackgroundTasks.add_task, ObjectProxy): + if not is_wrapted(starlette.background.BackgroundTasks.add_task): _w("starlette.background", "BackgroundTasks.add_task", _trace_background_tasks(starlette)) @@ -128,13 +128,13 @@ def unpatch(): _u(starlette.applications.Starlette, "__init__") # We need to check that Fastapi instrumentation hasn't already unpatched these - if isinstance(starlette.routing.Route.handle, ObjectProxy): + if is_wrapted(starlette.routing.Route.handle): _u(starlette.routing.Route, "handle") - if isinstance(starlette.routing.Mount.handle, ObjectProxy): + if is_wrapted(starlette.routing.Mount.handle): _u(starlette.routing.Mount, "handle") - if isinstance(starlette.background.BackgroundTasks.add_task, ObjectProxy): + if is_wrapted(starlette.background.BackgroundTasks.add_task): _u(starlette.background.BackgroundTasks, "add_task") diff --git a/ddtrace/internal/compat.py b/ddtrace/internal/compat.py index 40b8d0e1f87..aaa4b8fd358 100644 --- a/ddtrace/internal/compat.py +++ b/ddtrace/internal/compat.py @@ -8,6 +8,8 @@ from typing import Type # noqa:F401 from typing import Union # noqa:F401 +import wrapt + __all__ = [ "maybe_stringify", @@ -126,3 +128,14 @@ def __getattr__(name: str) -> Any: return globals()[name] except KeyError: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + + +if hasattr(wrapt, "BaseObjectProxy"): + # This must be used for wrapt version >= 2.0.0 + wrapt_class: type = wrapt.BaseObjectProxy +else: + wrapt_class = wrapt.ObjectProxy + + +def is_wrapted(o: object) -> bool: + return isinstance(o, wrapt_class) diff --git a/ddtrace/internal/forksafe.py b/ddtrace/internal/forksafe.py index 1f9d24cfd7e..313f8a73cb9 100644 --- a/ddtrace/internal/forksafe.py +++ b/ddtrace/internal/forksafe.py @@ -138,16 +138,13 @@ def _reset_object(self): self.__wrapped__ = self._self_wrapped_class() -def Lock(): - # type: (...) -> ResetObject[threading.Lock] - return ResetObject(threading.Lock) +def Lock() -> threading.Lock: + return ResetObject(threading.Lock) # type: ignore -def RLock(): - # type: (...) -> ResetObject[threading.RLock] - return ResetObject(threading.RLock) +def RLock() -> threading.RLock: + return ResetObject(threading.RLock) # type: ignore -def Event(): - # type: (...) -> ResetObject[threading.Event] - return ResetObject(threading.Event) +def Event() -> threading.Event: + return ResetObject(threading.Event) # type: ignore diff --git a/ddtrace/internal/safety.py b/ddtrace/internal/safety.py index 2bac507d1ec..8ce48458567 100644 --- a/ddtrace/internal/safety.py +++ b/ddtrace/internal/safety.py @@ -67,29 +67,34 @@ def __call__(self, *args, **kwargs): def __getattribute__(self, name): # type: (str) -> Any - if name == "__wrapped__" and not IS_312_OR_NEWER: - raise AttributeError("Access denied") - + if name == "__wrapped__": + if not IS_312_OR_NEWER: + raise AttributeError("Access denied") + else: + return super(SafeObjectProxy, self).__wrapped__ return super(SafeObjectProxy, self).__getattribute__(name) def __getattr__(self, name): # type: (str) -> Any - if name == "__wrapped__" and IS_312_OR_NEWER: - raise AttributeError("Access denied") - return type(self).safe(super(SafeObjectProxy, self).__getattr__(name)) + if name == "__wrapped__": + if IS_312_OR_NEWER: + raise AttributeError("Access denied") + else: + return super(SafeObjectProxy, self).__wrapped__ + return type(self).safe(super(SafeObjectProxy, self).__getattr__(name)) # type: ignore def __getitem__(self, item): # type: (Any) -> Any - return type(self).safe(super(SafeObjectProxy, self).__getitem__(item)) + return type(self).safe(super(SafeObjectProxy, self).__getitem__(item)) # type: ignore def __iter__(self): # type: () -> Any - return iter(type(self).safe(_) for _ in super(SafeObjectProxy, self).__iter__()) + return iter(type(self).safe(_) for _ in super(SafeObjectProxy, self).__iter__()) # type: ignore def items(self): # type: () -> Iterator[Tuple[Any, Any]] return ( - (type(self).safe(k), type(self).safe(v)) for k, v in super(SafeObjectProxy, self).__getattr__("items")() + (type(self).safe(k), type(self).safe(v)) for k, v in super(SafeObjectProxy, self).__getattr__("items")() # type: ignore ) # Custom object representations might cause side-effects @@ -103,7 +108,6 @@ def safe(cls, obj): # type: (Any) -> Optional[Any] """Turn an object into a safe proxy.""" _type = type(obj) - if _isinstance(obj, type): try: if obj.__module__ == "builtins": diff --git a/ddtrace/internal/utils/wrappers.py b/ddtrace/internal/utils/wrappers.py index cfe0b5df1ae..26eb9701471 100644 --- a/ddtrace/internal/utils/wrappers.py +++ b/ddtrace/internal/utils/wrappers.py @@ -3,7 +3,7 @@ from typing import Optional # noqa:F401 from typing import TypeVar # noqa:F401 -import wrapt +from ddtrace.internal.compat import is_wrapted F = TypeVar("F", bound=Callable[..., Any]) @@ -14,7 +14,7 @@ def iswrapped(obj, attr=None): """Returns whether an attribute is wrapped or not.""" if attr is not None: obj = getattr(obj, attr, None) - return (hasattr(obj, "__wrapped__") and isinstance(obj, wrapt.ObjectProxy)) or hasattr(obj, "__dd_wrapped__") + return (hasattr(obj, "__wrapped__") and is_wrapted(obj)) or hasattr(obj, "__dd_wrapped__") def unwrap(obj, attr): diff --git a/ddtrace/profiling/collector/_lock.py b/ddtrace/profiling/collector/_lock.py index f2a542c19c7..6e3e2ddfd7e 100644 --- a/ddtrace/profiling/collector/_lock.py +++ b/ddtrace/profiling/collector/_lock.py @@ -256,7 +256,7 @@ class FunctionWrapper(wrapt.FunctionWrapper): # Override the __get__ method: whatever happens, _allocate_lock is always considered by Python like a "static" # method, even when used as a class attribute. Python never tried to "bind" it to a method, because it sees it is a # builtin function. Override default wrapt behavior here that tries to detect bound method. - def __get__(self, instance: Any, owner: Optional[Type] = None) -> FunctionWrapper: + def __get__(self, instance: Any, owner: Optional[Type] = None) -> FunctionWrapper: # type: ignore return self diff --git a/hatch.toml b/hatch.toml index 16b501be794..f826ba78a09 100644 --- a/hatch.toml +++ b/hatch.toml @@ -15,9 +15,6 @@ dependencies = [ "types-PyYAML==6.0.12.2", "types-setuptools==65.6.0.0", "ddapm-test-agent>=1.2.0", - # TODO: Remove this when we are compatible with wrapt>=2 - # ddapm-test-agent -> vcrpy -> wrapt - "wrapt<2", "packaging==23.1", "pygments==2.16.1", "riot==0.20.1", diff --git a/lib-injection/sources/requirements.csv b/lib-injection/sources/requirements.csv index fbfd3b94930..46c1d111320 100644 --- a/lib-injection/sources/requirements.csv +++ b/lib-injection/sources/requirements.csv @@ -8,7 +8,7 @@ envier,~=0.6.1, legacy-cgi,>=2.0.0,python_version>='3.13.0' opentelemetry-api,>=1, protobuf,>=3, -wrapt,">=1,<2", +wrapt,>=1, opentracing,>=2.0.0, opentelemetry-exporter-otlp,>=1.0.0, tiktoken,, diff --git a/pyproject.toml b/pyproject.toml index 4cc4e37a40c..bf2080b78d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dependencies = [ "legacy-cgi>=2.0.0; python_version>='3.13.0'", "opentelemetry-api>=1", "protobuf>=3", - "wrapt>=1,<2", + "wrapt>=1", ] [project.optional-dependencies] diff --git a/releasenotes/notes/wrapt_2-42f935eac8adaac8.yaml b/releasenotes/notes/wrapt_2-42f935eac8adaac8.yaml new file mode 100644 index 00000000000..42d80a020dc --- /dev/null +++ b/releasenotes/notes/wrapt_2-42f935eac8adaac8.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - | + tracer: This fix ensures compatibility with wrapt 2.0.0 diff --git a/requirements.csv b/requirements.csv index fbfd3b94930..46c1d111320 100644 --- a/requirements.csv +++ b/requirements.csv @@ -8,7 +8,7 @@ envier,~=0.6.1, legacy-cgi,>=2.0.0,python_version>='3.13.0' opentelemetry-api,>=1, protobuf,>=3, -wrapt,">=1,<2", +wrapt,>=1, opentracing,>=2.0.0, opentelemetry-exporter-otlp,>=1.0.0, tiktoken,, diff --git a/riotfile.py b/riotfile.py index f12379c4b8c..b8144914b9f 100644 --- a/riotfile.py +++ b/riotfile.py @@ -512,6 +512,7 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT "python-json-logger": "==2.0.7", "pyfakefs": latest, "pytest-benchmark": latest, + "wrapt": [latest, "<2.0.0"], }, venvs=[ Venv( diff --git a/tests/contrib/aredis/test_aredis.py b/tests/contrib/aredis/test_aredis.py index baa8b7f6c30..c1ae507aae5 100644 --- a/tests/contrib/aredis/test_aredis.py +++ b/tests/contrib/aredis/test_aredis.py @@ -3,11 +3,11 @@ import aredis import pytest -from wrapt import ObjectProxy from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.aredis.patch import patch from ddtrace.contrib.internal.aredis.patch import unpatch +from ddtrace.internal.compat import is_wrapted from tests.conftest import DEFAULT_DDTRACE_SUBPROCESS_TEST_SERVICE_NAME from tests.opentracer.utils import init_tracer from tests.utils import override_config @@ -37,17 +37,17 @@ def test_patching(): When unpatching aredis library We unwrap the correct methods """ - assert isinstance(aredis.client.StrictRedis.execute_command, ObjectProxy) - assert isinstance(aredis.client.StrictRedis.pipeline, ObjectProxy) - assert isinstance(aredis.pipeline.StrictPipeline.execute, ObjectProxy) - assert isinstance(aredis.pipeline.StrictPipeline.immediate_execute_command, ObjectProxy) + assert is_wrapted(aredis.client.StrictRedis.execute_command) + assert is_wrapted(aredis.client.StrictRedis.pipeline) + assert is_wrapted(aredis.pipeline.StrictPipeline.execute) + assert is_wrapted(aredis.pipeline.StrictPipeline.immediate_execute_command) unpatch() - assert not isinstance(aredis.client.StrictRedis.execute_command, ObjectProxy) - assert not isinstance(aredis.client.StrictRedis.pipeline, ObjectProxy) - assert not isinstance(aredis.pipeline.StrictPipeline.execute, ObjectProxy) - assert not isinstance(aredis.pipeline.StrictPipeline.immediate_execute_command, ObjectProxy) + assert not is_wrapted(aredis.client.StrictRedis.execute_command) + assert not is_wrapted(aredis.client.StrictRedis.pipeline) + assert not is_wrapted(aredis.pipeline.StrictPipeline.execute) + assert not is_wrapted(aredis.pipeline.StrictPipeline.immediate_execute_command) @pytest.mark.asyncio diff --git a/tests/contrib/avro/test_avro.py b/tests/contrib/avro/test_avro.py index 0934f8a16ef..b6310295810 100644 --- a/tests/contrib/avro/test_avro.py +++ b/tests/contrib/avro/test_avro.py @@ -2,13 +2,13 @@ from avro.datafile import DataFileWriter from avro.io import DatumReader from avro.io import DatumWriter -from wrapt import ObjectProxy from ddtrace._trace.pin import Pin from ddtrace.constants import AUTO_KEEP from ddtrace.contrib.internal.avro.patch import patch from ddtrace.contrib.internal.avro.patch import unpatch from ddtrace.ext import schema as SCHEMA_TAGS +from ddtrace.internal.compat import is_wrapted OPENAPI_USER_SCHEMA_DEF = ( @@ -35,13 +35,13 @@ def test_patching(avro): We unwrap the correct methods """ patch() - assert isinstance(avro.io.DatumReader.read, ObjectProxy) - assert isinstance(avro.io.DatumWriter.write, ObjectProxy) + assert is_wrapted(avro.io.DatumReader.read) + assert is_wrapted(avro.io.DatumWriter.write) unpatch() - assert not isinstance(avro.io.DatumReader.read, ObjectProxy) - assert not isinstance(avro.io.DatumWriter.write, ObjectProxy) + assert not is_wrapted(avro.io.DatumReader.read) + assert not is_wrapted(avro.io.DatumWriter.write) def test_basic_schema_serialize(avro, tracer, test_spans): diff --git a/tests/contrib/dramatiq/autopatch.py b/tests/contrib/dramatiq/autopatch.py index 1a0d0cc7e8f..38b670de2aa 100644 --- a/tests/contrib/dramatiq/autopatch.py +++ b/tests/contrib/dramatiq/autopatch.py @@ -1,4 +1,4 @@ -import wrapt +from ddtrace.internal.compat import is_wrapted if __name__ == "__main__": @@ -15,5 +15,5 @@ def add_numbers(a: int, b: int): # now dramatiq should be patched actor = broker.get_actor("add_numbers") - assert isinstance(dramatiq.Actor.send_with_options, wrapt.ObjectProxy) + assert is_wrapted(dramatiq.Actor.send_with_options) print("Test success") diff --git a/tests/contrib/dramatiq/test_patch_manual.py b/tests/contrib/dramatiq/test_patch_manual.py index 67bbbe9e7ee..4807302d7af 100644 --- a/tests/contrib/dramatiq/test_patch_manual.py +++ b/tests/contrib/dramatiq/test_patch_manual.py @@ -1,6 +1,6 @@ import unittest -import wrapt +from ddtrace.internal.compat import is_wrapted class DramatiqPatchTest(unittest.TestCase): @@ -27,9 +27,9 @@ def add_numbers(a: int, b: int): assert msg.args == (1, 2) # Check patch/unpatch outcome - assert isinstance(dramatiq.Actor.send_with_options, wrapt.ObjectProxy) + assert is_wrapted(dramatiq.Actor.send_with_options) unpatch() - assert not isinstance(dramatiq.Actor.send_with_options, wrapt.ObjectProxy) + assert not is_wrapted(dramatiq.Actor.send_with_options) def test_patch_after_import(self): import dramatiq @@ -55,6 +55,6 @@ def custom_function_max_power(base: int, exp: int): assert msg.args == (3, 4) # Check patch/unpatch behavior - assert isinstance(dramatiq.Actor.send_with_options, wrapt.ObjectProxy) + assert is_wrapted(dramatiq.Actor.send_with_options) unpatch() - assert not isinstance(dramatiq.Actor.send_with_options, wrapt.ObjectProxy) + assert not is_wrapted(dramatiq.Actor.send_with_options) diff --git a/tests/contrib/flask/__init__.py b/tests/contrib/flask/__init__.py index 1f29a06ccf5..a887d62c9fb 100644 --- a/tests/contrib/flask/__init__.py +++ b/tests/contrib/flask/__init__.py @@ -1,10 +1,10 @@ import flask from flask.testing import FlaskClient -import wrapt from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.flask.patch import patch from ddtrace.contrib.internal.flask.patch import unpatch +from ddtrace.internal.compat import is_wrapted from tests.utils import TracerTestCase @@ -47,10 +47,10 @@ def get_spans(self): return self.tracer.pop() def assert_is_wrapped(self, obj): - self.assertTrue(isinstance(obj, wrapt.ObjectProxy), "{} is not wrapped".format(obj)) + self.assertTrue(is_wrapted(obj), "{} is not wrapped".format(obj)) def assert_is_not_wrapped(self, obj): - self.assertFalse(isinstance(obj, wrapt.ObjectProxy), "{} is wrapped".format(obj)) + self.assertFalse(is_wrapted(obj), "{} is wrapped".format(obj)) def find_span_by_name(self, spans, name, required=True): """Helper to find the first span with a given name from a list""" diff --git a/tests/contrib/flask/test_idempotency.py b/tests/contrib/flask/test_idempotency.py index 0b7758d24bc..52a4abe29ed 100644 --- a/tests/contrib/flask/test_idempotency.py +++ b/tests/contrib/flask/test_idempotency.py @@ -2,12 +2,12 @@ import flask import mock -import wrapt from ddtrace.contrib.internal.flask.patch import _u from ddtrace.contrib.internal.flask.patch import _w from ddtrace.contrib.internal.flask.patch import patch from ddtrace.contrib.internal.flask.patch import unpatch +from ddtrace.internal.compat import is_wrapted class FlaskIdempotencyTestCase(unittest.TestCase): @@ -17,11 +17,11 @@ def tearDown(self): def assert_is_patched(self): self.assertTrue(flask._datadog_patch) - self.assertTrue(isinstance(flask.render_template, wrapt.ObjectProxy)) + self.assertTrue(is_wrapted(flask.render_template)) def assert_is_not_patched(self): self.assertFalse(flask._datadog_patch) - self.assertFalse(isinstance(flask.render_template, wrapt.ObjectProxy)) + self.assertFalse(is_wrapted(flask.render_template)) def test_datadog_patch(self): # If we have been patching/testing in other files, diff --git a/tests/contrib/flask_autopatch/test_flask_autopatch.py b/tests/contrib/flask_autopatch/test_flask_autopatch.py index 1396e759581..eff212aca29 100644 --- a/tests/contrib/flask_autopatch/test_flask_autopatch.py +++ b/tests/contrib/flask_autopatch/test_flask_autopatch.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import flask -import wrapt from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.flask.patch import flask_version from ddtrace.ext import http +from ddtrace.internal.compat import is_wrapted from tests.utils import TracerTestCase from tests.utils import assert_is_measured from tests.utils import assert_span_http_status_code @@ -32,12 +32,12 @@ def test_patched(self): self.assertTrue(flask._datadog_patch) # Assert our instance of flask.app.Flask is patched - self.assertTrue(isinstance(self.app.add_url_rule, wrapt.ObjectProxy)) - self.assertTrue(isinstance(self.app.wsgi_app, wrapt.ObjectProxy)) + self.assertTrue(is_wrapted(self.app.add_url_rule)) + self.assertTrue(is_wrapted(self.app.wsgi_app)) # Assert the base module flask.app.Flask methods are patched - self.assertTrue(isinstance(flask.app.Flask.add_url_rule, wrapt.ObjectProxy)) - self.assertTrue(isinstance(flask.app.Flask.wsgi_app, wrapt.ObjectProxy)) + self.assertTrue(is_wrapted(flask.app.Flask.add_url_rule)) + self.assertTrue(is_wrapted(flask.app.Flask.wsgi_app)) def test_request(self): """ diff --git a/tests/contrib/httpx/test_httpx.py b/tests/contrib/httpx/test_httpx.py index 36f13064e09..6fbbbee9427 100644 --- a/tests/contrib/httpx/test_httpx.py +++ b/tests/contrib/httpx/test_httpx.py @@ -1,12 +1,12 @@ import httpx import pytest -from wrapt import ObjectProxy from ddtrace import config from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.httpx.patch import HTTPX_VERSION from ddtrace.contrib.internal.httpx.patch import patch from ddtrace.contrib.internal.httpx.patch import unpatch +from ddtrace.internal.compat import is_wrapted from ddtrace.settings.http import HttpConfig from tests.utils import override_config from tests.utils import override_http_config @@ -44,12 +44,12 @@ def test_patching(): When unpatching httpx library We unwrap the correct methods """ - assert isinstance(httpx.Client.send, ObjectProxy) - assert isinstance(httpx.AsyncClient.send, ObjectProxy) + assert is_wrapted(httpx.Client.send) + assert is_wrapted(httpx.AsyncClient.send) unpatch() - assert not isinstance(httpx.Client.send, ObjectProxy) - assert not isinstance(httpx.AsyncClient.send, ObjectProxy) + assert not is_wrapted(httpx.Client.send) + assert not is_wrapted(httpx.AsyncClient.send) def test_httpx_service_name(tracer, test_spans): diff --git a/tests/contrib/httpx/test_httpx_pre_0_11.py b/tests/contrib/httpx/test_httpx_pre_0_11.py index 351fab74e50..dff425f1635 100644 --- a/tests/contrib/httpx/test_httpx_pre_0_11.py +++ b/tests/contrib/httpx/test_httpx_pre_0_11.py @@ -1,12 +1,12 @@ import httpx import pytest -from wrapt import ObjectProxy from ddtrace import config from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.httpx.patch import HTTPX_VERSION from ddtrace.contrib.internal.httpx.patch import patch from ddtrace.contrib.internal.httpx.patch import unpatch +from ddtrace.internal.compat import is_wrapted from ddtrace.settings.http import HttpConfig from tests.utils import override_config from tests.utils import override_http_config @@ -45,9 +45,9 @@ def test_patching(): When unpatching httpx library We unwrap the correct methods """ - assert isinstance(httpx.Client.send, ObjectProxy) + assert is_wrapted(httpx.Client.send) unpatch() - assert not isinstance(httpx.Client.send, ObjectProxy) + assert not is_wrapted(httpx.Client.send) @pytest.mark.asyncio diff --git a/tests/contrib/patch.py b/tests/contrib/patch.py index da73a356f69..1e15cc9a828 100644 --- a/tests/contrib/patch.py +++ b/tests/contrib/patch.py @@ -8,8 +8,7 @@ from textwrap import dedent import unittest -import wrapt - +from ddtrace.internal.compat import is_wrapted from ddtrace.version import get_version from tests.subprocesstest import SubprocessTestCase from tests.subprocesstest import run_in_subprocess @@ -43,7 +42,7 @@ def assert_not_module_imported(self, modname): assert not self.module_imported(modname), "{} module is imported".format(modname) def is_wrapped(self, obj): - return isinstance(obj, wrapt.ObjectProxy) or hasattr(obj, "__dd_wrapped__") + return is_wrapted(obj) or hasattr(obj, "__dd_wrapped__") def assert_wrapped(self, obj): """ @@ -65,7 +64,7 @@ def assert_not_double_wrapped(self, obj): """ self.assert_wrapped(obj) - wrapped = obj.__wrapped__ if isinstance(obj, wrapt.ObjectProxy) else obj.__dd_wrapped__ + wrapped = obj.__wrapped__ if is_wrapted(obj) else obj.__dd_wrapped__ self.assert_not_wrapped(wrapped) diff --git a/tests/contrib/protobuf/test_protobuf.py b/tests/contrib/protobuf/test_protobuf.py index 6e6db042784..cfad6b24f07 100644 --- a/tests/contrib/protobuf/test_protobuf.py +++ b/tests/contrib/protobuf/test_protobuf.py @@ -1,11 +1,10 @@ import importlib -from wrapt import ObjectProxy - from ddtrace.constants import AUTO_KEEP from ddtrace.contrib.internal.protobuf.patch import patch from ddtrace.contrib.internal.protobuf.patch import unpatch from ddtrace.ext import schema as SCHEMA_TAGS +from ddtrace.internal.compat import is_wrapted from tests.contrib.protobuf.schemas import message_pb2 from tests.contrib.protobuf.schemas import other_message_pb2 @@ -34,10 +33,10 @@ def test_patching(protobuf): We unwrap the correct methods """ patch() - assert isinstance(protobuf.internal.builder.BuildTopDescriptorsAndMessages, ObjectProxy) + assert is_wrapted(protobuf.internal.builder.BuildTopDescriptorsAndMessages) unpatch() - assert not isinstance(protobuf.internal.builder.BuildTopDescriptorsAndMessages, ObjectProxy) + assert not is_wrapted(protobuf.internal.builder.BuildTopDescriptorsAndMessages) def test_basic_schema_serialize(protobuf, tracer, test_spans): diff --git a/tests/contrib/psycopg/test_psycopg_snapshot.py b/tests/contrib/psycopg/test_psycopg_snapshot.py index 8bdb7c7de94..3d6b9be6b5d 100644 --- a/tests/contrib/psycopg/test_psycopg_snapshot.py +++ b/tests/contrib/psycopg/test_psycopg_snapshot.py @@ -3,23 +3,23 @@ import psycopg import pytest -import wrapt from ddtrace.contrib.internal.psycopg.patch import patch from ddtrace.contrib.internal.psycopg.patch import unpatch +from ddtrace.internal.compat import is_wrapted @pytest.fixture(autouse=True) def patch_psycopg(): patch() - assert isinstance(psycopg.connect, wrapt.ObjectProxy) - assert isinstance(psycopg.Cursor, wrapt.ObjectProxy) - assert isinstance(psycopg.AsyncCursor, wrapt.ObjectProxy) + assert is_wrapted(psycopg.connect) + assert is_wrapted(psycopg.Cursor) + assert is_wrapted(psycopg.AsyncCursor) # check if Connection connect methods are patched try: - assert isinstance(psycopg.Connection.connect, wrapt.ObjectProxy) - assert isinstance(psycopg.AsyncConnection.connect, wrapt.ObjectProxy) + assert is_wrapted(psycopg.Connection.connect) + assert is_wrapted(psycopg.AsyncConnection.connect) except AttributeError: if sys.version_info >= (3, 11): # Python 3.11 is throwing an AttributeError when accessing a BoundMethod diff --git a/tests/contrib/psycopg2/test_psycopg_snapshot.py b/tests/contrib/psycopg2/test_psycopg_snapshot.py index 61da040c3c8..75106376dec 100644 --- a/tests/contrib/psycopg2/test_psycopg_snapshot.py +++ b/tests/contrib/psycopg2/test_psycopg_snapshot.py @@ -2,16 +2,16 @@ import psycopg2 import pytest -import wrapt from ddtrace.contrib.internal.psycopg.patch import patch from ddtrace.contrib.internal.psycopg.patch import unpatch +from ddtrace.internal.compat import is_wrapted @pytest.fixture(autouse=True) def patch_psycopg(): patch() - assert isinstance(psycopg2.connect, wrapt.ObjectProxy) + assert is_wrapted(psycopg2.connect) yield unpatch() diff --git a/tests/contrib/pymemcache/test_client.py b/tests/contrib/pymemcache/test_client.py index b5854be53ae..4d7cac89c09 100644 --- a/tests/contrib/pymemcache/test_client.py +++ b/tests/contrib/pymemcache/test_client.py @@ -14,6 +14,7 @@ from ddtrace.contrib.internal.pymemcache.client import WrappedClient from ddtrace.contrib.internal.pymemcache.patch import patch from ddtrace.contrib.internal.pymemcache.patch import unpatch +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from tests.utils import DummyTracer from tests.utils import TracerTestCase @@ -43,7 +44,7 @@ class PymemcacheClientTestCase(PymemcacheClientTestCaseMixin): def test_patch(self): assert issubclass(pymemcache.client.base.Client, wrapt.ObjectProxy) client = self.make_client([]) - self.assertIsInstance(client, wrapt.ObjectProxy) + self.assertTrue(is_wrapted(client)) def test_unpatch(self): unpatch() @@ -298,7 +299,7 @@ def test_patched_hash_client(self): assert client.client_class == WrappedClient assert len(client.clients) for _c in client.clients.values(): - assert isinstance(_c, wrapt.ObjectProxy) + assert is_wrapted(_c) def test_delete_many_found(self): """ diff --git a/tests/contrib/redis/test_redis_asyncio.py b/tests/contrib/redis/test_redis_asyncio.py index 7e96ef0e4c7..8df4174b209 100644 --- a/tests/contrib/redis/test_redis_asyncio.py +++ b/tests/contrib/redis/test_redis_asyncio.py @@ -5,11 +5,11 @@ import pytest import redis import redis.asyncio -from wrapt import ObjectProxy from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.redis.patch import patch from ddtrace.contrib.internal.redis.patch import unpatch +from ddtrace.internal.compat import is_wrapted from ddtrace.trace import tracer from tests.utils import override_config @@ -53,13 +53,13 @@ def test_patching(): When unpatching redis library We unwrap the correct methods """ - assert isinstance(redis.asyncio.client.Redis.execute_command, ObjectProxy) - assert isinstance(redis.asyncio.client.Redis.pipeline, ObjectProxy) - assert isinstance(redis.asyncio.client.Pipeline.pipeline, ObjectProxy) + assert is_wrapted(redis.asyncio.client.Redis.execute_command) + assert is_wrapted(redis.asyncio.client.Redis.pipeline) + assert is_wrapted(redis.asyncio.client.Pipeline.pipeline) unpatch() - assert not isinstance(redis.asyncio.client.Redis.execute_command, ObjectProxy) - assert not isinstance(redis.asyncio.client.Redis.pipeline, ObjectProxy) - assert not isinstance(redis.asyncio.client.Pipeline.pipeline, ObjectProxy) + assert not is_wrapted(redis.asyncio.client.Redis.execute_command) + assert not is_wrapted(redis.asyncio.client.Redis.pipeline) + assert not is_wrapted(redis.asyncio.client.Pipeline.pipeline) @pytest.mark.snapshot(wait_for_num_traces=1) diff --git a/tests/contrib/valkey/test_valkey_asyncio.py b/tests/contrib/valkey/test_valkey_asyncio.py index a518b0cf317..7131c5142d4 100644 --- a/tests/contrib/valkey/test_valkey_asyncio.py +++ b/tests/contrib/valkey/test_valkey_asyncio.py @@ -5,12 +5,12 @@ import pytest import valkey import valkey.asyncio -from wrapt import ObjectProxy from ddtrace import tracer from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.valkey.patch import patch from ddtrace.contrib.internal.valkey.patch import unpatch +from ddtrace.internal.compat import is_wrapted from tests.utils import override_config from ..config import VALKEY_CONFIG @@ -53,13 +53,13 @@ def test_patching(): When unpatching valkey library We unwrap the correct methods """ - assert isinstance(valkey.asyncio.client.Valkey.execute_command, ObjectProxy) - assert isinstance(valkey.asyncio.client.Valkey.pipeline, ObjectProxy) - assert isinstance(valkey.asyncio.client.Pipeline.pipeline, ObjectProxy) + assert is_wrapted(valkey.asyncio.client.Valkey.execute_command) + assert is_wrapted(valkey.asyncio.client.Valkey.pipeline) + assert is_wrapted(valkey.asyncio.client.Pipeline.pipeline) unpatch() - assert not isinstance(valkey.asyncio.client.Valkey.execute_command, ObjectProxy) - assert not isinstance(valkey.asyncio.client.Valkey.pipeline, ObjectProxy) - assert not isinstance(valkey.asyncio.client.Pipeline.pipeline, ObjectProxy) + assert not is_wrapted(valkey.asyncio.client.Valkey.execute_command) + assert not is_wrapted(valkey.asyncio.client.Valkey.pipeline) + assert not is_wrapted(valkey.asyncio.client.Pipeline.pipeline) @pytest.mark.snapshot(wait_for_num_traces=1) diff --git a/tests/contrib/vertica/test_vertica.py b/tests/contrib/vertica/test_vertica.py index c65b19dd0fd..1f3becdb8bf 100644 --- a/tests/contrib/vertica/test_vertica.py +++ b/tests/contrib/vertica/test_vertica.py @@ -1,5 +1,4 @@ import pytest -import wrapt import ddtrace from ddtrace import config @@ -9,6 +8,7 @@ from ddtrace.constants import ERROR_TYPE from ddtrace.contrib.internal.vertica.patch import patch from ddtrace.contrib.internal.vertica.patch import unpatch +from ddtrace.internal.compat import is_wrapted from ddtrace.internal.schema import DEFAULT_SPAN_SERVICE_NAME from ddtrace.settings._config import _deepmerge from tests.contrib.config import VERTICA_CONFIG @@ -63,8 +63,8 @@ def test_patch_before_import(self): import vertica_python # use a patched method from each class as indicators - assert isinstance(vertica_python.Connection.cursor, wrapt.ObjectProxy) - assert isinstance(vertica_python.vertica.cursor.Cursor.execute, wrapt.ObjectProxy) + assert is_wrapted(vertica_python.Connection.cursor) + assert is_wrapted(vertica_python.vertica.cursor.Cursor.execute) def test_patch_after_import(self): """Patching _after_ the import will not work because we hook into @@ -78,8 +78,8 @@ def test_patch_after_import(self): import vertica_python - assert not isinstance(vertica_python.vertica.connection.Connection.cursor, wrapt.ObjectProxy) - assert not isinstance(vertica_python.vertica.cursor.Cursor.execute, wrapt.ObjectProxy) + assert not is_wrapted(vertica_python.vertica.connection.Connection.cursor) + assert not is_wrapted(vertica_python.vertica.cursor.Cursor.execute) patch() @@ -91,33 +91,33 @@ def test_patch_after_import(self): with mock_patch("vertica_python.connect", return_value=mock_conn): conn = vertica_python.connect() cursor = conn.cursor() - assert not isinstance(cursor, wrapt.ObjectProxy) + assert not is_wrapted(cursor) def test_idempotent_patch(self): patch() patch() import vertica_python - assert not isinstance(vertica_python.Connection.cursor.__wrapped__, wrapt.ObjectProxy) - assert not isinstance(vertica_python.vertica.cursor.Cursor.execute.__wrapped__, wrapt.ObjectProxy) - assert isinstance(vertica_python.Connection.cursor, wrapt.ObjectProxy) - assert isinstance(vertica_python.vertica.cursor.Cursor.execute, wrapt.ObjectProxy) + assert not is_wrapted(vertica_python.Connection.cursor.__wrapped__) + assert not is_wrapted(vertica_python.vertica.cursor.Cursor.execute.__wrapped__) + assert is_wrapted(vertica_python.Connection.cursor) + assert is_wrapted(vertica_python.vertica.cursor.Cursor.execute) def test_unpatch_before_import(self): patch() unpatch() import vertica_python - assert not isinstance(vertica_python.Connection.cursor, wrapt.ObjectProxy) - assert not isinstance(vertica_python.vertica.cursor.Cursor.execute, wrapt.ObjectProxy) + assert not is_wrapted(vertica_python.Connection.cursor) + assert not is_wrapted(vertica_python.vertica.cursor.Cursor.execute) def test_unpatch_after_import(self): patch() import vertica_python unpatch() - assert not isinstance(vertica_python.Connection.cursor, wrapt.ObjectProxy) - assert not isinstance(vertica_python.vertica.cursor.Cursor.execute, wrapt.ObjectProxy) + assert not is_wrapted(vertica_python.Connection.cursor) + assert not is_wrapted(vertica_python.vertica.cursor.Cursor.execute) @pytest.mark.usefixtures("test_tracer", "test_conn") diff --git a/tests/contrib/yaaredis/test_yaaredis.py b/tests/contrib/yaaredis/test_yaaredis.py index fd9fb02c0f4..472612f11ca 100644 --- a/tests/contrib/yaaredis/test_yaaredis.py +++ b/tests/contrib/yaaredis/test_yaaredis.py @@ -3,12 +3,12 @@ import uuid import pytest -from wrapt import ObjectProxy import yaaredis from ddtrace._trace.pin import Pin from ddtrace.contrib.internal.yaaredis.patch import patch from ddtrace.contrib.internal.yaaredis.patch import unpatch +from ddtrace.internal.compat import is_wrapted from tests.opentracer.utils import init_tracer from tests.utils import override_config @@ -37,17 +37,17 @@ def test_patching(): When unpatching yaaredis library We unwrap the correct methods """ - assert isinstance(yaaredis.client.StrictRedis.execute_command, ObjectProxy) - assert isinstance(yaaredis.client.StrictRedis.pipeline, ObjectProxy) - assert isinstance(yaaredis.pipeline.StrictPipeline.execute, ObjectProxy) - assert isinstance(yaaredis.pipeline.StrictPipeline.immediate_execute_command, ObjectProxy) + assert is_wrapted(yaaredis.client.StrictRedis.execute_command) + assert is_wrapted(yaaredis.client.StrictRedis.pipeline) + assert is_wrapted(yaaredis.pipeline.StrictPipeline.execute) + assert is_wrapted(yaaredis.pipeline.StrictPipeline.immediate_execute_command) unpatch() - assert not isinstance(yaaredis.client.StrictRedis.execute_command, ObjectProxy) - assert not isinstance(yaaredis.client.StrictRedis.pipeline, ObjectProxy) - assert not isinstance(yaaredis.pipeline.StrictPipeline.execute, ObjectProxy) - assert not isinstance(yaaredis.pipeline.StrictPipeline.immediate_execute_command, ObjectProxy) + assert not is_wrapted(yaaredis.client.StrictRedis.execute_command) + assert not is_wrapted(yaaredis.client.StrictRedis.pipeline) + assert not is_wrapted(yaaredis.pipeline.StrictPipeline.execute) + assert not is_wrapted(yaaredis.pipeline.StrictPipeline.immediate_execute_command) @pytest.mark.asyncio diff --git a/tests/internal/test_packages.py b/tests/internal/test_packages.py index 0253ed44e45..4bf3da31204 100644 --- a/tests/internal/test_packages.py +++ b/tests/internal/test_packages.py @@ -58,6 +58,11 @@ def test_get_distributions(): importlib_pkgs.add("importlib-resources") else: importlib_pkgs.add(name) + # Fix for last zope namespace changes + for sub in ["interface", "event"]: + if f"zope-{sub}" in pkg_resources_ws and f"zope.{sub}" in importlib_pkgs: + pkg_resources_ws.discard(f"zope-{sub}") + importlib_pkgs.discard(f"zope.{sub}") # assert that pkg_resources and importlib.metadata return the same packages assert pkg_resources_ws == importlib_pkgs diff --git a/tests/internal/test_safety.py b/tests/internal/test_safety.py index b759ca54480..7819b1a5333 100644 --- a/tests/internal/test_safety.py +++ b/tests/internal/test_safety.py @@ -68,7 +68,8 @@ def test_safe_eval_property(): def test_safe_collection(_type): # Ensure that all the items within a collection are wrapped by a safe object # proxy. - assert all(isinstance(_, SafeObjectProxy) for _ in SafeObjectProxy.safe(_type([UnsafeObject()] * 10))) + iterator = SafeObjectProxy.safe(_type([UnsafeObject()] * 10)) + assert all(isinstance(_, SafeObjectProxy) for _ in iterator) def test_safe_dict(): diff --git a/tests/internal/test_serverless.py b/tests/internal/test_serverless.py index 47858d2e6d6..d5147b20006 100644 --- a/tests/internal/test_serverless.py +++ b/tests/internal/test_serverless.py @@ -55,7 +55,8 @@ def test_not_azure_function(): "secrets", ] expanded_blocklist = standard_blocklist + [ - "importlib.metadata", + # wrapt 2.0 is importing importlib.metada + # "importlib.metadata", ]