From ec091bd47e2f968b0d1631b9a8104283a7beeb1b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 24 Feb 2022 17:07:12 +0100 Subject: bpo-45459: Add pytypedefs.h header file (GH-31527) Move forward declarations of Python C API types to a new pytypedefs.h header file to solve interdependency issues between header files. pytypedefs.h contains forward declarations of the following types: * PyCodeObject * PyFrameObject * PyGetSetDef * PyInterpreterState * PyLongObject * PyMemberDef * PyMethodDef * PyModuleDef * PyObject * PyThreadState * PyTypeObject --- Include/Python.h | 1 + Include/code.h | 2 -- Include/cpython/object.h | 5 ----- Include/descrobject.h | 4 ++-- Include/longobject.h | 2 -- Include/methodobject.h | 1 - Include/moduleobject.h | 4 ++-- Include/object.h | 11 +++-------- Include/pybuffer.h | 4 ---- Include/pyframe.h | 2 -- Include/pystate.h | 10 ---------- Include/pytypedefs.h | 29 +++++++++++++++++++++++++++++ Include/structmember.h | 4 ++-- Makefile.pre.in | 1 + PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 +++ 16 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 Include/pytypedefs.h diff --git a/Include/Python.h b/Include/Python.h index 5bc8cc6..4dc2edb 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -39,6 +39,7 @@ #include "pymacro.h" #include "pymath.h" #include "pymem.h" +#include "pytypedefs.h" #include "pybuffer.h" #include "object.h" #include "objimpl.h" diff --git a/Include/code.h b/Include/code.h index 2dea3c2..0245c32 100644 --- a/Include/code.h +++ b/Include/code.h @@ -6,8 +6,6 @@ extern "C" { #endif -typedef struct PyCodeObject PyCodeObject; - #ifndef Py_LIMITED_API # define Py_CPYTHON_CODE_H # include "cpython/code.h" diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 6cc3d72..65d7d85 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -262,10 +262,8 @@ PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); -struct PyModuleDef; PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, struct PyModuleDef *); -struct _Py_Identifier; PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); @@ -462,9 +460,6 @@ partially-deallocated object. To check this, the tp_dealloc function must be passed as second argument to Py_TRASHCAN_BEGIN(). */ -/* Forward declarations for PyThreadState */ -struct _ts; - /* Python 3.9 private API, invoked by the macros below. */ PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); diff --git a/Include/descrobject.h b/Include/descrobject.h index 36802f4..aefa760 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -8,13 +8,13 @@ extern "C" { typedef PyObject *(*getter)(PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *); -typedef struct PyGetSetDef { +struct PyGetSetDef { const char *name; getter get; setter set; const char *doc; void *closure; -} PyGetSetDef; +}; PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; diff --git a/Include/longobject.h b/Include/longobject.h index 7fe8f58..81ba123 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -7,8 +7,6 @@ extern "C" { /* Long (arbitrary precision) integer object interface */ -typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ - PyAPI_DATA(PyTypeObject) PyLong_Type; #define PyLong_Check(op) \ diff --git a/Include/methodobject.h b/Include/methodobject.h index 1be5873..5d2e06c 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -39,7 +39,6 @@ struct PyMethodDef { describe the args expected by the C func */ const char *ml_doc; /* The __doc__ attribute, or NULL */ }; -typedef struct PyMethodDef PyMethodDef; /* PyCFunction_New is declared as a function for stable ABI (declaration is * needed for e.g. GCC with -fvisibility=hidden), but redefined as a macro diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 49b116c..0f40683 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -72,7 +72,7 @@ typedef struct PyModuleDef_Slot{ #endif /* New in 3.5 */ -typedef struct PyModuleDef{ +struct PyModuleDef { PyModuleDef_Base m_base; const char* m_name; const char* m_doc; @@ -82,7 +82,7 @@ typedef struct PyModuleDef{ traverseproc m_traverse; inquiry m_clear; freefunc m_free; -} PyModuleDef; +}; // Internal C API diff --git a/Include/object.h b/Include/object.h index 3566c73..5313ea6 100644 --- a/Include/object.h +++ b/Include/object.h @@ -1,6 +1,5 @@ #ifndef Py_OBJECT_H #define Py_OBJECT_H - #ifdef __cplusplus extern "C" { #endif @@ -61,10 +60,6 @@ whose size is determined when the object is allocated. # error Py_LIMITED_API is incompatible with Py_TRACE_REFS #endif -/* PyTypeObject structure is defined in cpython/object.h. - In Py_LIMITED_API, PyTypeObject is an opaque structure. */ -typedef struct _typeobject PyTypeObject; - #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ #define _PyObject_HEAD_EXTRA \ @@ -102,11 +97,11 @@ typedef struct _typeobject PyTypeObject; * by hand. Similarly every pointer to a variable-size Python object can, * in addition, be cast to PyVarObject*. */ -typedef struct _object { +struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; PyTypeObject *ob_type; -} PyObject; +}; /* Cast argument to PyObject* type. */ #define _PyObject_CAST(op) ((PyObject*)(op)) @@ -765,4 +760,4 @@ static inline int PyType_CheckExact(PyObject *op) { #ifdef __cplusplus } #endif -#endif /* !Py_OBJECT_H */ +#endif // !Py_OBJECT_H diff --git a/Include/pybuffer.h b/Include/pybuffer.h index 31795b7..6893505 100644 --- a/Include/pybuffer.h +++ b/Include/pybuffer.h @@ -17,10 +17,6 @@ extern "C" { * */ -// Forward declaration to be able to include pybuffer.h before object.h: -// pybuffer.h uses PyObject and object.h uses Py_buffer. -typedef struct _object PyObject; - typedef struct { void *buf; PyObject *obj; /* owned reference */ diff --git a/Include/pyframe.h b/Include/pyframe.h index 3816224..feac16f 100644 --- a/Include/pyframe.h +++ b/Include/pyframe.h @@ -9,8 +9,6 @@ extern "C" { #endif -typedef struct _frame PyFrameObject; - /* Return the line of code the frame is currently executing. */ PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); diff --git a/Include/pystate.h b/Include/pystate.h index b6ee0ed..5b4245e 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -11,16 +11,6 @@ extern "C" { removed (with effort). */ #define MAX_CO_EXTRA_USERS 255 -/* Forward declarations for PyFrameObject, PyThreadState - and PyInterpreterState */ -struct _ts; -struct _is; - -/* struct _ts is defined in cpython/pystate.h */ -typedef struct _ts PyThreadState; -/* struct _is is defined in internal/pycore_interp.h */ -typedef struct _is PyInterpreterState; - PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); diff --git a/Include/pytypedefs.h b/Include/pytypedefs.h new file mode 100644 index 0000000..5dd841e --- /dev/null +++ b/Include/pytypedefs.h @@ -0,0 +1,29 @@ +// Forward declarations of types of the Python C API. +// Declare them at the same place since redefining typedef is a C11 feature. +// Only use a forward declaration if there is an interdependency between two +// header files. + +#ifndef Py_PYTYPEDEFS_H +#define Py_PYTYPEDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyModuleDef PyModuleDef; +typedef struct PyMethodDef PyMethodDef; +typedef struct PyGetSetDef PyGetSetDef; +typedef struct PyMemberDef PyMemberDef; + +typedef struct _object PyObject; +typedef struct _longobject PyLongObject; +typedef struct _typeobject PyTypeObject; +typedef struct PyCodeObject PyCodeObject; +typedef struct _frame PyFrameObject; + +typedef struct _ts PyThreadState; +typedef struct _is PyInterpreterState; + +#ifdef __cplusplus +} +#endif +#endif // !Py_PYTYPEDEFS_H diff --git a/Include/structmember.h b/Include/structmember.h index 93b7aff..acce438 100644 --- a/Include/structmember.h +++ b/Include/structmember.h @@ -15,13 +15,13 @@ extern "C" { flag is set). The array must be terminated with an entry whose name pointer is NULL. */ -typedef struct PyMemberDef { +struct PyMemberDef { const char *name; int type; Py_ssize_t offset; int flags; const char *doc; -} PyMemberDef; +}; /* Types */ #define T_SHORT 0 diff --git a/Makefile.pre.in b/Makefile.pre.in index 2a3e0fb..0383853 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1488,6 +1488,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/pystrtod.h \ $(srcdir)/Include/pythonrun.h \ $(srcdir)/Include/pythread.h \ + $(srcdir)/Include/pytypedefs.h \ $(srcdir)/Include/rangeobject.h \ $(srcdir)/Include/setobject.h \ $(srcdir)/Include/sliceobject.h \ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index c2f1a01..9699698 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -279,6 +279,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index b300103..92c6bf8 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -192,6 +192,9 @@ Include + + Include + Include -- cgit v0.12