Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-101819: Adapt _io.PyWindowsConsoleIO_Type to heap type #104197

Merged
merged 6 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -669,22 +675,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) {
Expand Down Expand Up @@ -778,6 +774,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);
Expand Down
7 changes: 5 additions & 2 deletions Modules/_io/_iomodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,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.
Expand Down Expand Up @@ -159,6 +159,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))
Expand Down
91 changes: 35 additions & 56 deletions Modules/_io/winconsoleio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -156,8 +156,6 @@ typedef struct {
wchar_t wbuf;
} winconsoleio;

PyTypeObject PyWindowsConsoleIO_Type;

int
_PyWindowsConsoleIO_closed(PyObject *self)
{
Expand Down Expand Up @@ -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
erlend-aasland marked this conversation as resolved.
Show resolved Hide resolved
_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. */
Expand Down Expand Up @@ -417,6 +418,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
static int
winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
Expand All @@ -431,14 +433,16 @@ 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;
_PyObject_GC_UNTRACK(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 *
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
1 change: 0 additions & 1 deletion Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ Modules/_io/iobase.c - PyIOBase_Type -
Modules/_io/iobase.c - PyRawIOBase_Type -
Modules/_io/textio.c - PyIncrementalNewlineDecoder_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 -
Expand Down