Index: Lib/test/test_array.py =================================================================== --- Lib/test/test_array.py (revision 75227) +++ Lib/test/test_array.py (working copy) @@ -188,6 +188,27 @@ f.close() test_support.unlink(test_support.TESTFN) + def test_fromfile_ioerror(self): + # Issue #5395: Check if fromfile raises a proper IOError + # instead of EOFError. + try: + import os + except ImportError: + return + a = array.array(self.typecode, self.example) + f = open(test_support.TESTFN, 'wb') + try: + f.write(a) + f.close() + b = array.array(self.typecode) + f = open(test_support.TESTFN, 'rb') + os.close(f.fileno()) + self.assertRaises(IOError, b.fromfile, f, len(a)) + finally: + if not f.closed: + test_support.expect_exception(IOError, f.close) + test_support.unlink(test_support.TESTFN) + def test_filewrite(self): a = array.array(self.typecode, 2*self.example) f = open(test_support.TESTFN, 'wb') Index: Lib/test/test_support.py =================================================================== --- Lib/test/test_support.py (revision 75227) +++ Lib/test/test_support.py (working copy) @@ -458,6 +458,16 @@ file.close() unlink(TESTFN) +def expect_exception(exception, function, *args): + """ + Call a function and catch the expected exception. Don't handly any other + Exceptions. + """ + try: + function(*args) + except exception: + pass + def check_syntax_error(testcase, statement): testcase.assertRaises(SyntaxError, compile, statement, '', 'exec') Index: Modules/arraymodule.c =================================================================== --- Modules/arraymodule.c (revision 75227) +++ Modules/arraymodule.c (working copy) @@ -1228,8 +1228,14 @@ PyMem_RESIZE(item, char, Py_SIZE(self)*itemsize); self->ob_item = item; self->allocated = Py_SIZE(self); - PyErr_SetString(PyExc_EOFError, - "not enough items in file"); + if (ferror(fp)) { + PyErr_SetFromErrno(PyExc_IOError); + clearerr(fp); + } + else { + PyErr_SetString(PyExc_EOFError, + "not enough items in file"); + } return NULL; } }