Skip to content

Commit

Permalink
Add Python 3.13 compatibility
Browse files Browse the repository at this point in the history
- Use the new `PyEval_SetProfileAllThreads` public function, instead of
  our hacky backport of it.
- Handle `_Py_IsFinalizing` being promoted to a public API.
- Handle the prototype for `_PyMem_GetCurrentAllocatorName` being
  removed.

Signed-off-by: Matt Wozniski <[email protected]>
  • Loading branch information
godlygeek authored and pablogsal committed Jun 14, 2024
1 parent 88aa01a commit 19ab5ff
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 5 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ def build_js_files(self):
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development :: Debuggers",
],
Expand Down
11 changes: 7 additions & 4 deletions src/memray/_memray/compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ void
setprofileAllThreads(Py_tracefunc func, PyObject* arg)
{
assert(PyGILState_Check());

#if PY_VERSION_HEX >= 0x030D0000
PyEval_SetProfileAllThreads(func, arg);
#else
PyThreadState* this_tstate = PyThreadState_Get();
PyInterpreterState* interp = threadStateGetInterpreter(this_tstate);
for (PyThreadState* tstate = PyInterpreterState_ThreadHead(interp); tstate != nullptr;
tstate = PyThreadState_Next(tstate))
{
#if PY_VERSION_HEX >= 0x03090000
# if PY_VERSION_HEX >= 0x03090000
if (_PyEval_SetProfile(tstate, func, arg) < 0) {
_PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", nullptr);
}
#else
# else
// For 3.7 and 3.8, backport _PyEval_SetProfile from 3.9
// https://github.com/python/cpython/blob/v3.9.13/Python/ceval.c#L4738-L4767
PyObject* profileobj = tstate->c_profileobj;
Expand All @@ -33,8 +35,9 @@ setprofileAllThreads(Py_tracefunc func, PyObject* arg)

/* Flag that tracing or profiling is turned on */
tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
#endif
# endif
}
#endif
}

} // namespace memray::compat
10 changes: 10 additions & 0 deletions src/memray/_memray/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@

namespace memray::compat {

inline int
isPythonFinalizing()
{
#if PY_VERSION_HEX >= 0x030D0000
return Py_IsFinalizing();
#else
return _Py_IsFinalizing();
#endif
}

inline bool
isEntryFrame(PyFrameObject* frame)
{
Expand Down
6 changes: 6 additions & 0 deletions src/memray/_memray/record_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
#include "records.h"
#include "snapshot.h"

#if PY_VERSION_HEX >= 0x030D0000
// This function still exists in 3.13 but Python.h no longer has its prototype.
extern "C" const char*
_PyMem_GetCurrentAllocatorName();
#endif

namespace memray::tracking_api {

using namespace std::chrono;
Expand Down
2 changes: 1 addition & 1 deletion src/memray/_memray/tracking_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ Tracker::~Tracker()
d_patcher.restore_symbols();
}

if (Py_IsInitialized() && !_Py_IsFinalizing()) {
if (Py_IsInitialized() && !compat::isPythonFinalizing()) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

Expand Down

0 comments on commit 19ab5ff

Please sign in to comment.