diff options
-rw-r--r-- | Lib/test/test_io.py | 11 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_io/iobase.c | 14 |
3 files changed, 27 insertions, 0 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 1129484..2c502ab 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -610,6 +610,17 @@ class IOTest(unittest.TestCase): self.assertEqual(rawio.read(2), None) self.assertEqual(rawio.read(2), b"") + def test_types_have_dict(self): + test = ( + self.IOBase(), + self.RawIOBase(), + self.TextIOBase(), + self.StringIO(), + self.BytesIO() + ) + for obj in test: + self.assertTrue(hasattr(obj, "__dict__")) + class CIOTest(IOTest): def test_IOBase_finalize(self): @@ -271,6 +271,8 @@ Core and Builtins Library ------- +- Issue #12878: Expose a __dict__ attribute on io.IOBase and its subclasses. + - Issue #12636: IDLE reads the coding cookie when executing a Python script. - Issue #12494: On error, call(), check_call(), check_output() and diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index f06f562..2c59d42 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -156,6 +156,19 @@ iobase_closed_get(PyObject *self, void *context) return PyBool_FromLong(IS_CLOSED(self)); } +static PyObject * +iobase_get_dict(PyObject *self) +{ + PyObject **dictptr = _PyObject_GetDictPtr(self); + PyObject *dict; + assert(dictptr); + dict = *dictptr; + if (dict == NULL) + dict = *dictptr = PyDict_New(); + Py_XINCREF(dict); + return dict; +} + PyObject * _PyIOBase_check_closed(PyObject *self, PyObject *args) { @@ -691,6 +704,7 @@ static PyMethodDef iobase_methods[] = { }; static PyGetSetDef iobase_getset[] = { + {"__dict__", iobase_get_dict, NULL, NULL}, {"closed", (getter)iobase_closed_get, NULL, NULL}, {NULL} }; |