Support the whence parameter in GFile's .seek() to match Python's file
semantics. Also rename position to offset to match Python's file parameter naming. Fixes numpy.load() from gfile. Change: 153655962
This commit is contained in:
parent
7821dbee6a
commit
fd14d0ac6a
tensorflow
@ -27,6 +27,7 @@ import uuid
|
||||
from tensorflow.python import pywrap_tensorflow
|
||||
from tensorflow.python.framework import errors
|
||||
from tensorflow.python.util import compat
|
||||
from tensorflow.python.util import deprecation
|
||||
|
||||
|
||||
class FileIO(object):
|
||||
@ -121,11 +122,51 @@ class FileIO(object):
|
||||
return self._prepare_value(
|
||||
pywrap_tensorflow.ReadFromStream(self._read_buf, length, status))
|
||||
|
||||
def seek(self, position):
|
||||
"""Seeks to the position in the file."""
|
||||
@deprecation.deprecated_args(
|
||||
None,
|
||||
"position is deprecated in favor of the offset argument.",
|
||||
"position")
|
||||
def seek(self, offset=None, whence=0, position=None):
|
||||
# TODO(jhseu): Delete later. Used to omit `position` from docs.
|
||||
# pylint: disable=g-doc-args
|
||||
"""Seeks to the offset in the file.
|
||||
|
||||
Args:
|
||||
offset: The byte count relative to the whence argument.
|
||||
whence: Valid values for whence are:
|
||||
0: start of the file (default)
|
||||
1: relative to the current position of the file
|
||||
2: relative to the end of file. offset is usually negative.
|
||||
"""
|
||||
# pylint: enable=g-doc-args
|
||||
self._preread_check()
|
||||
# We needed to make offset a keyword argument for backwards-compatibility.
|
||||
# This check exists so that we can convert back to having offset be a
|
||||
# positional argument.
|
||||
# TODO(jhseu): Make `offset` a positional argument after `position` is
|
||||
# deprecated.
|
||||
if offset is None and position is None:
|
||||
raise TypeError("seek(): offset argument required")
|
||||
if offset is not None and position is not None:
|
||||
raise TypeError("seek(): offset and position may not be set "
|
||||
"simultaneously.")
|
||||
|
||||
if position is not None:
|
||||
offset = position
|
||||
|
||||
with errors.raise_exception_on_not_ok_status() as status:
|
||||
ret_status = self._read_buf.Seek(position)
|
||||
if whence == 0:
|
||||
pass
|
||||
elif whence == 1:
|
||||
offset += self.tell()
|
||||
elif whence == 2:
|
||||
offset += self.size()
|
||||
else:
|
||||
raise errors.InvalidArgumentError(
|
||||
None, None,
|
||||
"Invalid whence argument: {}. Valid values are 0, 1, or 2."
|
||||
.format(whence))
|
||||
ret_status = self._read_buf.Seek(offset)
|
||||
pywrap_tensorflow.Set_TF_Status_from_Status(status, ret_status)
|
||||
|
||||
def readline(self):
|
||||
|
@ -392,6 +392,40 @@ class FileIoTest(test.TestCase):
|
||||
with self.assertRaises(errors.InvalidArgumentError):
|
||||
f.seek(-1)
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
f.seek()
|
||||
|
||||
# TODO(jhseu): Delete after position deprecation.
|
||||
with self.assertRaises(TypeError):
|
||||
f.seek(offset=0, position=0)
|
||||
f.seek(position=9)
|
||||
self.assertEqual(9, f.tell())
|
||||
self.assertEqual("testing2\n", f.readline())
|
||||
|
||||
def testSeekFromWhat(self):
|
||||
file_path = os.path.join(self._base_dir, "temp_file")
|
||||
with file_io.FileIO(file_path, mode="r+") as f:
|
||||
f.write("testing1\ntesting2\ntesting3\n\ntesting5")
|
||||
self.assertEqual("testing1\n", f.readline())
|
||||
self.assertEqual(9, f.tell())
|
||||
|
||||
# Seek to 18
|
||||
f.seek(9, 1)
|
||||
self.assertEqual(18, f.tell())
|
||||
self.assertEqual("testing3\n", f.readline())
|
||||
|
||||
# Seek back to 9
|
||||
f.seek(9, 0)
|
||||
self.assertEqual(9, f.tell())
|
||||
self.assertEqual("testing2\n", f.readline())
|
||||
|
||||
f.seek(-f.size(), 2)
|
||||
self.assertEqual(0, f.tell())
|
||||
self.assertEqual("testing1\n", f.readline())
|
||||
|
||||
with self.assertRaises(errors.InvalidArgumentError):
|
||||
f.seek(0, 3)
|
||||
|
||||
def testReadingIterator(self):
|
||||
file_path = os.path.join(self._base_dir, "temp_file")
|
||||
data = ["testing1\n", "testing2\n", "testing3\n", "\n", "testing5"]
|
||||
|
@ -41,7 +41,7 @@ tf_class {
|
||||
}
|
||||
member_method {
|
||||
name: "seek"
|
||||
argspec: "args=[\'self\', \'position\'], varargs=None, keywords=None, defaults=None"
|
||||
argspec: "args=[], varargs=args, keywords=kwargs, defaults=None"
|
||||
}
|
||||
member_method {
|
||||
name: "size"
|
||||
|
@ -41,7 +41,7 @@ tf_class {
|
||||
}
|
||||
member_method {
|
||||
name: "seek"
|
||||
argspec: "args=[\'self\', \'position\'], varargs=None, keywords=None, defaults=None"
|
||||
argspec: "args=[], varargs=args, keywords=kwargs, defaults=None"
|
||||
}
|
||||
member_method {
|
||||
name: "size"
|
||||
|
@ -41,7 +41,7 @@ tf_class {
|
||||
}
|
||||
member_method {
|
||||
name: "seek"
|
||||
argspec: "args=[\'self\', \'position\'], varargs=None, keywords=None, defaults=None"
|
||||
argspec: "args=[], varargs=args, keywords=kwargs, defaults=None"
|
||||
}
|
||||
member_method {
|
||||
name: "size"
|
||||
|
Loading…
Reference in New Issue
Block a user