bpo-35134: Split warnings.h and weakrefobject.h (GH-29042)

Split header files to move the non-limited API to Include/cpython/:

* Include/warnings.h => Include/cpython/warnings.h
* Include/weakrefobject.h => Include/cpython/weakrefobject.h

Exclude PyWeakref_GET_OBJECT() from the limited C API. It never
worked since the PyWeakReference structure is opaque in the limited C
API.

Move _PyWarnings_Init() and _PyErr_WarnUnawaitedCoroutine() to the
internal C API.
This commit is contained in:
Victor Stinner 2021-10-19 01:31:57 +02:00 committed by GitHub
parent 4d03de3329
commit aad88d33d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 100 additions and 77 deletions

View File

@ -644,3 +644,8 @@ Removed
Remove also the ``Py_MARSHAL_VERSION`` macro from the limited C API. Remove also the ``Py_MARSHAL_VERSION`` macro from the limited C API.
(Contributed by Victor Stinner in :issue:`45474`.) (Contributed by Victor Stinner in :issue:`45474`.)
* Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
worked since the :c:type:`PyWeakReference` structure is opaque in the
limited C API.
(Contributed by Victor Stinner in :issue:`35134`.)

View File

@ -0,0 +1,20 @@
#ifndef Py_CPYTHON_WARNINGS_H
# error "this header file must not be included directly"
#endif
PyAPI_FUNC(int) PyErr_WarnExplicitObject(
PyObject *category,
PyObject *message,
PyObject *filename,
int lineno,
PyObject *module,
PyObject *registry);
PyAPI_FUNC(int) PyErr_WarnExplicitFormat(
PyObject *category,
const char *filename, int lineno,
const char *module, PyObject *registry,
const char *format, ...);
// DEPRECATED: Use PyErr_WarnEx() instead.
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)

View File

@ -0,0 +1,47 @@
#ifndef Py_CPYTHON_WEAKREFOBJECT_H
# error "this header file must not be included directly"
#endif
/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
* and CallableProxyType.
*/
struct _PyWeakReference {
PyObject_HEAD
/* The object to which this is a weak reference, or Py_None if none.
* Note that this is a stealth reference: wr_object's refcount is
* not incremented to reflect this pointer.
*/
PyObject *wr_object;
/* A callable to invoke when wr_object dies, or NULL if none. */
PyObject *wr_callback;
/* A cache for wr_object's hash code. As usual for hashes, this is -1
* if the hash code isn't known yet.
*/
Py_hash_t hash;
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
* terminated list of weak references to it. These are the list pointers.
* If wr_object goes away, wr_object is set to Py_None, and these pointers
* have no meaning then.
*/
PyWeakReference *wr_prev;
PyWeakReference *wr_next;
};
PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
/* Explanation for the Py_REFCNT() check: when a weakref's target is part
of a long chain of deallocations which triggers the trashcan mechanism,
clearing the weakrefs can be delayed long after the target's refcount
has dropped to zero. In the meantime, code accessing the weakref will
be able to "see" the target object even though it is supposed to be
unreachable. See issue #16602. */
#define PyWeakref_GET_OBJECT(ref) \
(Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
? ((PyWeakReference *)(ref))->wr_object \
: Py_None)

View File

