Skip to content

Commit 1781d55

Browse files
authored
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.
1 parent 17f268a commit 1781d55

File tree

10 files changed

+40
-19
lines changed

10 files changed

+40
-19
lines changed

Include/internal/pycore_structseq.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@ extern PyStatus _PyStructSequence_InitState(PyInterpreterState *);
1616

1717
/* other API */
1818

19+
PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
20+
PyStructSequence_Desc *desc,
21+
unsigned long tp_flags);
22+
1923
PyAPI_FUNC(int) _PyStructSequence_InitType(
2024
PyTypeObject *type,
2125
PyStructSequence_Desc *desc,
2226
unsigned long tp_flags);
2327

28+
extern void _PyStructSequence_FiniType(PyTypeObject *type);
2429

2530
#ifdef __cplusplus
2631
}

Include/structseq.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
2727
PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type,
2828
PyStructSequence_Desc *desc);
2929
#endif
30-
#ifdef Py_BUILD_CORE
31-
PyAPI_FUNC(void) _PyStructSequence_FiniType(PyTypeObject *type);
32-
#endif
3330
PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc);
3431

3532
PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type);

Lib/test/pythoninfo.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,15 @@ def collect_time(info_add):
434434
info_add('time.get_clock_info(%s)' % clock, clock_info)
435435

436436

437+
def collect_curses(info_add):
438+
try:
439+
import curses
440+
except ImportError:
441+
return
442+
443+
copy_attr(info_add, 'curses.ncurses_version', curses, 'ncurses_version')
444+
445+
437446
def collect_datetime(info_add):
438447
try:
439448
import datetime
@@ -752,6 +761,7 @@ def collect_info(info):
752761

753762
collect_builtins,
754763
collect_cc,
764+
collect_curses,
755765
collect_datetime,
756766
collect_decimal,
757767
collect_expat,

Modules/_cursesmodule.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static const char PyCursesVersion[] = "2.2";
108108

109109
#include "Python.h"
110110
#include "pycore_long.h" // _PyLong_GetZero()
111-
#include "pycore_structseq.h" // PyStructSequence_InitType()
111+
#include "pycore_structseq.h" // _PyStructSequence_NewType()
112112

113113
#ifdef __hpux
114114
#define STRICT_SYSV_CURSES
@@ -4569,8 +4569,6 @@ PyDoc_STRVAR(ncurses_version__doc__,
45694569
\n\
45704570
Ncurses version information as a named tuple.");
45714571

4572-
static PyTypeObject NcursesVersionType;
4573-
45744572
static PyStructSequence_Field ncurses_version_fields[] = {
45754573
{"major", "Major release number"},
45764574
{"minor", "Minor release number"},
@@ -4586,12 +4584,12 @@ static PyStructSequence_Desc ncurses_version_desc = {
45864584
};
45874585

45884586
static PyObject *
4589-
make_ncurses_version(void)
4587+
make_ncurses_version(PyTypeObject *type)
45904588
{
45914589
PyObject *ncurses_version;
45924590
int pos = 0;
45934591

4594-
ncurses_version = PyStructSequence_New(&NcursesVersionType);
4592+
ncurses_version = PyStructSequence_New(type);
45954593
if (ncurses_version == NULL) {
45964594
return NULL;
45974595
}
@@ -4796,14 +4794,14 @@ PyInit__curses(void)
47964794

47974795
#ifdef NCURSES_VERSION
47984796
/* ncurses_version */
4799-
if (NcursesVersionType.tp_name == NULL) {
4800-
if (_PyStructSequence_InitType(&NcursesVersionType,
4801-
&ncurses_version_desc,
4802-
Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
4803-
return NULL;
4804-
}
4797+
PyTypeObject *version_type;
4798+
version_type = _PyStructSequence_NewType(&ncurses_version_desc,
4799+
Py_TPFLAGS_DISALLOW_INSTANTIATION);
4800+
if (version_type == NULL) {
4801+
return NULL;
48054802
}
4806-
v = make_ncurses_version();
4803+
v = make_ncurses_version(version_type);
4804+
Py_DECREF(version_type);
48074805
if (v == NULL) {
48084806
return NULL;
48094807
}

Objects/floatobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "pycore_object.h" // _PyObject_Init()
1313
#include "pycore_pymath.h" // _Py_ADJUST_ERANGE1()
1414
#include "pycore_pystate.h" // _PyInterpreterState_GET()
15+
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
1516

1617
#include <ctype.h>
1718
#include <float.h>

Objects/longobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "pycore_object.h" // _PyObject_InitVar()
1010
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
1111
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
12+
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
1213

1314
#include <ctype.h>
1415
#include <float.h>

Objects/structseq.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ _PyStructSequence_FiniType(PyTypeObject *type)
563563

564564

565565
PyTypeObject *
566-
PyStructSequence_NewType(PyStructSequence_Desc *desc)
566+
_PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
567567
{
568568
PyMemberDef *members;
569569
PyTypeObject *type;
@@ -596,7 +596,7 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
596596
spec.name = desc->name;
597597
spec.basicsize = sizeof(PyStructSequence) - sizeof(PyObject *);
598598
spec.itemsize = sizeof(PyObject *);
599-
spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC;
599+
spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags;
600600
spec.slots = slots;
601601

602602
type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type);
@@ -615,6 +615,13 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
615615
}
616616

617617

618+
PyTypeObject *
619+
PyStructSequence_NewType(PyStructSequence_Desc *desc)
620+
{
621+
return _PyStructSequence_NewType(desc, 0);
622+
}
623+
624+
618625
/* runtime lifecycle */
619626

620627
PyStatus _PyStructSequence_InitState(PyInterpreterState *interp)

Python/errors.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "pycore_initconfig.h" // _PyStatus_ERR()
77
#include "pycore_pyerrors.h" // _PyErr_Format()
88
#include "pycore_pystate.h" // _PyThreadState_GET()
9+
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
910
#include "pycore_sysmodule.h" // _PySys_Audit()
1011
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
1112

Python/sysmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Data members:
2727
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
2828
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
2929
#include "pycore_pystate.h" // _PyThreadState_GET()
30-
#include "pycore_structseq.h" // PyStructSequence_InitType()
30+
#include "pycore_structseq.h" // _PyStructSequence_InitType()
3131
#include "pycore_tuple.h" // _PyTuple_FromArray()
3232

3333
#include "code.h"

Python/thread.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
Stuff shared by all thread_*.h files is collected here. */
77

88
#include "Python.h"
9-
#include "pycore_pystate.h" // _PyInterpreterState_GET()
9+
#include "pycore_pystate.h" // _PyInterpreterState_GET()
10+
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
1011

1112
#ifndef _POSIX_THREADS
1213
/* This means pthreads are not implemented in libc headers, hence the macro

0 commit comments

Comments
 (0)