Author: Ronan Lamy <[email protected]>
Branch: follow_symlinks
Changeset: r83513:c6615ca37d32
Date: 2016-04-04 19:55 +0100
http://bitbucket.org/pypy/pypy/changeset/c6615ca37d32/
Log: Allow specifying path as file descriptor in os.listdir()
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
@@ -744,35 +744,56 @@
raise wrap_oserror(space, e)
-@unwrap_spec(w_dirname=WrappedDefault(u"."))
-def listdir(space, w_dirname):
- """Return a list containing the names of the entries in the directory.
+@unwrap_spec(w_path=WrappedDefault(u"."))
+def listdir(space, w_path):
+ """listdir(path='.') -> list_of_filenames
-\tpath: path of directory to list
+Return a list containing the names of the files in the directory.
+The list is in arbitrary order. It does not include the special
+entries '.' and '..' even if they are present in the directory.
-The list is in arbitrary order. It does not include the special
-entries '.' and '..' even if they are present in the directory."""
+path can be specified as either str or bytes. If path is bytes,
+ the filenames returned will also be bytes; in all other circumstances
+ the filenames returned will be str.
+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.isinstance_w(w_path, space.w_bytes):
+ dirname = space.str0_w(w_path)
+ try:
+ result = rposix.listdir(dirname)
+ except OSError as e:
+ raise wrap_oserror2(space, e, w_path)
+ return space.newlist_bytes(result)
try:
- if space.isinstance_w(w_dirname, space.w_unicode):
- dirname = FileEncoder(space, w_dirname)
+ path = space.fsencode_w(w_path)
+ except OperationError as operr:
+ if not rposix.HAVE_FDOPENDIR:
+ raise oefmt(space.w_TypeError,
+ "listdir: illegal type for path argument")
+ if not space.isinstance_w(w_path, space.w_int):
+ raise oefmt(space.w_TypeError,
+ "argument should be string, bytes or integer, not %T", w_path)
+ fd = unwrap_fd(space, w_path)
+ try:
+ result = rposix.fdlistdir(fd)
+ except OSError as e:
+ raise wrap_oserror2(space, e, w_path)
+ else:
+ dirname = FileEncoder(space, w_path)
+ try:
result = rposix.listdir(dirname)
- len_result = len(result)
- result_w = [None] * len_result
- for i in range(len_result):
- if _WIN32:
- result_w[i] = space.wrap(result[i])
- else:
- w_bytes = space.wrapbytes(result[i])
- result_w[i] = space.fsdecode(w_bytes)
- return space.newlist(result_w)
+ except OSError as e:
+ raise wrap_oserror2(space, e, w_path)
+ len_result = len(result)
+ result_w = [None] * len_result
+ for i in range(len_result):
+ if _WIN32:
+ result_w[i] = space.wrap(result[i])
else:
- dirname = space.str0_w(w_dirname)
- result = rposix.listdir(dirname)
- # The list comprehension is a workaround for an obscure translation
- # bug.
- return space.newlist_bytes([x for x in result])
- except OSError, e:
- raise wrap_oserror2(space, e, w_dirname)
+ w_bytes = space.wrapbytes(result[i])
+ result_w[i] = space.fsdecode(w_bytes)
+ return space.newlist(result_w)
def pipe(space):
"Create a pipe. Returns (read_end, write_end)."
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit