]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46417: _curses uses PyStructSequence_NewType() (GH-30736)
authorVictor Stinner <vstinner@python.org>
Fri, 21 Jan 2022 02:30:20 +0000 (03:30 +0100)
committerGitHub <noreply@github.com>
Fri, 21 Jan 2022 02:30:20 +0000 (03:30 +0100)
The _curses module now creates its ncurses_version type as a heap
type using PyStructSequence_NewType(), rather than using a static
type.

* Move _PyStructSequence_FiniType() definition to pycore_structseq.h.
* test.pythoninfo: log curses.ncurses_version.

Include/internal/pycore_structseq.h
Include/structseq.h
Lib/test/pythoninfo.py
Modules/_cursesmodule.c
Objects/floatobject.c
Objects/longobject.c
Objects/structseq.c
Python/errors.c
Python/sysmodule.c
Python/thread.c

index 3a61cb9a12608b652d7fda1ae8313cbdbd442939..c0323bbea89916c075b73a2863a9483e0ffbf4f8 100644 (file)
@@ -16,11 +16,16 @@ extern PyStatus _PyStructSequence_InitState(PyInterpreterState *);
 
 /* other API */
 
+PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
+    PyStructSequence_Desc *desc,
+    unsigned long tp_flags);
+
 PyAPI_FUNC(int) _PyStructSequence_InitType(
     PyTypeObject *type,
     PyStructSequence_Desc *desc,
     unsigned long tp_flags);
 
+extern void _PyStructSequence_FiniType(PyTypeObject *type);
 
 #ifdef __cplusplus
 }
index 8abd2443468b7726b75900402d33fd97c82e72aa..e89265a67c322e8792d4454e0440234f1fff1199 100644 (file)
@@ -27,9 +27,6 @@ PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
 PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type,
                                            PyStructSequence_Desc *desc);
 #endif
-#ifdef Py_BUILD_CORE
-PyAPI_FUNC(void) _PyStructSequence_FiniType(PyTypeObject *type);
-#endif
 PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc);
 
 PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type);
index 39ee9e1d769f8d24cd1cb6d79008b67580304723..9d733c5721cde8fc1dd40402dde75ff9c7cbf186 100644 (file)
@@ -434,6 +434,15 @@ def collect_time(info_add):
                 info_add('time.get_clock_info(%s)' % clock, clock_info)
 
 
+def collect_curses(info_add):
+    try:
+        import curses
+    except ImportError:
+        return
+
+    copy_attr(info_add, 'curses.ncurses_version', curses, 'ncurses_version')
+
+
 def collect_datetime(info_add):
     try:
         import datetime
@@ -752,6 +761,7 @@ def collect_info(info):
 
         collect_builtins,
         collect_cc,
+        collect_curses,
         collect_datetime,
         collect_decimal,
         collect_expat,
index bf742dacf011057c917caaed02d7973160da0e65..423b042b90755a69361451210e26a4959b4f8bf5 100644 (file)
@@ -108,7 +108,7 @@ static const char PyCursesVersion[] = "2.2";
 
 #include "Python.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
-#include "pycore_structseq.h"     // PyStructSequence_InitType()
+#include "pycore_structseq.h"     // _PyStructSequence_NewType()
 
 #ifdef __hpux
 #define STRICT_SYSV_CURSES
