summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-01-21 02:30:20 (GMT)
committerGitHub <noreply@github.com>2022-01-21 02:30:20 (GMT)
commit1781d55eb34f94029e50970232635fc5082378cb (patch)
tree613d5c847480facfe411345b4a61ee3239950e53
parent17f268a4ae6190b2659c89c6f32ad2d006e0e3c8 (diff)
downloadcpython-1781d55eb34f94029e50970232635fc5082378cb.zip
cpython-1781d55eb34f94029e50970232635fc5082378cb.tar.gz
cpython-1781d55eb34f94029e50970232635fc5082378cb.tar.bz2
bpo-46417: _curses uses PyStructSequence_NewType() (GH-30736)
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.
-rw-r--r--Include/internal/pycore_structseq.h5
-rw-r--r--Include/structseq.h3
-rw-r--r--Lib/test/pythoninfo.py10
-rw-r--r--Modules/_cursesmodule.c22
-rw-r--r--Objects/floatobject.c1
-rw-r--r--Objects/longobject.c1
-rw-r--r--Objects/structseq.c11
-rw-r--r--Python/errors.c1
-rw-r--r--Python/sysmodule.c2
-rw-r--r--Python/thread.c3
10 files changed, 40 insertions, 19 deletions
diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h
index 3a61cb9..c0323bb 100644
--- a/Include/internal/pycore_structseq.h
+++ b/Include/internal/pycore_structseq.h
@@ -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
}
diff --git a/Include/structseq.h b/Include/structseq.h
index 8abd244..e89265a 100644
--- a/Include/structseq.h
+++ b/Include/structseq.h
@@ -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);
diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py
index 39ee9e1..9d733c5 100644
--- a/Lib/test/pythoninfo.py
+++ b/Lib/test/pythoninfo.py
@@ -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,
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index bf742da..423b042 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -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;
}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 88f25d6..68be7ac 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -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>
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 5aa53dd..7721f40 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -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>
diff --git a/Objects/structseq.c b/Objects/structseq.c
index f8bf947..dfefae8 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -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)
diff --git a/Python/errors.c b/Python/errors.c
index 211881c..0232349 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -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()
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 515994f..7597ea2 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -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"
diff --git a/Python/thread.c b/Python/thread.c
index c2457c4..c6b1625 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -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