Skip to content

Commit aad88d3

Browse files
authored
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.
1 parent 4d03de3 commit aad88d3

File tree

10 files changed

+100
-77
lines changed

10 files changed

+100
-77
lines changed

Doc/whatsnew/3.11.rst

+5
Original file line numberDiff line numberDiff line change
@@ -644,3 +644,8 @@ Removed
644644

645645
Remove also the ``Py_MARSHAL_VERSION`` macro from the limited C API.
646646
(Contributed by Victor Stinner in :issue:`45474`.)
647+
648+
* Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
649+
worked since the :c:type:`PyWeakReference` structure is opaque in the
650+
limited C API.
651+
(Contributed by Victor Stinner in :issue:`35134`.)

Include/cpython/warnings.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef Py_CPYTHON_WARNINGS_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
PyAPI_FUNC(int) PyErr_WarnExplicitObject(
6+
PyObject *category,
7+
PyObject *message,
8+
PyObject *filename,
9+
int lineno,
10+
PyObject *module,
11+
PyObject *registry);
12+
13+
PyAPI_FUNC(int) PyErr_WarnExplicitFormat(
14+
PyObject *category,
15+
const char *filename, int lineno,
16+
const char *module, PyObject *registry,
17+
const char *format, ...);
18+
19+
// DEPRECATED: Use PyErr_WarnEx() instead.
20+
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)

Include/cpython/weakrefobject.h

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef Py_CPYTHON_WEAKREFOBJECT_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
6+
* and CallableProxyType.
7+
*/
8+
struct _PyWeakReference {
9+
PyObject_HEAD
10+
11+
/* The object to which this is a weak reference, or Py_None if none.
12+
* Note that this is a stealth reference: wr_object's refcount is
13+
* not incremented to reflect this pointer.
14+
*/
15+
PyObject *wr_object;
16+
17+
/* A callable to invoke when wr_object dies, or NULL if none. */
18+
PyObject *wr_callback;
19+
20+
/* A cache for wr_object's hash code. As usual for hashes, this is -1
21+
* if the hash code isn't known yet.
22+
*/
23+
Py_hash_t hash;
24+
25+
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
26+
* terminated list of weak references to it. These are the list pointers.
27+
* If wr_object goes away, wr_object is set to Py_None, and these pointers
28+
* have no meaning then.
29+
*/
30+
PyWeakReference *wr_prev;
31+
PyWeakReference *wr_next;
32+
};
33+
34+
PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
35+
36+
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
37+
38+
/* Explanation for the Py_REFCNT() check: when a weakref's target is part
39+
of a long chain of deallocations which triggers the trashcan mechanism,
40+
clearing the weakrefs can be delayed long after the target's refcount
41+
has dropped to zero. In the meantime, code accessing the weakref will
42+
be able to "see" the target object even though it is supposed to be
43+
unreachable. See issue #16602. */
44+
#define PyWeakref_GET_OBJECT(ref) \
45+
(Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
46+
? ((PyWeakReference *)(ref))->wr_object \
47+
: Py_None)

Include/internal/pycore_warnings.h

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ struct _warnings_runtime_state {
1919

2020
extern int _PyWarnings_InitState(PyInterpreterState *interp);
2121

22+
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
23+
24+
extern void _PyErr_WarnUnawaitedCoroutine(PyObject *coro);
25+
2226
#ifdef __cplusplus
2327
}
2428
#endif

Include/warnings.h

