Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r86397:9629ba2a4200
Date: 2016-08-22 10:27 +0200
http://bitbucket.org/pypy/pypy/changeset/9629ba2a4200/

Log:    hg merge py3k

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
@@ -838,8 +838,7 @@
             raise wrap_oserror(space, e)
 
 
-@unwrap_spec(w_path=WrappedDefault(u"."))
-def listdir(space, w_path):
+def listdir(space, w_path=None):
     """listdir(path='.') -> list_of_filenames
 
 Return a list containing the names of the files in the directory.
@@ -852,6 +851,8 @@
 On some platforms, path may also be specified as an open file descriptor;
   the file descriptor must refer to a directory.
   If this functionality is unavailable, using it raises NotImplementedError."""
+    if space.is_none(w_path):
+        w_path = space.newunicode(u".")
     if space.isinstance_w(w_path, space.w_bytes):
         dirname = space.str0_w(w_path)
         try:
@@ -869,9 +870,9 @@
                 "listdir: illegal type for path argument")
         fd = unwrap_fd(space, w_path, "string, bytes or integer")
         try:
-            result = rposix.fdlistdir(fd)
+            result = rposix.fdlistdir(os.dup(fd))
         except OSError as e:
-            raise wrap_oserror2(space, e, w_path)
+            raise wrap_oserror(space, e)
     else:
         dirname = FileEncoder(space, w_path)
         try:
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
@@ -313,7 +313,7 @@
 
     def test_listdir_default(self):
         posix = self.posix
-        assert posix.listdir() == posix.listdir('.')
+        assert posix.listdir() == posix.listdir('.') == posix.listdir(None)
 
     def test_listdir_bytes(self):
         import sys
@@ -325,6 +325,17 @@
         expected = b'caf%E9' if sys.platform == 'darwin' else b'caf\xe9'
         assert expected in result
 
+    def test_fdlistdir(self):
+        posix = self.posix
+        dirfd = posix.open('.', posix.O_RDONLY)
+        lst1 = posix.listdir(dirfd)   # does not close dirfd
+        lst2 = posix.listdir('.')
+        assert lst1 == lst2
+        #
+        lst3 = posix.listdir(dirfd)   # rewinddir() was used
+        assert lst3 == lst1
+        posix.close(dirfd)
+
     def test_undecodable_filename(self):
         import sys
         posix = self.posix
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -620,15 +620,18 @@
         [rffi.CCHARP], DIRP, save_err=rffi.RFFI_SAVE_ERRNO)
     c_fdopendir = external('fdopendir',
         [rffi.INT], DIRP, save_err=rffi.RFFI_SAVE_ERRNO)
+    c_rewinddir = external('rewinddir',
+        [DIRP], lltype.Void, releasegil=False)
     # XXX macro=True is hack to make sure we get the correct kind of
     # dirent struct (which depends on defines)
     c_readdir = external('readdir', [DIRP], DIRENTP,
                          macro=True, save_err=rffi.RFFI_FULL_ERRNO_ZERO)
     c_closedir = external('closedir', [DIRP], rffi.INT, releasegil=False)
+    c_dirfd = external('dirfd', [DIRP], rffi.INT, releasegil=False)
 else:
     dirent_config = {}
 
-def _listdir(dirp):
+def _listdir(dirp, rewind=False):
     result = []
     while True:
         direntp = c_readdir(dirp)
@@ -639,6 +642,8 @@
         name = rffi.charp2str(namep)
         if name != '.' and name != '..':
             result.append(name)
+    if rewind:
+        c_rewinddir(dirp)
     c_closedir(dirp)
     if error:
         raise OSError(error, "readdir failed")
@@ -649,12 +654,16 @@
     Like listdir(), except that the directory is specified as an open
     file descriptor.
 
-    Note: fdlistdir() closes the file descriptor.
+    Note: fdlistdir() closes the file descriptor.  To emulate the
+    Python 3.x 'os.opendir(dirfd)', you must first duplicate the
+    file descriptor.
     """
     dirp = c_fdopendir(dirfd)
     if not dirp:
-        raise OSError(get_saved_errno(), "opendir failed")
-    return _listdir(dirp)
+        error = get_saved_errno()
+        c_close(dirfd)
+        raise OSError(error, "opendir failed")
+    return _listdir(dirp, rewind=True)
 
 @replace_os_function('listdir')
 @specialize.argtype(0)
@@ -1791,12 +1800,7 @@
 # Support for f... and ...at families of POSIX functions
 
 class CConfig:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=['sys/stat.h',
-                  'sys/time.h',
-                  'unistd.h',
-                  'fcntl.h'],
-    )
+    _compilation_info_ = eci
     for _name in """faccessat fchdir fchmod fchmodat fchown fchownat fexecve
             fdopendir fpathconf fstat fstatat fstatvfs ftruncate
             futimens futimes futimesat linkat chflags lchflags lchmod lchown
