[pypy-commit] pypy py3.5-scandir: hg merge py3.5
arigo
pypy.commits at gmail.com
Mon Aug 22 04:33:16 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5-scandir
Changeset: r86398:1abeaf52ade5
Date: 2016-08-22 10:30 +0200
http://bitbucket.org/pypy/pypy/changeset/1abeaf52ade5/
Log: hg merge py3.5
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)
- at 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,6 +620,8 @@
[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,
@@ -629,7 +631,7 @@
else:
dirent_config = {}
-def _listdir(dirp):
+def _listdir(dirp, rewind=False):
result = []
while True:
direntp = c_readdir(dirp)
@@ -640,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")
@@ -650,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)
@@ -1792,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/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']
+ at 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')
More information about the pypy-commit
mailing list