Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r91845:4d0f184d43a2
Date: 2017-07-08 18:10 +0200
http://bitbucket.org/pypy/pypy/changeset/4d0f184d43a2/

Log:    Accept buffer objects as filenames. It often works like the
        corresponding bytes object. Of course, os.listdir() is an exception
        to that rule.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1641,9 +1641,13 @@
         return fsdecode(space, w_obj)
 
     def fsencode_w(self, w_obj):
-        from rpython.rlib import rstring
         if self.isinstance_w(w_obj, self.w_unicode):
             w_obj = self.fsencode(w_obj)
+        return self.bytesbuf0_w(w_obj)
+
+    def bytesbuf0_w(self, w_obj):
+        # Like bytes0_w(), but also accept a read-only buffer.
+        from rpython.rlib import rstring
         try:
             result = self.bytes_w(w_obj)
         except OperationError as e:
diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -66,7 +66,7 @@
         self.w_obj = w_obj
 
     def as_bytes(self):
-        return self.space.bytes0_w(self.w_obj)
+        return self.space.bytesbuf0_w(self.w_obj)
 
     def as_unicode(self):
         return self.space.fsdecode_w(self.w_obj)
@@ -85,7 +85,7 @@
             fname = FileEncoder(space, w_fname)
             return func(fname, *args)
         else:
-            fname = space.bytes0_w(w_fname)
+            fname = space.bytesbuf0_w(w_fname)
             return func(fname, *args)
     return dispatch
 
@@ -746,7 +746,7 @@
             fullpath = rposix.getfullpathname(path)
             w_fullpath = space.newunicode(fullpath)
         else:
-            path = space.bytes0_w(w_path)
+            path = space.bytesbuf0_w(w_path)
             fullpath = rposix.getfullpathname(path)
             w_fullpath = space.newbytes(fullpath)
     except OSError as e:
@@ -931,6 +931,8 @@
     if space.is_none(w_path):
         w_path = space.newunicode(u".")
     if space.isinstance_w(w_path, space.w_bytes):
+        # XXX CPython doesn't follow this path either if w_path is,
+        # for example, a memoryview or another buffer type
         dirname = space.bytes0_w(w_path)
         try:
             result = rposix.listdir(dirname)
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -334,6 +334,14 @@
         expected = b'caf%E9' if sys.platform == 'darwin' else b'caf\xe9'
         assert expected in result
 
+    def test_listdir_memoryview_returns_unicode(self):
+        # XXX unknown why CPython has this behaviour
+        bytes_dir = self.bytes_dir
+        os, posix = self.os, self.posix
+        result1 = posix.listdir(bytes_dir)              # -> list of bytes
+        result2 = posix.listdir(memoryview(bytes_dir))  # -> list of unicodes
+        assert [os.fsencode(x) for x in result2] == result1
+
     def test_fdlistdir(self):
         posix = self.posix
         dirfd = posix.open('.', posix.O_RDONLY)
@@ -1141,6 +1149,12 @@
             with open(dest) as f:
                 data = f.read()
                 assert data == "who cares?"
+            #
+            posix.unlink(dest)
+            posix.symlink(memoryview(bytes_dir + b"/somefile"), dest)
+            with open(dest) as f:
+                data = f.read()
+                assert data == "who cares?"
 
         # XXX skip test if dir_fd is unsupported
         def test_symlink_fd(self):
@@ -1293,6 +1307,15 @@
             s2.close()
             s1.close()
 
+        def test_filename_can_be_a_buffer(self):
+            import posix, sys
+            fsencoding = sys.getfilesystemencoding()
+            pdir = (self.pdir + '/file1').encode(fsencoding)
+            fd = posix.open(pdir, posix.O_RDONLY)
+            posix.close(fd)
+            fd = posix.open(memoryview(pdir), posix.O_RDONLY)
+            posix.close(fd)
+
     if sys.platform.startswith('linux'):
         def test_sendfile_no_offset(self):
             import _socket, posix
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to