@ -19,6 +19,10 @@ struct _warnings_runtime_state {
extern int _PyWarnings_InitState(PyInterpreterState *interp); extern int _PyWarnings_InitState(PyInterpreterState *interp);
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
extern void _PyErr_WarnUnawaitedCoroutine(PyObject *coro);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -4,14 +4,11 @@
extern "C" { extern "C" {
#endif #endif
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
#endif
PyAPI_FUNC(int) PyErr_WarnEx( PyAPI_FUNC(int) PyErr_WarnEx(
PyObject *category, PyObject *category,
const char *message, /* UTF-8 encoded string */ const char *message, /* UTF-8 encoded string */
Py_ssize_t stack_level); Py_ssize_t stack_level);
PyAPI_FUNC(int) PyErr_WarnFormat( PyAPI_FUNC(int) PyErr_WarnFormat(
PyObject *category, PyObject *category,
Py_ssize_t stack_level, Py_ssize_t stack_level,
@ -26,15 +23,7 @@ PyAPI_FUNC(int) PyErr_ResourceWarning(
const char *format, /* ASCII-encoded string */ const char *format, /* ASCII-encoded string */
...); ...);
#endif #endif
#ifndef Py_LIMITED_API
PyAPI_FUNC(int) PyErr_WarnExplicitObject(
PyObject *category,
PyObject *message,
PyObject *filename,
int lineno,
PyObject *module,
PyObject *registry);
#endif
PyAPI_FUNC(int) PyErr_WarnExplicit( PyAPI_FUNC(int) PyErr_WarnExplicit(
PyObject *category, PyObject *category,
const char *message, /* UTF-8 encoded string */ const char *message, /* UTF-8 encoded string */
@ -44,20 +33,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicit(
PyObject *registry); PyObject *registry);
#ifndef Py_LIMITED_API #ifndef Py_LIMITED_API
PyAPI_FUNC(int) # define Py_CPYTHON_WARNINGS_H
PyErr_WarnExplicitFormat(PyObject *category, # include "cpython/warnings.h"
const char *filename, int lineno, # undef Py_CPYTHON_WARNINGS_H
const char *module, PyObject *registry,
const char *format, ...);
#endif
/* DEPRECATED: Use PyErr_WarnEx() instead. */
#ifndef Py_LIMITED_API
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
#endif
#ifndef Py_LIMITED_API
void _PyErr_WarnUnawaitedCoroutine(PyObject *coro);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -6,40 +6,8 @@
extern "C" { extern "C" {
#endif #endif
typedef struct _PyWeakReference PyWeakReference; typedef struct _PyWeakReference PyWeakReference;
/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
* and CallableProxyType.
*/
#ifndef Py_LIMITED_API
struct _PyWeakReference {
PyObject_HEAD
/* The object to which this is a weak reference, or Py_None if none.
* Note that this is a stealth reference: wr_object's refcount is
* not incremented to reflect this pointer.
*/
PyObject *wr_object;
/* A callable to invoke when wr_object dies, or NULL if none. */
PyObject *wr_callback;
/* A cache for wr_object's hash code. As usual for hashes, this is -1
* if the hash code isn't known yet.
*/
Py_hash_t hash;
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
* terminated list of weak references to it. These are the list pointers.
* If wr_object goes away, wr_object is set to Py_None, and these pointers
* have no meaning then.
*/
PyWeakReference *wr_prev;
PyWeakReference *wr_next;
};
#endif
PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
@ -56,30 +24,18 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
PyObject *callback); PyObject *callback);
PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
PyObject *callback); PyObject *callback);
PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
#ifndef Py_LIMITED_API #ifndef Py_LIMITED_API
PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); # define Py_CPYTHON_WEAKREFOBJECT_H
# include "cpython/weakrefobject.h"
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); # undef Py_CPYTHON_WEAKREFOBJECT_H
#endif #endif
/* Explanation for the Py_REFCNT() check: when a weakref's target is part
of a long chain of deallocations which triggers the trashcan mechanism,
clearing the weakrefs can be delayed long after the target's refcount
has dropped to zero. In the meantime, code accessing the weakref will
be able to "see" the target object even though it is supposed to be
unreachable. See issue #16602. */
#define PyWeakref_GET_OBJECT(ref) \
(Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
? ((PyWeakReference *)(ref))->wr_object \
: Py_None)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1228,6 +1228,8 @@ PYTHON_HEADERS= \
$(srcdir)/Include/cpython/traceback.h \ $(srcdir)/Include/cpython/traceback.h \
$(srcdir)/Include/cpython/tupleobject.h \ $(srcdir)/Include/cpython/tupleobject.h \
$(srcdir)/Include/cpython/unicodeobject.h \ $(srcdir)/Include/cpython/unicodeobject.h \
$(srcdir)/Include/cpython/warnings.h \
$(srcdir)/Include/cpython/weakrefobject.h \
\ \
$(srcdir)/Include/internal/pycore_abstract.h \ $(srcdir)/Include/internal/pycore_abstract.h \
$(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_accu.h \

View File

@ -0,0 +1,3 @@
Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
worked since the :c:type:`PyWeakReference` structure is opaque in the
limited C API.

View File

@ -160,6 +160,8 @@
<ClInclude Include="..\Include\cpython\traceback.h" /> <ClInclude Include="..\Include\cpython\traceback.h" />
<ClInclude Include="..\Include\cpython\tupleobject.h" /> <ClInclude Include="..\Include\cpython\tupleobject.h" />
<ClInclude Include="..\Include\cpython\unicodeobject.h" /> <ClInclude Include="..\Include\cpython\unicodeobject.h" />
<ClInclude Include="..\Include\cpython\warnings.h" />
<ClInclude Include="..\Include\cpython\weakrefobject.h" />
<ClInclude Include="..\Include\datetime.h" /> <ClInclude Include="..\Include\datetime.h" />
<ClInclude Include="..\Include\descrobject.h" /> <ClInclude Include="..\Include\descrobject.h" />
<ClInclude Include="..\Include\dictobject.h" /> <ClInclude Include="..\Include\dictobject.h" />

View File

@ -393,6 +393,12 @@
<ClInclude Include="..\Include\cpython\unicodeobject.h"> <ClInclude Include="..\Include\cpython\unicodeobject.h">
<Filter>Include\cpython</Filter> <Filter>Include\cpython</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\cpython\warnings.h">
<Filter>Include\cpython</Filter>
</ClInclude>
<ClInclude Include="..\Include\cpython\weakrefobject.h">
<Filter>Include\cpython</Filter>
</ClInclude>
<ClInclude Include="..\Include\cpython\methodobject.h"> <ClInclude Include="..\Include\cpython\methodobject.h">
<Filter>Include\cpython</Filter> <Filter>Include\cpython</Filter>
</ClInclude> </ClInclude>