diff options
author | Guido van Rossum <guido@python.org> | 2007-07-10 09:12:49 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-07-10 09:12:49 (GMT) |
commit | 4b5386f3982b86817cfe42dbedfaf0c04d0e443f (patch) | |
tree | c6c73336f78929f1ac300579d72ef82744375434 | |
parent | 2b6a97e69cd33ac7389b0e42c243b47e3d23f2fb (diff) | |
download | cpython-4b5386f3982b86817cfe42dbedfaf0c04d0e443f.zip cpython-4b5386f3982b86817cfe42dbedfaf0c04d0e443f.tar.gz cpython-4b5386f3982b86817cfe42dbedfaf0c04d0e443f.tar.bz2 |
Add proper tests for closed files to various I/O operations,
restoring a disabled test.
This was necessary to make test_pickle.py pass.
-rw-r--r-- | Lib/io.py | 25 | ||||
-rw-r--r-- | Lib/test/test_file.py | 30 |
2 files changed, 41 insertions, 14 deletions
@@ -157,6 +157,10 @@ def open(file, mode="r", buffering=None, encoding=None, newline=None): return text +class UnsupportedOperation(ValueError, IOError): + pass + + class IOBase: """Base class for all I/O classes. @@ -177,8 +181,8 @@ class IOBase: def _unsupported(self, name: str) -> IOError: """Internal: raise an exception for unsupported operations.""" - raise IOError("%s.%s() not supported" % (self.__class__.__name__, - name)) + raise UnsupportedOperation("%s.%s() not supported" % + (self.__class__.__name__, name)) ### Positioning ### @@ -327,6 +331,8 @@ class IOBase: return res def __iter__(self): + if self.closed: + raise ValueError("__iter__ on closed file") return self def __next__(self): @@ -348,6 +354,8 @@ class IOBase: return lines def writelines(self, lines): + if self.closed: + raise ValueError("write to closed file") for line in lines: self.write(line) @@ -587,8 +595,9 @@ class _BufferedIOMixin(BufferedIOBase): self.raw.flush() def close(self): - self.flush() - self.raw.close() + if not self.closed: + self.flush() + self.raw.close() ### Inquiries ### @@ -644,6 +653,8 @@ class BytesIO(BufferedIOBase): return self.read(n) def write(self, b): + if self.closed: + raise ValueError("write to closed file") n = len(b) newpos = self._pos + n self._buffer[self._pos:newpos] = b @@ -779,6 +790,8 @@ class BufferedWriter(_BufferedIOMixin): self._write_buf = b"" def write(self, b): + if self.closed: + raise ValueError("write to closed file") if not isinstance(b, bytes): if hasattr(b, "__index__"): raise TypeError("Can't write object of type %s" % @@ -809,6 +822,8 @@ class BufferedWriter(_BufferedIOMixin): return written def flush(self): + if self.closed: + raise ValueError("flush of closed file") written = 0 try: while self._write_buf: @@ -1040,6 +1055,8 @@ class TextIOWrapper(TextIOBase): return self.buffer.isatty() def write(self, s: str): + if self.closed: + raise ValueError("write to closed file") # XXX What if we were just reading? b = s.encode(self._encoding) if isinstance(b, str): diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index adede2b..0764000 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -89,21 +89,31 @@ class AutoFileTests(unittest.TestCase): self.assert_(f.closed) def testMethods(self): - methods = ['fileno', 'flush', 'isatty', '__next__', 'read', 'readinto', - 'readline', 'readlines', 'seek', 'tell', 'truncate', - 'write', '__iter__'] - if sys.platform.startswith('atheos'): - methods.remove('truncate') + methods = [('fileno', ()), + ('flush', ()), + ('isatty', ()), + ('__next__', ()), + ('read', ()), + ('write', (b"",)), + ('readline', ()), + ('readlines', ()), + ('seek', (0,)), + ('tell', ()), + ('write', (b"",)), + ('writelines', ([],)), + ('__iter__', ()), + ] + if not sys.platform.startswith('atheos'): + methods.append(('truncate', ())) # __exit__ should close the file self.f.__exit__(None, None, None) self.assert_(self.f.closed) -## for methodname in methods: -## method = getattr(self.f, methodname) -## # should raise on closed file -## self.assertRaises(ValueError, method) -## self.assertRaises(ValueError, self.f.writelines, []) + for methodname, args in methods: + method = getattr(self.f, methodname) + # should raise on closed file + self.assertRaises(ValueError, method, *args) # file is closed, __exit__ shouldn't do anything self.assertEquals(self.f.__exit__(None, None, None), None) |