Skip to content

Commit

Permalink
pythongh-106320: Remove private _PyMem API (python#107187)
Browse files Browse the repository at this point in the history
Move private _PyMem functions to the internal C API (pycore_pymem.h):

* _PyMem_GetCurrentAllocatorName()
* _PyMem_RawStrdup()
* _PyMem_RawWcsdup()
* _PyMem_Strdup()

No longer export these functions.

Move pymem_getallocatorsname() function from _testcapi to _testinternalcapi,
since the API moved to the internal C API.
  • Loading branch information
vstinner authored Jul 24, 2023
1 parent d27eb1e commit 3071867
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 35 deletions.
12 changes: 0 additions & 12 deletions Include/cpython/pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize);
PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size);
PyAPI_FUNC(void) PyMem_RawFree(void *ptr);

/* Try to get the allocators name set by _PyMem_SetupAllocators(). */
PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);

/* strdup() using PyMem_RawMalloc() */
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);

/* strdup() using PyMem_Malloc() */
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);

/* wcsdup() using PyMem_RawMalloc() */
PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str);


typedef enum {
/* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */
Expand Down
14 changes: 13 additions & 1 deletion Include/internal/pycore_pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,20 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#include "pymem.h" // PyMemAllocatorName
// Try to get the allocators name set by _PyMem_SetupAllocators().
// Return NULL if unknown.
// Export for shared _testinternalcapi extension.
PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);

// strdup() using PyMem_RawMalloc()
extern char* _PyMem_RawStrdup(const char *str);

// strdup() using PyMem_Malloc().
// Export for shared _pickle extension.
PyAPI_FUNC(char*) _PyMem_Strdup(const char *str);

// wcsdup() using PyMem_RawMalloc()
extern wchar_t* _PyMem_RawWcsdup(const wchar_t *str);

typedef struct {
/* We tag each block with an API ID in order to tag API violations */
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,11 +637,11 @@ def collect_decimal(info_add):

def collect_testcapi(info_add):
try:
import _testcapi
import _testinternalcapi
except ImportError:
return

call_func(info_add, 'pymem.allocator', _testcapi, 'pymem_getallocatorsname')
call_func(info_add, 'pymem.allocator', _testinternalcapi, 'pymem_getallocatorsname')


def collect_resource(info_add):
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_cmd_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,11 +717,11 @@ def test_xdev(self):

# Memory allocator debug hooks
try:
import _testcapi
import _testinternalcapi
except ImportError:
pass
else:
code = "import _testcapi; print(_testcapi.pymem_getallocatorsname())"
code = "import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())"
with support.SuppressCrashReport():
out = self.run_xdev("-c", code, check_exitcode=False)
if support.with_pymalloc():
Expand Down Expand Up @@ -783,7 +783,7 @@ def test_warnings_filter_precedence(self):
self.assertEqual(out, expected_filters)

def check_pythonmalloc(self, env_var, name):
code = 'import _testcapi; print(_testcapi.pymem_getallocatorsname())'
code = 'import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())'
env = dict(os.environ)
env.pop('PYTHONDEVMODE', None)
if env_var is not None:
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,12 +960,12 @@ def test_debugmallocstats(self):
"sys.getallocatedblocks unavailable on this build")
def test_getallocatedblocks(self):
try:
import _testcapi
import _testinternalcapi
except ImportError:
with_pymalloc = support.with_pymalloc()
else:
try:
alloc_name = _testcapi.pymem_getallocatorsname()
alloc_name = _testinternalcapi.pymem_getallocatorsname()
except RuntimeError as exc:
# "cannot get allocators name" (ex: tracemalloc is used)
with_pymalloc = True
Expand Down
12 changes: 0 additions & 12 deletions Modules/_testcapi/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,17 +440,6 @@ test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored))
Py_RETURN_NONE;
}

static PyObject *
test_pymem_getallocatorsname(PyObject *self, PyObject *args)
{
const char *name = _PyMem_GetCurrentAllocatorName();
if (name == NULL) {
PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name");
return NULL;
}
return PyUnicode_FromString(name);
}

static PyObject *
test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored))
{
Expand Down Expand Up @@ -589,7 +578,6 @@ tracemalloc_untrack(PyObject *self, PyObject *args)
static PyMethodDef test_methods[] = {
{"pymem_api_misuse", pymem_api_misuse, METH_NOARGS},
{"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS},
{"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS},
{"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS},
{"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS},
{"remove_mem_hooks", remove_mem_hooks, METH_NOARGS,
Expand Down
13 changes: 13 additions & 0 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,18 @@ check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args))
}


static PyObject *
test_pymem_getallocatorsname(PyObject *self, PyObject *args)
{
const char *name = _PyMem_GetCurrentAllocatorName();
if (name == NULL) {
PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name");
return NULL;
}
return PyUnicode_FromString(name);
}


static PyMethodDef module_functions[] = {
{"get_configs", get_configs, METH_NOARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
Expand Down Expand Up @@ -1581,6 +1593,7 @@ static PyMethodDef module_functions[] = {
{"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS},
{"check_pyobject_uninitialized_is_freed",
check_pyobject_uninitialized_is_freed, METH_NOARGS},
{"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS},
{NULL, NULL} /* sentinel */
};

Expand Down
8 changes: 5 additions & 3 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* Return the initial module search path. */

#include "Python.h"
#include "pycore_fileutils.h" // _Py_abspath()
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
#include "pycore_pathconfig.h" // _PyPathConfig_ReadGlobal()
#include "pycore_pymem.h" // _PyMem_RawWcsdup()

#include "marshal.h" // PyMarshal_ReadObjectFromString
#include "osdefs.h" // DELIM
#include "pycore_initconfig.h"
#include "pycore_fileutils.h"
#include "pycore_pathconfig.h"
#include <wchar.h>

#ifdef MS_WINDOWS
Expand Down

0 comments on commit 3071867

Please sign in to comment.