diff --git a/Lib/test/test_io/test_fileio.py b/Lib/test/test_io/test_fileio.py index 21a160904a7f1e..14db757964cf3d 100644 --- a/Lib/test/test_io/test_fileio.py +++ b/Lib/test/test_io/test_fileio.py @@ -62,6 +62,10 @@ def testSeekTell(self): self.f.seek(-5, 2) self.assertEqual(self.f.tell(), 15) + def testSeekableAfterFailedSeek(self) -> None: + self.assertRaises(OSError, self.f.seek, -1) + self.assertTrue(self.f.seekable()) + def testAttributes(self): # verify expected attributes exist f = self.f diff --git a/Misc/NEWS.d/next/Library/2026-10-18-17-26-00.gh-issue-159677.fIoSk1.rst b/Misc/NEWS.d/next/Library/2026-10-18-17-26-00.gh-issue-159677.fIoSk1.rst new file mode 100644 index 00000000000000..93feb6c41c545a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-18-17-26-00.gh-issue-159677.fIoSk1.rst @@ -0,0 +1,2 @@ +Fix :class:`io.FileIO` ``seekable`` being cached as false because of an invalid +argument to :meth:`!io.FileIO.seek` diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index e5cd7aca5de2f1..974369f107e927 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1013,7 +1013,7 @@ portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_er _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS - if (self->seekable < 0) { + if (self->seekable < 0 && (res >= 0 || errno == ESPIPE || posobj == NULL)) { self->seekable = (res >= 0); }