diff -r 181ced5bf0be Lib/test/test_bz2.py --- a/Lib/test/test_bz2.py Mon Dec 02 05:53:35 2013 -0800 +++ b/Lib/test/test_bz2.py Wed Dec 04 12:18:12 2013 +0800 @@ -325,6 +325,18 @@ self.assertRaises(ValueError, f.readline) self.assertRaises(ValueError, f.readlines) + def testInitNonExistentFile(self): + # Issue #19878: Should not segfault when __init__ with non-existent + # file for the second time. + with BZ2File(self.filename, "wb") as f: + f.write(b"xxx") + # Bz2File_Dealloc + f = bz2.BZ2File(self.filename) + self.assertRaises(IOError, f.__init__, "non-existent-file") + # Bz2File_Close + with BZ2File(self.filename, "wb") as f: + self.assertRaises(IOError, f.__init__, "non-existent-file") + class BZ2CompressorTest(BaseTest): def testCompress(self): # "Test BZ2Compressor.compress()/flush()" diff -r 181ced5bf0be Modules/bz2module.c --- a/Modules/bz2module.c Mon Dec 02 05:53:35 2013 -0800 +++ b/Modules/bz2module.c Wed Dec 04 12:18:12 2013 +0800 @@ -1207,11 +1207,15 @@ break; } if (self->fp) { - PyFile_DecUseCount((PyFileObject *)self->file); + if (self->file) { + PyFile_DecUseCount((PyFileObject *)self->file); + ret = PyObject_CallMethod(self->file, "close", NULL); + } else { + ret = PyLong_FromLong(1); + } self->fp = NULL; } self->mode = MODE_CLOSED; - ret = PyObject_CallMethod(self->file, "close", NULL); if (bzerror != BZ_OK) { Util_CatchBZ2Error(bzerror); Py_XDECREF(ret); @@ -1480,7 +1484,8 @@ break; } if (self->fp) { - PyFile_DecUseCount((PyFileObject *)self->file); + if (self->file) + PyFile_DecUseCount((PyFileObject *)self->file); self->fp = NULL; } Util_DropReadAhead(self);