Skip to content
Open
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
9 changes: 9 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ jobs:
os: ubuntu-24.04
- wheel: cp313-manylinux
os: ubuntu-24.04
- wheel: cp313t-manylinux
os: ubuntu-24.04
- wheel: cp314-manylinux
os: ubuntu-24.04
- wheel: cp314t-manylinux
os: ubuntu-24.04
# Linux musllibc
- wheel: cp38-musllinux
os: ubuntu-24.04
Expand All @@ -56,8 +60,12 @@ jobs:
os: ubuntu-24.04
- wheel: cp313-musllinux
os: ubuntu-24.04
- wheel: cp313t-musllinux
os: ubuntu-24.04
- wheel: cp314-musllinux
os: ubuntu-24.04
- wheel: cp314t-musllinux
os: ubuntu-24.04
# Windows
# Windows wheels won't but published until the full release announcement.
# - wheel: cp313-win
Expand Down Expand Up @@ -89,6 +97,7 @@ jobs:
CIBW_ARCHS_MACOS: native
CIBW_ARCHS_WINDOWS: AMD64 ARM64
CIBW_ENVIRONMENT_LINUX: "LD_LIBRARY_PATH=/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/usr/local/lib64:/usr/local/lib"
CIBW_ENABLE: cpython-freethreading
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND_LINUX: "export PYTHONPATH={project}/tests; pytest {project}/tests/agent_unittests -vx"
CIBW_TEST_COMMAND_MACOS: "export PYTHONPATH={project}/tests; pytest {project}/tests/agent_unittests -vx"
Expand Down
11 changes: 8 additions & 3 deletions newrelic/common/object_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@

import inspect

from newrelic.packages.wrapt import ( # noqa: F401
BaseObjectProxy,
apply_patch,
resolve_path,
wrap_object,
wrap_object_attribute,
)
from newrelic.packages.wrapt import BoundFunctionWrapper as _BoundFunctionWrapper
from newrelic.packages.wrapt import CallableObjectProxy as _CallableObjectProxy
from newrelic.packages.wrapt import FunctionWrapper as _FunctionWrapper
from newrelic.packages.wrapt import ObjectProxy as _ObjectProxy
from newrelic.packages.wrapt import apply_patch, resolve_path, wrap_object, wrap_object_attribute # noqa: F401

# We previously had our own pure Python implementation of the generic
# object wrapper but we now defer to using the wrapt module as its C
Expand All @@ -44,7 +49,7 @@
# ObjectProxy or FunctionWrapper should be used going forward.


class ObjectProxy(_ObjectProxy):
class ObjectProxy(BaseObjectProxy):
"""
This class provides method overrides for all object wrappers used by the
agent. These methods allow attributes to be defined with the special prefix
Expand Down
13 changes: 7 additions & 6 deletions newrelic/core/_thread_utilization.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,10 @@ static PyObject *NRUtilization_new(PyTypeObject *type,
return NULL;

/*
* XXX Using a mutex for now just in case the calls to get
* the current thread are causing release of GIL in a
* multithreaded context. May explain why having issues with
* object referred to by weakrefs being corrupted. The GIL
* should technically be enough to protect us here.
* Using a mutex to ensure this is compatible with free threaded Python interpreters.
* In the past, this relied on the GIL for thread safety with weakrefs but that was
* not reliable enough anyway.
*/

self->thread_mutex = PyThread_allocate_lock();

self->set_of_all_threads = PyDict_New();
Expand Down Expand Up @@ -455,6 +452,10 @@ moduleinit(void)
PyModule_AddObject(module, "ThreadUtilization",
(PyObject *)&NRUtilization_Type);

#ifdef Py_GIL_DISABLED
PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
#endif

return module;
}

Expand Down
3 changes: 3 additions & 0 deletions newrelic/hooks/database_dbapi2.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def callproc(self, procname, parameters=DEFAULT):
else:
return self.__wrapped__.callproc(procname)

def __iter__(self):
return iter(self.__wrapped__)


class ConnectionWrapper(ObjectProxy):
__cursor_wrapper__ = CursorWrapper
Expand Down
2 changes: 1 addition & 1 deletion newrelic/packages/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
# to the New Relic Python Agent's dependencies in newrelic/packages/.
opentelemetry_proto==1.32.1
urllib3==1.26.19
wrapt==1.16.0
wrapt==2.0.0
asgiref==3.6.0 # We only vendor asgiref.compatibility.py
89 changes: 61 additions & 28 deletions newrelic/packages/wrapt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,63 @@
__version_info__ = ('1', '16', '0')
__version__ = '.'.join(__version_info__)

from .__wrapt__ import (ObjectProxy, CallableObjectProxy, FunctionWrapper,
BoundFunctionWrapper, PartialCallableObjectProxy)

from .patches import (resolve_path, apply_patch, wrap_object, wrap_object_attribute,
function_wrapper, wrap_function_wrapper, patch_function_wrapper,
transient_function_wrapper)

"""
Wrapt is a library for decorators, wrappers and monkey patching.
"""

__version_info__ = ("2", "0", "0")
__version__ = ".".join(__version_info__)

from .__wrapt__ import (
BaseObjectProxy,
BoundFunctionWrapper,
CallableObjectProxy,
FunctionWrapper,
PartialCallableObjectProxy,
partial,
)
from .decorators import AdapterFactory, adapter_factory, decorator, synchronized
from .importer import (
discover_post_import_hooks,
notify_module_loaded,
register_post_import_hook,
when_imported,
)
from .patches import (
apply_patch,
function_wrapper,
patch_function_wrapper,
resolve_path,
transient_function_wrapper,
wrap_function_wrapper,
wrap_object,
wrap_object_attribute,
)
from .proxies import AutoObjectProxy, LazyObjectProxy, ObjectProxy, lazy_import
from .weakrefs import WeakFunctionProxy

from .decorators import (adapter_factory, AdapterFactory, decorator,
synchronized)

from .importer import (register_post_import_hook, when_imported,
notify_module_loaded, discover_post_import_hooks)

# Import of inspect.getcallargs() included for backward compatibility. An
# implementation of this was previously bundled and made available here for
# Python <2.7. Avoid using this in future.

from inspect import getcallargs

# Variant of inspect.formatargspec() included here for forward compatibility.
# This is being done because Python 3.11 dropped inspect.formatargspec() but
# code for handling signature changing decorators relied on it. Exposing the
# bundled implementation here in case any user of wrapt was also needing it.

from .arguments import formatargspec
__all__ = (
"AutoObjectProxy",
"BaseObjectProxy",
"BoundFunctionWrapper",
"CallableObjectProxy",
"FunctionWrapper",
"LazyObjectProxy",
"ObjectProxy",
"PartialCallableObjectProxy",
"partial",
"AdapterFactory",
"adapter_factory",
"decorator",
"synchronized",
"discover_post_import_hooks",
"notify_module_loaded",
"register_post_import_hook",
"when_imported",
"apply_patch",
"function_wrapper",
"patch_function_wrapper",
"resolve_path",
"transient_function_wrapper",
"wrap_function_wrapper",
"wrap_object",
"wrap_object_attribute",
"WeakFunctionProxy",
)
Loading
Loading