Permalink
Browse files

Make seekable() check the underlying file object.

This requires some messy introspection, since file objects in 2.x can seek but
do not have a seekable() method.
  • Loading branch information...
1 parent 65d3f19 commit 52983d0fdf63cd50341c392b9baaf876330ce22e @nvawda committed Feb 12, 2012
Showing with 19 additions and 2 deletions.
  1. +10 −2 bz2file.py
  2. +9 −0 test_bz2file.py
View
12 bz2file.py
@@ -137,7 +137,12 @@ def fileno(self):
def seekable(self):
"""Return whether the file supports seeking."""
- return self.readable()
+ if not self.readable():
+ return False
+ if hasattr(self._fp, "seekable"):
+ return self._fp.seekable()
+ else:
+ return hasattr(self._fp, "seek")
def readable(self):
"""Return whether the file was opened for reading."""
@@ -164,9 +169,12 @@ def _check_can_write(self):
raise io.UnsupportedOperation("File not open for writing")
def _check_can_seek(self):
- if not self.seekable():
+ if not self.readable():
raise io.UnsupportedOperation("Seeking is only supported "
"on files open for reading")
+ if hasattr(self._fp, "seekable") and not self._fp.seekable():
+ raise io.UnsupportedOperation("The underlying file object "
+ "does not support seeking")
# Fill the readahead buffer if it is empty. Returns False on EOF.
def _fill_buffer(self):
View
9 test_bz2file.py
@@ -352,6 +352,15 @@ def testSeekable(self):
bz2f.close()
self.assertRaises(ValueError, bz2f.seekable)
+ src = BytesIO(self.DATA)
+ src.seekable = lambda: False
+ bz2f = BZ2File(fileobj=src)
+ try:
+ self.assertFalse(bz2f.seekable())
+ finally:
+ bz2f.close()
+ self.assertRaises(ValueError, bz2f.seekable)
+
def testReadable(self):
bz2f = BZ2File(fileobj=BytesIO(self.DATA))
try:

0 comments on commit 52983d0

Please sign in to comment.