summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-05-07 09:23:11 (GMT)
committerGitHub <noreply@github.com>2023-05-07 09:23:11 (GMT)
commitcab1298a6022ddf12ddcdadd74bb8741650d8e9f (patch)
treecda4c8d85b645b2c092fec1f0bb2a8afe24dba17
parent39523796554c41f16e74961f7a90dfc30b0eed64 (diff)
downloadcpython-cab1298a6022ddf12ddcdadd74bb8741650d8e9f.zip
cpython-cab1298a6022ddf12ddcdadd74bb8741650d8e9f.tar.gz
cpython-cab1298a6022ddf12ddcdadd74bb8741650d8e9f.tar.bz2
gh-101819: Adapt _io.PyWindowsConsoleIO_Type to heap type (#104197)
-rw-r--r--Modules/_io/_iomodule.c22
-rw-r--r--Modules/_io/_iomodule.h7
-rw-r--r--Modules/_io/winconsoleio.c91
-rw-r--r--Tools/c-analyzer/cpython/globals-to-fix.tsv1
4 files changed, 51 insertions, 70 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index ce9fcca..b72b847 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -321,7 +321,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
#ifdef HAVE_WINDOWS_CONSOLE_IO
const PyConfig *config = _Py_GetConfig();
if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
- RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type;
+ RawIO_class = (PyObject *)state->PyWindowsConsoleIO_Type;
encoding = "utf-8";
}
#endif
@@ -595,6 +595,9 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
Py_VISIT(state->PyStringIO_Type);
Py_VISIT(state->PyTextIOBase_Type);
Py_VISIT(state->PyTextIOWrapper_Type);
+#ifdef HAVE_WINDOWS_CONSOLE_IO
+ Py_VISIT(state->PyWindowsConsoleIO_Type);
+#endif
return 0;
}
@@ -619,6 +622,9 @@ iomodule_clear(PyObject *mod) {
Py_CLEAR(state->PyStringIO_Type);
Py_CLEAR(state->PyTextIOBase_Type);
Py_CLEAR(state->PyTextIOWrapper_Type);
+#ifdef HAVE_WINDOWS_CONSOLE_IO
+ Py_CLEAR(state->PyWindowsConsoleIO_Type);
+#endif
return 0;
}
@@ -668,22 +674,12 @@ static PyTypeObject* static_types[] = {
// PyRawIOBase_Type(PyIOBase_Type) subclasses
&_PyBytesIOBuffer_Type,
-#ifdef HAVE_WINDOWS_CONSOLE_IO
- &PyWindowsConsoleIO_Type,
-#endif
};
PyStatus
_PyIO_InitTypes(PyInterpreterState *interp)
{
-#ifdef HAVE_WINDOWS_CONSOLE_IO
- if (_Py_IsMainInterpreter(interp)) {
- // Set type base classes
- PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
- }
-#endif
-
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
PyTypeObject *type = static_types[i];
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
@@ -777,6 +773,10 @@ PyInit__io(void)
// PyRawIOBase_Type(PyIOBase_Type) subclasses
state->PyBytesIOBuffer_Type = (PyTypeObject *)Py_NewRef(&_PyBytesIOBuffer_Type);
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, state->PyRawIOBase_Type);
+#ifdef MS_WINDOWS
+ ADD_TYPE(m, state->PyWindowsConsoleIO_Type, &winconsoleio_spec,
+ state->PyRawIOBase_Type);
+#endif
// PyTextIOBase_Type(PyIOBase_Type) subclasses
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, state->PyTextIOBase_Type);
diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h
index f191cea..00e6a19 100644
--- a/Modules/_io/_iomodule.h
+++ b/Modules/_io/_iomodule.h
@@ -26,8 +26,8 @@ extern PyType_Spec stringio_spec;
extern PyType_Spec textiowrapper_spec;
#ifdef HAVE_WINDOWS_CONSOLE_IO
-extern PyTypeObject PyWindowsConsoleIO_Type;
-#endif /* HAVE_WINDOWS_CONSOLE_IO */
+extern PyType_Spec winconsoleio_spec;
+#endif
/* These functions are used as METH_NOARGS methods, are normally called
* with args=NULL, and return a new reference.
@@ -157,6 +157,9 @@ typedef struct {
PyTypeObject *PyStringIO_Type;
PyTypeObject *PyTextIOBase_Type;
PyTypeObject *PyTextIOWrapper_Type;
+#ifdef MS_WINDOWS
+ PyTypeObject *PyWindowsConsoleIO_Type;
+#endif
} _PyIO_State;
#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod))
diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c
index f836e23..fdb57cf 100644
--- a/Modules/_io/winconsoleio.c
+++ b/Modules/_io/winconsoleio.c
@@ -137,9 +137,9 @@ char _PyIO_get_console_type(PyObject *path_or_fd) {
/*[clinic input]
module _io
-class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type"
+class _io._WindowsConsoleIO "winconsoleio *" "clinic_state()->PyWindowsConsoleIO_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=05526e723011ab36]*/
typedef struct {
PyObject_HEAD
@@ -156,8 +156,6 @@ typedef struct {
wchar_t wbuf;
} winconsoleio;
-PyTypeObject PyWindowsConsoleIO_Type;
-
int
_PyWindowsConsoleIO_closed(PyObject *self)
{
@@ -265,7 +263,10 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
int fd_is_own = 0;
HANDLE handle = NULL;
- assert(PyObject_TypeCheck(self, (PyTypeObject *)&PyWindowsConsoleIO_Type));
+#ifdef Py_DEBUG
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
+ assert(PyObject_TypeCheck(self, state->PyWindowsConsoleIO_Type));
+#endif
if (self->fd >= 0) {
if (self->closefd) {
/* Have to close the existing file first. */
@@ -417,6 +418,7 @@ done:
static int
winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
@@ -431,6 +433,7 @@ winconsoleio_clear(winconsoleio *self)
static void
winconsoleio_dealloc(winconsoleio *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
@@ -438,7 +441,8 @@ winconsoleio_dealloc(winconsoleio *self)
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) self);
Py_CLEAR(self->dict);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ tp->tp_free((PyObject *)self);
+ Py_DECREF(tp);
}
static PyObject *
@@ -1078,7 +1082,9 @@ _io__WindowsConsoleIO_isatty_impl(winconsoleio *self)
Py_RETURN_TRUE;
}
+#define clinic_state() (IO_STATE())
#include "clinic/winconsoleio.c.h"
+#undef clinic_state
static PyMethodDef winconsoleio_methods[] = {
_IO__WINDOWSCONSOLEIO_READ_METHODDEF
@@ -1124,59 +1130,32 @@ static PyGetSetDef winconsoleio_getsetlist[] = {
static PyMemberDef winconsoleio_members[] = {
{"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0},
{"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(winconsoleio, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(winconsoleio, dict), READONLY},
{NULL}
};
-PyTypeObject PyWindowsConsoleIO_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io._WindowsConsoleIO",
- sizeof(winconsoleio),
- 0,
- (destructor)winconsoleio_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- (reprfunc)winconsoleio_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- _io__WindowsConsoleIO___init____doc__, /* tp_doc */
- (traverseproc)winconsoleio_traverse, /* tp_traverse */
- (inquiry)winconsoleio_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(winconsoleio, weakreflist), /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- winconsoleio_methods, /* tp_methods */
- winconsoleio_members, /* tp_members */
- winconsoleio_getsetlist, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(winconsoleio, dict), /* tp_dictoffset */
- _io__WindowsConsoleIO___init__, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- winconsoleio_new, /* tp_new */
- PyObject_GC_Del, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot winconsoleio_slots[] = {
+ {Py_tp_dealloc, winconsoleio_dealloc},
+ {Py_tp_repr, winconsoleio_repr},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_doc, (void *)_io__WindowsConsoleIO___init____doc__},
+ {Py_tp_traverse, winconsoleio_traverse},
+ {Py_tp_clear, winconsoleio_clear},
+ {Py_tp_methods, winconsoleio_methods},
+ {Py_tp_members, winconsoleio_members},
+ {Py_tp_getset, winconsoleio_getsetlist},
+ {Py_tp_init, _io__WindowsConsoleIO___init__},
+ {Py_tp_new, winconsoleio_new},
+ {0, NULL},
+};
+
+PyType_Spec winconsoleio_spec = {
+ .name = "_io._WindowsConsoleIO",
+ .basicsize = sizeof(winconsoleio),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = winconsoleio_slots,
};
#endif /* HAVE_WINDOWS_CONSOLE_IO */
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index b195dab..ffe1515 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -322,7 +322,6 @@ Modules/_io/bytesio.c - _PyBytesIOBuffer_Type -
Modules/_io/iobase.c - PyIOBase_Type -
Modules/_io/iobase.c - PyRawIOBase_Type -
Modules/_io/textio.c - PyTextIOBase_Type -
-Modules/_io/winconsoleio.c - PyWindowsConsoleIO_Type -
Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type -
Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type -
Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type -