@@ -4569,8 +4569,6 @@ PyDoc_STRVAR(ncurses_version__doc__,
 \n\
 Ncurses version information as a named tuple.");
 
-static PyTypeObject NcursesVersionType;
-
 static PyStructSequence_Field ncurses_version_fields[] = {
     {"major", "Major release number"},
     {"minor", "Minor release number"},
@@ -4586,12 +4584,12 @@ static PyStructSequence_Desc ncurses_version_desc = {
 };
 
 static PyObject *
-make_ncurses_version(void)
+make_ncurses_version(PyTypeObject *type)
 {
     PyObject *ncurses_version;
     int pos = 0;
 
-    ncurses_version = PyStructSequence_New(&NcursesVersionType);
+    ncurses_version = PyStructSequence_New(type);
     if (ncurses_version == NULL) {
         return NULL;
     }
@@ -4796,14 +4794,14 @@ PyInit__curses(void)
 
 #ifdef NCURSES_VERSION
     /* ncurses_version */
-    if (NcursesVersionType.tp_name == NULL) {
-        if (_PyStructSequence_InitType(&NcursesVersionType,
-                                       &ncurses_version_desc,
-                                       Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
-            return NULL;
-        }
+    PyTypeObject *version_type;
+    version_type = _PyStructSequence_NewType(&ncurses_version_desc,
+                                             Py_TPFLAGS_DISALLOW_INSTANTIATION);
+    if (version_type == NULL) {
+        return NULL;
     }
-    v = make_ncurses_version();
+    v = make_ncurses_version(version_type);
+    Py_DECREF(version_type);
     if (v == NULL) {
         return NULL;
     }
index 88f25d6b8c8863530756ea1ccbb954d272692185..68be7acaa2e726bf446a23684f90d3c9f0aa0cf9 100644 (file)
@@ -12,6 +12,7 @@
 #include "pycore_object.h"        // _PyObject_Init()
 #include "pycore_pymath.h"        // _Py_ADJUST_ERANGE1()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_structseq.h"     // _PyStructSequence_FiniType()
 
 #include <ctype.h>
 #include <float.h>
index 5aa53dd91c2997408f2b615bd1712c296b574922..7721f40adbba6509e59487e98ffb39504150b210 100644 (file)
@@ -9,6 +9,7 @@
 #include "pycore_object.h"        // _PyObject_InitVar()
 #include "pycore_pystate.h"       // _Py_IsMainInterpreter()
 #include "pycore_runtime.h"       // _PY_NSMALLPOSINTS
+#include "pycore_structseq.h"     // _PyStructSequence_FiniType()
 
 #include <ctype.h>
 #include <float.h>
index f8bf9477f284871f9ab5fe9acc827cd2c5b18c18..dfefae8928eb6977d6dd991c60e3326bb34950d0 100644 (file)
@@ -563,7 +563,7 @@ _PyStructSequence_FiniType(PyTypeObject *type)
 
 
 PyTypeObject *
-PyStructSequence_NewType(PyStructSequence_Desc *desc)
+_PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
 {
     PyMemberDef *members;
     PyTypeObject *type;
@@ -596,7 +596,7 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
     spec.name = desc->name;
     spec.basicsize = sizeof(PyStructSequence) - sizeof(PyObject *);
     spec.itemsize = sizeof(PyObject *);
-    spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC;
+    spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags;
     spec.slots = slots;
 
     type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type);
@@ -615,6 +615,13 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
 }
 
 
+PyTypeObject *
+PyStructSequence_NewType(PyStructSequence_Desc *desc)
+{
+    return _PyStructSequence_NewType(desc, 0);
+}
+
+
 /* runtime lifecycle */
 
 PyStatus _PyStructSequence_InitState(PyInterpreterState *interp)
index 211881ca5eb6ce675fac6b4d9b2c6412c9499f66..023234974c47d4d2493ffae58ffdab00f0bcba5a 100644 (file)
@@ -6,6 +6,7 @@
 #include "pycore_initconfig.h"    // _PyStatus_ERR()
 #include "pycore_pyerrors.h"      // _PyErr_Format()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
+#include "pycore_structseq.h"     // _PyStructSequence_FiniType()
 #include "pycore_sysmodule.h"     // _PySys_Audit()
 #include "pycore_traceback.h"     // _PyTraceBack_FromFrame()
 
index 515994f0490866dfae3f5b48770903d30c860e4b..7597ea2ea9e495ab850f5568ddd767165cb44e10 100644 (file)
@@ -27,7 +27,7 @@ Data members:
 #include "pycore_pylifecycle.h"   // _PyErr_WriteUnraisableDefaultHook()
 #include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
-#include "pycore_structseq.h"     // PyStructSequence_InitType()
+#include "pycore_structseq.h"     // _PyStructSequence_InitType()
 #include "pycore_tuple.h"         // _PyTuple_FromArray()
 
 #include "code.h"
index c2457c4f8fe83511a93188e4e7cb897cf28883b8..c6b16251a05b6954abe4c93cd0aee06c5c31d5b1 100644 (file)
@@ -6,7 +6,8 @@
    Stuff shared by all thread_*.h files is collected here. */
 
 #include "Python.h"
-#include "pycore_pystate.h"   // _PyInterpreterState_GET()
+#include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_structseq.h"     // _PyStructSequence_FiniType()
 
 #ifndef _POSIX_THREADS
 /* This means pthreads are not implemented in libc headers, hence the macro