From 94afb2af3fd82d139033da22078e555b56f53eb7 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Sun, 26 Feb 2017 03:15:19 +0900 Subject: [PATCH 1/3] bpo-29110: add test for Aifc_write. --- Lib/aifc.py | 4 ++-- Lib/test/test_aifc.py | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/aifc.py b/Lib/aifc.py index 380adc8d0da619..22afe6b243caef 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -371,7 +371,7 @@ def rewind(self): self._soundpos = 0 def close(self): - file = self._file + file = getattr(self, '_file') if file is not None: self._file = None file.close() @@ -730,7 +730,7 @@ def writeframes(self, data): self._patchheader() def close(self): - if self._file is None: + if getattr(self, '_file', None) is None: return try: self._ensure_header_written(0) diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index 989df93a3a5741..a731a5136ba5fd 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -1,5 +1,6 @@ from test.support import check_no_resource_warning, findfile, TESTFN, unlink import unittest +from unittest import mock from test import audiotests from audioop import byteswap import io @@ -155,7 +156,14 @@ def test_close_opened_files_on_error(self): with self.assertRaises(aifc.Error): # Try opening a non-AIFC file, with the expectation that # `aifc.open` will fail (without raising a ResourceWarning) - f = self.f = aifc.open(non_aifc_file, 'rb') + self.f = aifc.open(non_aifc_file, 'rb') + + # Aifc_write.initfp() won't raise in normal case. But some errors + # (e.g. MemoryError, KeyboardInterrupt, etc..) can happen. + with mock.patch.object(aifc.Aifc_write, 'initfp', + side_effect=RuntimeError): + with self.assertRaises(RuntimeError): + self.fout = aifc.open(TESTFN, 'wb') def test_params_added(self): f = self.f = aifc.open(TESTFN, 'wb') From 67a172db1b1c78807906bf94579cae089caf49b7 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Sun, 26 Feb 2017 09:39:48 +0900 Subject: [PATCH 2/3] Use class attribute to avoid AttributeError --- Lib/aifc.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/aifc.py b/Lib/aifc.py index 22afe6b243caef..89c97c23fd65c2 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -303,6 +303,8 @@ class Aifc_read: # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk # _framesize -- size of one frame in the file + _file = None + def initfp(self, file): self._version = 0 self._convert = None @@ -371,7 +373,7 @@ def rewind(self): self._soundpos = 0 def close(self): - file = getattr(self, '_file') + file = self._file if file is not None: self._file = None file.close() @@ -547,6 +549,8 @@ class Aifc_write: # _datalength -- the size of the audio samples written to the header # _datawritten -- the size of the audio samples actually written + _file = None + def __init__(self, f): if isinstance(f, str): file_object = builtins.open(f, 'wb') @@ -730,7 +734,7 @@ def writeframes(self, data): self._patchheader() def close(self): - if getattr(self, '_file', None) is None: + if self._file is None: return try: self._ensure_header_written(0) From a04c4337e29c484b8e919f7234a87c4583ae6bbe Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Sun, 26 Feb 2017 18:57:45 +0900 Subject: [PATCH 3/3] Add comment for _file class attribute --- Lib/aifc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/aifc.py b/Lib/aifc.py index 89c97c23fd65c2..13ad7dc5ca3d62 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -303,7 +303,7 @@ class Aifc_read: # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk # _framesize -- size of one frame in the file - _file = None + _file = None # Set here since __del__ checks it def initfp(self, file): self._version = 0 @@ -549,7 +549,7 @@ class Aifc_write: # _datalength -- the size of the audio samples written to the header # _datawritten -- the size of the audio samples actually written - _file = None + _file = None # Set here since __del__ checks it def __init__(self, f): if isinstance(f, str):