Skip to content

Commit

Permalink
gh-128863: Deprecate private C API functions (#128864)
Browse files Browse the repository at this point in the history
Deprecate private C API functions:

* _PyBytes_Join()
* _PyDict_GetItemStringWithError()
* _PyDict_Pop()
* _PyThreadState_UncheckedGet()
* _PyUnicode_AsString()
* _Py_HashPointer()
* _Py_fopen_obj()

Replace _Py_HashPointer() with Py_HashPointer().

Remove references to deprecated functions.
  • Loading branch information
vstinner authored Jan 22, 2025
1 parent 470a0a6 commit 9012fa7
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 30 deletions.
16 changes: 16 additions & 0 deletions Doc/deprecations/c-api-pending-removal-in-3.18.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Pending removal in Python 3.18
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* Deprecated private functions (:gh:`128863`):

* :c:func:`!_PyBytes_Join`: use :c:func:`PyBytes_Join`.
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
* :c:func:`!_PyDict_Pop()`: :c:func:`PyDict_Pop`.
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.
* :c:func:`!_Py_fopen_obj`: use :c:func:`Py_fopen`.

The `pythoncapi-compat project
<https://github.com/python/pythoncapi-compat/>`__ can be used to get these
new public functions on Python 3.13 and older.
19 changes: 19 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1376,12 +1376,31 @@ Deprecated
.. include:: ../deprecations/c-api-pending-removal-in-3.15.rst

.. include:: ../deprecations/c-api-pending-removal-in-3.18.rst

.. include:: ../deprecations/c-api-pending-removal-in-future.rst

* The ``PyMonitoring_FireBranchEvent`` function is deprecated and should
be replaced with calls to :c:func:`PyMonitoring_FireBranchLeftEvent`
and :c:func:`PyMonitoring_FireBranchRightEvent`.

* The following private functions are deprecated and planned for removal in
Python 3.18:

* :c:func:`!_PyBytes_Join`: use :c:func:`PyBytes_Join`.
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
* :c:func:`!_PyDict_Pop()`: use :c:func:`PyDict_Pop`.
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.
* :c:func:`!_Py_fopen_obj`: use :c:func:`Py_fopen`.

The `pythoncapi-compat project`_ can be used to get these new public
functions on Python 3.13 and older.

(Contributed by Victor Stinner in :gh:`128863`.)


Removed
-------

Expand Down
8 changes: 6 additions & 2 deletions Include/cpython/bytesobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,9 @@ static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) {

PyAPI_FUNC(PyObject*) PyBytes_Join(PyObject *sep, PyObject *iterable);

// Alias kept for backward compatibility
#define _PyBytes_Join PyBytes_Join
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline PyObject*
_PyBytes_Join(PyObject *sep, PyObject *iterable)
{
return PyBytes_Join(sep, iterable);
}
7 changes: 6 additions & 1 deletion Include/cpython/dictobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);

PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);

// Use PyDict_Pop() instead
Py_DEPRECATED(3.14) PyAPI_FUNC(PyObject *) _PyDict_Pop(
PyObject *dict,
PyObject *key,
PyObject *default_value);

/* Dictionary watchers */

Expand Down
10 changes: 6 additions & 4 deletions Include/cpython/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ PyAPI_FUNC(FILE*) Py_fopen(
PyObject *path,
const char *mode);

// Deprecated alias to Py_fopen() kept for backward compatibility
Py_DEPRECATED(3.14) PyAPI_FUNC(FILE*) _Py_fopen_obj(
PyObject *path,
const char *mode);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline FILE*
_Py_fopen_obj(PyObject *path, const char *mode)
{
return Py_fopen(path, mode);
}

PyAPI_FUNC(int) Py_fclose(FILE *file);
11 changes: 8 additions & 3 deletions Include/cpython/pyhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
/* Helpers for hash functions */
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double);

// Kept for backward compatibility
#define _Py_HashPointer Py_HashPointer


/* hash function definition */
typedef struct {
Expand All @@ -44,6 +41,14 @@ typedef struct {
PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);

PyAPI_FUNC(Py_hash_t) Py_HashPointer(const void *ptr);

// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline Py_hash_t
_Py_HashPointer(const void *ptr)
{
return Py_HashPointer(ptr);
}

PyAPI_FUNC(Py_hash_t) PyObject_GenericHash(PyObject *);

PyAPI_FUNC(Py_hash_t) Py_HashBuffer(const void *ptr, Py_ssize_t len);
8 changes: 6 additions & 2 deletions Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,12 @@ struct _ts {
* if it is NULL. */
PyAPI_FUNC(PyThreadState *) PyThreadState_GetUnchecked(void);

// Alias kept for backward compatibility
#define _PyThreadState_UncheckedGet PyThreadState_GetUnchecked
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline PyThreadState*
_PyThreadState_UncheckedGet(void)
{
return PyThreadState_GetUnchecked();
}


// Disable tracing and profiling.
Expand Down
8 changes: 6 additions & 2 deletions Include/cpython/unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,12 @@ _PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer);

PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode);

