This is an automated email from the ASF dual-hosted git repository.
wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 524b522 ARROW-2218: [Python] PythonFile should infer mode when not
given
524b522 is described below
commit 524b5221d2c977f2fa8284ed72d6bbb51dedcb69
Author: Antoine Pitrou <[email protected]>
AuthorDate: Wed Feb 28 14:04:49 2018 -0500
ARROW-2218: [Python] PythonFile should infer mode when not given
Author: Antoine Pitrou <[email protected]>
Closes #1674 from pitrou/ARROW-2218-infer-python-file-mode and squashes the
following commits:
a5d704e8 <Antoine Pitrou> ARROW-2218: PythonFile should infer mode when
not given
---
python/pyarrow/io-hdfs.pxi | 2 --
python/pyarrow/io.pxi | 14 +++++++++++++-
python/pyarrow/lib.pxd | 1 +
python/pyarrow/tests/test_io.py | 39 +++++++++++++++++++++++++++++++++++++++
4 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/python/pyarrow/io-hdfs.pxi b/python/pyarrow/io-hdfs.pxi
index dc6ba23..31c0437 100644
--- a/python/pyarrow/io-hdfs.pxi
+++ b/python/pyarrow/io-hdfs.pxi
@@ -480,7 +480,5 @@ cdef class HdfsFile(NativeFile):
object mode
object parent
- cdef object __weakref__
-
def __dealloc__(self):
self.parent = None
diff --git a/python/pyarrow/io.pxi b/python/pyarrow/io.pxi
index 8b364dc..0b444cd 100644
--- a/python/pyarrow/io.pxi
+++ b/python/pyarrow/io.pxi
@@ -410,9 +410,21 @@ cdef class PythonFile(NativeFile):
cdef:
object handle
- def __cinit__(self, handle, mode='w'):
+ def __cinit__(self, handle, mode=None):
self.handle = handle
+ if mode is None:
+ try:
+ mode = handle.mode
+ except AttributeError:
+ # Not all file-like objects have a mode attribute
+ # (e.g. BytesIO)
+ try:
+ mode = 'w' if handle.writable() else 'r'
+ except AttributeError:
+ raise ValueError("could not infer open mode for file-like "
+ "object %r, please pass it explicitly"
+ % (handle,))
if mode.startswith('w'):
self.wr_file.reset(new PyOutputStream(handle))
self.is_writable = True
diff --git a/python/pyarrow/lib.pxd b/python/pyarrow/lib.pxd
index 31732a6..e4d574f 100644
--- a/python/pyarrow/lib.pxd
+++ b/python/pyarrow/lib.pxd
@@ -337,6 +337,7 @@ cdef class NativeFile:
bint is_writable
readonly bint closed
bint own_file
+ object __weakref__
# By implementing these "virtual" functions (all functions in Cython
# extension classes are technically virtual in the C++ sense) we can expose
diff --git a/python/pyarrow/tests/test_io.py b/python/pyarrow/tests/test_io.py
index 736020f..d269ad0 100644
--- a/python/pyarrow/tests/test_io.py
+++ b/python/pyarrow/tests/test_io.py
@@ -21,6 +21,7 @@ import gc
import os
import pytest
import sys
+import weakref
import numpy as np
@@ -124,6 +125,44 @@ def test_bytes_reader_retains_parent_reference():
assert buf.to_pybytes() == b'sample'
assert buf.parent is not None
+
+def test_python_file_implicit_mode(tmpdir):
+ path = os.path.join(str(tmpdir), 'foo.txt')
+ with open(path, 'wb') as f:
+ pf = pa.PythonFile(f)
+ assert pf.writable()
+ assert not pf.readable()
+ assert not pf.seekable() # PyOutputStream isn't seekable
+ f.write(b'foobar\n')
+
+ with open(path, 'rb') as f:
+ pf = pa.PythonFile(f)
+ assert pf.readable()
+ assert not pf.writable()
+ assert pf.seekable()
+ assert pf.read() == b'foobar\n'
+
+ bio = BytesIO()
+ pf = pa.PythonFile(bio)
+ assert pf.writable()
+ assert not pf.readable()
+ assert not pf.seekable()
+ pf.write(b'foobar\n')
+ assert bio.getvalue() == b'foobar\n'
+
+
+def test_python_file_closing():
+ bio = BytesIO()
+ pf = pa.PythonFile(bio)
+ wr = weakref.ref(pf)
+ del pf
+ assert wr() is None # object was destroyed
+ assert not bio.closed
+ pf = pa.PythonFile(bio)
+ pf.close()
+ assert bio.closed
+
+
# ----------------------------------------------------------------------
# Buffers
--
To stop receiving notification emails like this one, please contact
[email protected].