+5-27
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
extern "C" {
55
#endif
66

7-
#ifndef Py_LIMITED_API
8-
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
9-
#endif
10-
117
PyAPI_FUNC(int) PyErr_WarnEx(
128
PyObject *category,
139
const char *message, /* UTF-8 encoded string */
1410
Py_ssize_t stack_level);
11+
1512
PyAPI_FUNC(int) PyErr_WarnFormat(
1613
PyObject *category,
1714
Py_ssize_t stack_level,
@@ -26,15 +23,7 @@ PyAPI_FUNC(int) PyErr_ResourceWarning(
2623
const char *format, /* ASCII-encoded string */
2724
...);
2825
#endif
29-
#ifndef Py_LIMITED_API
30-
PyAPI_FUNC(int) PyErr_WarnExplicitObject(
31-
PyObject *category,
32-
PyObject *message,
33-
PyObject *filename,
34-
int lineno,
35-
PyObject *module,
36-
PyObject *registry);
37-
#endif
26+
3827
PyAPI_FUNC(int) PyErr_WarnExplicit(
3928
PyObject *category,
4029
const char *message, /* UTF-8 encoded string */
@@ -44,20 +33,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicit(
4433
PyObject *registry);
4534

4635
#ifndef Py_LIMITED_API
47-
PyAPI_FUNC(int)
48-
PyErr_WarnExplicitFormat(PyObject *category,
49-
const char *filename, int lineno,
50-
const char *module, PyObject *registry,
51-
const char *format, ...);
52-
#endif
53-
54-
/* DEPRECATED: Use PyErr_WarnEx() instead. */
55-
#ifndef Py_LIMITED_API
56-
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
57-
#endif
58-
59-
#ifndef Py_LIMITED_API
60-
void _PyErr_WarnUnawaitedCoroutine(PyObject *coro);
36+
# define Py_CPYTHON_WARNINGS_H
37+
# include "cpython/warnings.h"
38+
# undef Py_CPYTHON_WARNINGS_H
6139
#endif
6240

6341
#ifdef __cplusplus

Include/weakrefobject.h

+6-50
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,8 @@
66
extern "C" {
77
#endif
88

9-
109
typedef struct _PyWeakReference PyWeakReference;
1110

12-
/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
13-
* and CallableProxyType.
14-
*/
15-
#ifndef Py_LIMITED_API
16-
struct _PyWeakReference {
17-
PyObject_HEAD
18-
19-
/* The object to which this is a weak reference, or Py_None if none.
20-
* Note that this is a stealth reference: wr_object's refcount is
21-
* not incremented to reflect this pointer.
22-
*/
23-
PyObject *wr_object;
24-
25-
/* A callable to invoke when wr_object dies, or NULL if none. */
26-
PyObject *wr_callback;
27-
28-
/* A cache for wr_object's hash code. As usual for hashes, this is -1
29-
* if the hash code isn't known yet.
30-
*/
31-
Py_hash_t hash;
32-
33-
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
34-
* terminated list of weak references to it. These are the list pointers.
35-
* If wr_object goes away, wr_object is set to Py_None, and these pointers
36-
* have no meaning then.
37-
*/
38-
PyWeakReference *wr_prev;
39-
PyWeakReference *wr_next;
40-
};
41-
#endif
42-
4311
PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
4412
PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
4513
PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
@@ -56,30 +24,18 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType;
5624

5725

5826
PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
59-
PyObject *callback);
27+
PyObject *callback);
6028
PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
61-
PyObject *callback);
29+
PyObject *callback);
6230
PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
6331

64-
#ifndef Py_LIMITED_API
65-
PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
6632

67-
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
33+
#ifndef Py_LIMITED_API
34+
# define Py_CPYTHON_WEAKREFOBJECT_H
35+
# include "cpython/weakrefobject.h"
36+
# undef Py_CPYTHON_WEAKREFOBJECT_H
6837
#endif
6938

70-
/* Explanation for the Py_REFCNT() check: when a weakref's target is part
71-
of a long chain of deallocations which triggers the trashcan mechanism,
72-
clearing the weakrefs can be delayed long after the target's refcount
73-
has dropped to zero. In the meantime, code accessing the weakref will
74-
be able to "see" the target object even though it is supposed to be
75-
unreachable. See issue #16602. */
76-
77-
#define PyWeakref_GET_OBJECT(ref) \
78-
(Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
79-
? ((PyWeakReference *)(ref))->wr_object \
80-
: Py_None)
81-
82-
8339
#ifdef __cplusplus
8440
}
8541
#endif

Makefile.pre.in

+2
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,8 @@ PYTHON_HEADERS= \
12281228
$(srcdir)/Include/cpython/traceback.h \
12291229
$(srcdir)/Include/cpython/tupleobject.h \
12301230
$(srcdir)/Include/cpython/unicodeobject.h \
1231+
$(srcdir)/Include/cpython/warnings.h \
1232+
$(srcdir)/Include/cpython/weakrefobject.h \
12311233
\
12321234
$(srcdir)/Include/internal/pycore_abstract.h \
12331235
$(srcdir)/Include/internal/pycore_accu.h \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
2+
worked since the :c:type:`PyWeakReference` structure is opaque in the
3+
limited C API.

PCbuild/pythoncore.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@
160160
<ClInclude Include="..\Include\cpython\traceback.h" />
161161
<ClInclude Include="..\Include\cpython\tupleobject.h" />
162162
<ClInclude Include="..\Include\cpython\unicodeobject.h" />
163+
<ClInclude Include="..\Include\cpython\warnings.h" />
164+
<ClInclude Include="..\Include\cpython\weakrefobject.h" />
163165
<ClInclude Include="..\Include\datetime.h" />
164166
<ClInclude Include="..\Include\descrobject.h" />
165167
<ClInclude Include="..\Include\dictobject.h" />

PCbuild/pythoncore.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,12 @@
393393
<ClInclude Include="..\Include\cpython\unicodeobject.h">
394394
<Filter>Include\cpython</Filter>
395395
</ClInclude>
396+
<ClInclude Include="..\Include\cpython\warnings.h">
397+
<Filter>Include\cpython</Filter>
398+
</ClInclude>
399+
<ClInclude Include="..\Include\cpython\weakrefobject.h">
400+
<Filter>Include\cpython</Filter>
401+
</ClInclude>
396402
<ClInclude Include="..\Include\cpython\methodobject.h">
397403
<Filter>Include\cpython</Filter>
398404
</ClInclude>

0 commit comments

Comments
 (0)