[pypy-commit] pypy py3.3: Implement the opener parameter of io.open()

amauryfa noreply at buildbot.pypy.org
Mon Dec 29 21:28:40 CET 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r75148:8af0b2050bd1
Date: 2014-12-21 17:33 +0100
http://bitbucket.org/pypy/pypy/changeset/8af0b2050bd1/

Log:	Implement the opener parameter of io.open()

diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty, GetSetProperty
 from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import wrap_oserror, wrap_oserror2
 from rpython.rlib.rarithmetic import r_longlong
 from rpython.rlib.rstring import StringBuilder
 from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC
@@ -131,7 +132,7 @@
         return space.wrap(self)
 
     @unwrap_spec(mode=str, closefd=int)
-    def descr_init(self, space, w_name, mode='r', closefd=True):
+    def descr_init(self, space, w_name, mode='r', closefd=True, w_opener=None):
         if space.isinstance_w(w_name, space.w_float):
             raise OperationError(space.w_TypeError, space.wrap(
                 "integer argument expected, got float"))
@@ -159,7 +160,7 @@
                     # else: pass
                 self.fd = fd
                 self.closefd = bool(closefd)
-            else:
+            elif space.is_none(w_opener):
                 self.closefd = True
                 if not closefd:
                     raise OperationError(space.w_ValueError, space.wrap(
@@ -175,6 +176,17 @@
                                         exception_name='w_IOError')
                 finally:
                     fd_is_own = True
+            else:
+                w_fd = space.call_function(w_opener, w_name, space.wrap(flags))
+                try:
+                    self.fd = space.int_w(w_fd)
+                except OperationError as e:
+                    if not e.match(space, space.w_TypeError):
+                        raise
+                    raise oefmt(space.w_TypeError,
+                                "expected integer from opener")
+                finally:
+                    fd_is_own = True
 
             self._dircheck(space, w_name)
             space.setattr(self, space.wrap("name"), w_name)
diff --git a/pypy/module/_io/interp_io.py b/pypy/module/_io/interp_io.py
--- a/pypy/module/_io/interp_io.py
+++ b/pypy/module/_io/interp_io.py
@@ -21,7 +21,7 @@
              encoding="str_or_None", errors="str_or_None",
              newline="str_or_None", closefd=bool)
 def open(space, w_file, mode="r", buffering=-1, encoding=None, errors=None,
-    newline=None, closefd=True):
+         newline=None, closefd=True, w_opener=None):
     from pypy.module._io.interp_bufferedio import (W_BufferedRandom,
         W_BufferedWriter, W_BufferedReader)
 
@@ -87,8 +87,8 @@
             space.wrap("binary mode doesn't take a newline argument")
         )
     w_raw = space.call_function(
-        space.gettypefor(W_FileIO), w_file, space.wrap(rawmode), space.wrap(closefd)
-    )
+        space.gettypefor(W_FileIO), w_file, space.wrap(rawmode),
+        space.wrap(closefd), w_opener)
 
     isatty = space.is_true(space.call_method(w_raw, "isatty"))
     line_buffering = buffering == 1 or (buffering < 0 and isatty)
diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py
--- a/pypy/module/_io/test/test_io.py
+++ b/pypy/module/_io/test/test_io.py
@@ -229,6 +229,16 @@
                 assert g.name == f.fileno()
                 assert g.raw.name == f.fileno()
 
+    def test_opener(self):
+        import _io, os
+        with _io.open(self.tmpfile, "w") as f:
+            f.write("egg\n")
+        fd = os.open(self.tmpfile, os.O_RDONLY)
+        def opener(path, flags):
+            return fd
+        with _io.open("non-existent", "r", opener=opener) as f:
+            assert f.read() == "egg\n"
+
     def test_seek_and_tell(self):
         import _io
 


More information about the pypy-commit mailing list