diff --git a/rpython/rlib/rposix_scandir.py b/rpython/rlib/rposix_scandir.py
--- a/rpython/rlib/rposix_scandir.py
+++ b/rpython/rlib/rposix_scandir.py
@@ -1,6 +1,6 @@
 from rpython.rlib import rposix
 from rpython.rlib.objectmodel import specialize
-from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
 
 
 @specialize.argtype(0)
@@ -17,21 +17,22 @@
 def closedir(dirp):
     rposix.c_closedir(dirp)
 
+NULL_DIRP = lltype.nullptr(rposix.DIRENT)
+
 def nextentry(dirp):
     """Read the next entry and returns an opaque object.
     Use the methods has_xxx() and get_xxx() to read from that
     opaque object.  The opaque object is valid until the next
     time nextentry() or closedir() is called.  This may raise
-    StopIteration, or OSError.  Note that this doesn't filter
-    out the "." and ".." entries.
+    OSError, or return a NULL pointer when exhausted.  Note
+    that this doesn't filter out the "." and ".." entries.
     """
     direntp = rposix.c_readdir(dirp)
     if direntp:
-        return direntp
-    error = rposix.get_saved_errno()
-    if error:
-        raise OSError(error, "readdir failed")
-    raise StopIteration
+        error = rposix.get_saved_errno()
+        if error:
+            raise OSError(error, "readdir failed")
+    return direntp
 
 def has_name_bytes(direntp):
     return True
@@ -40,20 +41,12 @@
     namep = rffi.cast(rffi.CCHARP, direntp.c_d_name)
     return rffi.charp2str(namep)
 
-DT_UNKNOWN = rposix.dirent_config.get('DT_UNKNOWN', None)
-DT_REG = rposix.dirent_config.get('DT_REG', None)
-DT_DIR = rposix.dirent_config.get('DT_DIR', None)
-DT_LNK = rposix.dirent_config.get('DT_LNK', None)
+DT_UNKNOWN = rposix.dirent_config.get('DT_UNKNOWN', 0)
+DT_REG = rposix.dirent_config.get('DT_REG', 255)
+DT_DIR = rposix.dirent_config.get('DT_DIR', 255)
+DT_LNK = rposix.dirent_config.get('DT_LNK', 255)
 
-def has_type(direntp):
-    return (DT_UNKNOWN is not None and
-            rffi.getintfield(direntp, 'c_d_type') != DT_UNKNOWN)
-
-def type_is_regular(direntp):
-    return rffi.getintfield(direntp, 'c_d_type') == DT_REG
-
-def type_is_dir(direntp):
-    return rffi.getintfield(direntp, 'c_d_type') == DT_DIR
-
-def type_is_link(direntp):
-    return rffi.getintfield(direntp, 'c_d_type') == DT_LNK
+def get_known_type(direntp):
+    if rposix.HAVE_D_TYPE:
+        return rffi.getintfield(direntp, 'c_d_type')
+    return DT_UNKNOWN
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -552,6 +552,14 @@
     # Note: fdlistdir() always closes dirfd
     assert result == ['file']
 
+@rposix_requires('fdlistdir')
+def test_fdlistdir_rewinddir(tmpdir):
+    tmpdir.join('file').write('text')
+    dirfd = os.open(str(tmpdir), os.O_RDONLY)
+    result1 = rposix.fdlistdir(os.dup(dirfd))
+    result2 = rposix.fdlistdir(dirfd)
+    assert result1 == result2 == ['file']
+
 @rposix_requires('symlinkat')
 def test_symlinkat(tmpdir):
     tmpdir.join('file').write('text')
diff --git a/rpython/rlib/test/test_rposix_scandir.py 
b/rpython/rlib/test/test_rposix_scandir.py
--- a/rpython/rlib/test/test_rposix_scandir.py
+++ b/rpython/rlib/test/test_rposix_scandir.py
@@ -10,9 +10,8 @@
         scan = rposix_scandir.opendir('/')
         found = []
         while True:
-            try:
-                p = rposix_scandir.nextentry(scan)
-            except StopIteration:
+            p = rposix_scandir.nextentry(scan)
+            if not p:
                 break
             assert rposix_scandir.has_name_bytes(p)
             found.append(rposix_scandir.get_name_bytes(p))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to