From b0cb11b0f4d62aca9a3d531e91341a8a7f2bada2 Mon Sep 17 00:00:00 2001 From: Gus Goulart Date: Tue, 16 Oct 2018 22:03:45 -0300 Subject: [PATCH 1/5] _WindowsConsoleIO rises correct exception _WindowsConsoleIO implementation of fileno should raise a ValueError instead of io.UnsupportedOperation if the internal handle value is INVALID_HANDLE_VALUE. --- Modules/_io/winconsoleio.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 13342ec239d6d6..c703520c4ab8d8 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -177,8 +177,9 @@ internal_close(winconsoleio *self) _Py_BEGIN_SUPPRESS_IPH close(self->fd); _Py_END_SUPPRESS_IPH + } else { + CloseHandle(self->handle); } - CloseHandle(self->handle); } self->handle = INVALID_HANDLE_VALUE; self->fd = -1; @@ -474,16 +475,22 @@ static PyObject * _io__WindowsConsoleIO_fileno_impl(winconsoleio *self) /*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ { - if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) { + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + + if (self->fd < 0) { _Py_BEGIN_SUPPRESS_IPH if (self->writable) self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY); else self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY); _Py_END_SUPPRESS_IPH + + if (self->closehandle) + CloseHandle(self->handle); + self->handle = INVALID_HANDLE_VALUE; + return err_closed(); } - if (self->fd < 0) - return err_mode("fileno"); return PyLong_FromLong(self->fd); } From fb456f19b29b3216a487697c73178fa3b191928a Mon Sep 17 00:00:00 2001 From: Gus Goulart Date: Wed, 17 Oct 2018 22:23:37 -0300 Subject: [PATCH 2/5] Split logic --- Modules/_io/winconsoleio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index c703520c4ab8d8..e8eb5e36b46fd7 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -485,7 +485,9 @@ _io__WindowsConsoleIO_fileno_impl(winconsoleio *self) else self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY); _Py_END_SUPPRESS_IPH + } + if (self->fd < 0) { if (self->closehandle) CloseHandle(self->handle); self->handle = INVALID_HANDLE_VALUE; From bc814b6832ccf9f87d7696a14825f88b4c1ff896 Mon Sep 17 00:00:00 2001 From: Gus Goulart Date: Thu, 25 Oct 2018 21:31:47 -0300 Subject: [PATCH 3/5] Remove changes on internal_close --- Modules/_io/winconsoleio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index e8eb5e36b46fd7..9209e427e35c63 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -177,9 +177,8 @@ internal_close(winconsoleio *self) _Py_BEGIN_SUPPRESS_IPH close(self->fd); _Py_END_SUPPRESS_IPH - } else { - CloseHandle(self->handle); } + CloseHandle(self->handle); } self->handle = INVALID_HANDLE_VALUE; self->fd = -1; From 6ecd91d34353a41795ffb975367c0941969bf15c Mon Sep 17 00:00:00 2001 From: Gus Goulart Date: Thu, 25 Oct 2018 22:08:01 -0300 Subject: [PATCH 4/5] If statement should have curly braces --- Modules/_io/winconsoleio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 9209e427e35c63..ab8ccaf8b25a84 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -474,8 +474,9 @@ static PyObject * _io__WindowsConsoleIO_fileno_impl(winconsoleio *self) /*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ { - if (self->handle == INVALID_HANDLE_VALUE) + if (self->handle == INVALID_HANDLE_VALUE) { return err_closed(); + } if (self->fd < 0) { _Py_BEGIN_SUPPRESS_IPH From c1aec3c56d8b298890ad33128065446c3aeba522 Mon Sep 17 00:00:00 2001 From: Gus Goulart Date: Fri, 26 Oct 2018 00:08:46 -0300 Subject: [PATCH 5/5] Add test for fileno exception --- Lib/test/test_winconsoleio.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/test/test_winconsoleio.py b/Lib/test/test_winconsoleio.py index a78fa4d7d919ff..0e71a029390c40 100644 --- a/Lib/test/test_winconsoleio.py +++ b/Lib/test/test_winconsoleio.py @@ -125,6 +125,14 @@ def test_write_empty_data(self): with ConIO('CONOUT$', 'w') as f: self.assertEqual(f.write(b''), 0) + def test_fileno_raises_correct_exception(self): + # Test that WindowsConsoleIO implementation of fileno + # raises a ValueError instead of io.UnsupportedOperation + # if the internal handle value is INVALID_HANDLE_VALUE. + f = open('conin$', 'r') + f.close() + self.assertRaisesRegex(ValueError, "I/O operation on closed file", f.fileno) + def assertStdinRoundTrip(self, text): stdin = open('CONIN$', 'r') old_stdin = sys.stdin