// Alias kept for backward compatibility
#define _PyUnicode_AsString PyUnicode_AsUTF8
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline const char*
_PyUnicode_AsString(PyObject *unicode)
{
return PyUnicode_AsUTF8(unicode);
}


/* === Characters Type APIs =============================================== */
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/audit-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class C(A):


def test_open(testfn):
# SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open()
# SSLContext.load_dh_params uses Py_fopen() rather than normal open()
try:
import ssl

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
The following private functions are deprecated and planned for removal in
Python 3.18:

* :c:func:`!_PyBytes_Join`: use :c:func:`PyBytes_Join`.
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
* :c:func:`!_PyDict_Pop()`: use :c:func:`PyDict_Pop`.
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.
* :c:func:`!_Py_fopen_obj`: use :c:func:`Py_fopen`.

The `pythoncapi-compat project
<https://github.com/python/pythoncapi-compat/>`__ can be used to get these new
public functions on Python 3.13 and older.

Patch by Victor Stinner.
2 changes: 1 addition & 1 deletion Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,7 @@ wrapper_hash(PyObject *self)
wrapperobject *wp = (wrapperobject *)self;
Py_hash_t x, y;
x = PyObject_GenericHash(wp->self);
y = _Py_HashPointer(wp->descr);
y = Py_HashPointer(wp->descr);
x = x ^ y;
if (x == -1)
x = -2;
Expand Down
12 changes: 9 additions & 3 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3090,8 +3090,8 @@ PyDict_PopString(PyObject *op, const char *key, PyObject **result)
}


PyObject *
_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value)
static PyObject *
dict_pop_default(PyObject *dict, PyObject *key, PyObject *default_value)
{
PyObject *result;
if (PyDict_Pop(dict, key, &result) == 0) {
Expand All @@ -3104,6 +3104,12 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value)
return result;
}

PyObject *
_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value)
{
return dict_pop_default(dict, key, default_value);
}

static PyDictObject *
dict_dict_fromkeys(PyInterpreterState *interp, PyDictObject *mp,
PyObject *iterable, PyObject *value)
Expand Down Expand Up @@ -4465,7 +4471,7 @@ static PyObject *
dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
/*[clinic end generated code: output=3abb47b89f24c21c input=e221baa01044c44c]*/
{
return _PyDict_Pop((PyObject*)self, key, default_value);
return dict_pop_default((PyObject*)self, key, default_value);
}

/*[clinic input]
Expand Down
2 changes: 1 addition & 1 deletion Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ meth_hash(PyObject *self)
{
PyCFunctionObject *a = _PyCFunctionObject_CAST(self);
Py_hash_t x = PyObject_GenericHash(a->m_self);
Py_hash_t y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
Py_hash_t y = Py_HashPointer((void*)(a->m_ml->ml_meth));
x ^= y;
if (x == -1) {
x = -2;
Expand Down
2 changes: 1 addition & 1 deletion Objects/odictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ mp_length __len__ - dict_length
mp_subscript __getitem__ - dict_subscript
mp_ass_subscript __setitem__ - dict_ass_sub
__delitem__
tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
tp_hash __hash__ Py_HashPointer ..._HashNotImpl
tp_str __str__ object_str -
tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
__getattr__
Expand Down
2 changes: 1 addition & 1 deletion Python/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ contextvar_generate_hash(void *addr, PyObject *name)
return -1;
}

Py_hash_t res = _Py_HashPointer(addr) ^ name_hash;
Py_hash_t res = Py_HashPointer(addr) ^ name_hash;
return res == -1 ? -2 : res;
}

Expand Down
8 changes: 0 additions & 8 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1842,14 +1842,6 @@ Py_fopen(PyObject *path, const char *mode)
}


// Deprecated alias to Py_fopen() kept for backward compatibility
FILE*
_Py_fopen_obj(PyObject *path, const char *mode)
{
return Py_fopen(path, mode);
}


// Call fclose().
//
// On Windows, files opened by Py_fopen() in the Python DLL must be closed by
Expand Down

0 comments on commit 9012fa7

Please sign in to comment.