mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update os.py from 3.13.5 (#6076)
* Update `os.py` from 3.13.5 * Set availablity of some `os` functions * revert some cfg * Mark more failing tests
This commit is contained in:
1 parent
4ae5a1f894
commit
133aada0b7
3 files changed
+827
-113
No files matched your search
@@ -110,6 +110,7 @@ if _exists("_have_functions"):
|
||||
_add("HAVE_FCHMODAT", "chmod")
|
||||
_add("HAVE_FCHOWNAT", "chown")
|
||||
_add("HAVE_FSTATAT", "stat")
|
||||
_add("HAVE_LSTAT", "lstat")
|
||||
_add("HAVE_FUTIMESAT", "utime")
|
||||
_add("HAVE_LINKAT", "link")
|
||||
_add("HAVE_MKDIRAT", "mkdir")
|
||||
@@ -131,6 +132,7 @@ if _exists("_have_functions"):
|
||||
_set = set()
|
||||
_add("HAVE_FCHDIR", "chdir")
|
||||
_add("HAVE_FCHMOD", "chmod")
|
||||
_add("MS_WINDOWS", "chmod")
|
||||
_add("HAVE_FCHOWN", "chown")
|
||||
_add("HAVE_FDOPENDIR", "listdir")
|
||||
_add("HAVE_FDOPENDIR", "scandir")
|
||||
@@ -171,6 +173,7 @@ if _exists("_have_functions"):
|
||||
_add("HAVE_FSTATAT", "stat")
|
||||
_add("HAVE_LCHFLAGS", "chflags")
|
||||
_add("HAVE_LCHMOD", "chmod")
|
||||
_add("MS_WINDOWS", "chmod")
|
||||
if _exists("lchown"): # mac os x10.3
|
||||
_add("HAVE_LCHOWN", "chown")
|
||||
_add("HAVE_LINKAT", "link")
|
||||
@@ -279,6 +282,10 @@ def renames(old, new):
|
||||
|
||||
__all__.extend(["makedirs", "removedirs", "renames"])
|
||||
|
||||
# Private sentinel that makes walk() classify all symlinks and junctions as
|
||||
# regular files.
|
||||
_walk_symlinks_as_files = object()
|
||||
|
||||
def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
"""Directory tree generator.
|
||||
|
||||
@@ -331,12 +338,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
|
||||
import os
|
||||
from os.path import join, getsize
|
||||
for root, dirs, files in os.walk('python/Lib/email'):
|
||||
for root, dirs, files in os.walk('python/Lib/xml'):
|
||||
print(root, "consumes ")
|
||||
print(sum(getsize(join(root, name)) for name in files), end=" ")
|
||||
print("bytes in", len(files), "non-directory files")
|
||||
if 'CVS' in dirs:
|
||||
dirs.remove('CVS') # don't visit CVS directories
|
||||
if '__pycache__' in dirs:
|
||||
dirs.remove('__pycache__') # don't visit __pycache__ directories
|
||||
|
||||
"""
|
||||
sys.audit("os.walk", top, topdown, onerror, followlinks)
|
||||
@@ -380,7 +387,10 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
break
|
||||
|
||||
try:
|
||||
is_dir = entry.is_dir()
|
||||
if followlinks is _walk_symlinks_as_files:
|
||||
is_dir = entry.is_dir(follow_symlinks=False) and not entry.is_junction()
|
||||
else:
|
||||
is_dir = entry.is_dir()
|
||||
except OSError:
|
||||
# If is_dir() raises an OSError, consider the entry not to
|
||||
# be a directory, same behaviour as os.path.isdir().
|
||||
@@ -459,34 +469,69 @@ if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
|
||||
Example:
|
||||
|
||||
import os
|
||||
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
|
||||
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
|
||||
print(root, "consumes", end="")
|
||||
print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
|
||||
end="")
|
||||
print("bytes in", len(files), "non-directory files")
|
||||
if 'CVS' in dirs:
|
||||
dirs.remove('CVS') # don't visit CVS directories
|
||||
if '__pycache__' in dirs:
|
||||
dirs.remove('__pycache__') # don't visit __pycache__ directories
|
||||
"""
|
||||
sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
|
||||
top = fspath(top)
|
||||
# Note: To guard against symlink races, we use the standard
|
||||
# lstat()/open()/fstat() trick.
|
||||
if not follow_symlinks:
|
||||
orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
|
||||
topfd = open(top, O_RDONLY | O_NONBLOCK, dir_fd=dir_fd)
|
||||
stack = [(_fwalk_walk, (True, dir_fd, top, top, None))]
|
||||
isbytes = isinstance(top, bytes)
|
||||
try:
|
||||
if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
|
||||
path.samestat(orig_st, stat(topfd)))):
|
||||
yield from _fwalk(topfd, top, isinstance(top, bytes),
|
||||
topdown, onerror, follow_symlinks)
|
||||
while stack:
|
||||
yield from _fwalk(stack, isbytes, topdown, onerror, follow_symlinks)
|
||||
finally:
|
||||
close(topfd)
|
||||
# Close any file descriptors still on the stack.
|
||||
while stack:
|
||||
action, value = stack.pop()
|
||||
if action == _fwalk_close:
|
||||
close(value)
|
||||
|
||||
def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks):
|
||||
# Each item in the _fwalk() stack is a pair (action, args).
|
||||
_fwalk_walk = 0 # args: (isroot, dirfd, toppath, topname, entry)
|
||||
_fwalk_yield = 1 # args: (toppath, dirnames, filenames, topfd)
|
||||
_fwalk_close = 2 # args: dirfd
|
||||
|
||||
def _fwalk(stack, isbytes, topdown, onerror, follow_symlinks):
|
||||
# Note: This uses O(depth of the directory tree) file descriptors: if
|
||||
# necessary, it can be adapted to only require O(1) FDs, see issue
|
||||
# #13734.
|
||||
|
||||
action, value = stack.pop()
|
||||
if action == _fwalk_close:
|
||||
close(value)
|
||||
return
|
||||
elif action == _fwalk_yield:
|
||||
yield value
|
||||
return
|
||||
assert action == _fwalk_walk
|
||||
isroot, dirfd, toppath, topname, entry = value
|
||||
try:
|
||||
if not follow_symlinks:
|
||||
# Note: To guard against symlink races, we use the standard
|
||||
# lstat()/open()/fstat() trick.
|
||||
if entry is None:
|
||||
orig_st = stat(topname, follow_symlinks=False, dir_fd=dirfd)
|
||||
else:
|
||||
orig_st = entry.stat(follow_symlinks=False)
|
||||
topfd = open(topname, O_RDONLY | O_NONBLOCK, dir_fd=dirfd)
|
||||
except OSError as err:
|
||||
if isroot:
|
||||
raise
|
||||
if onerror is not None:
|
||||
onerror(err)
|
||||
return
|
||||
stack.append((_fwalk_close, topfd))
|
||||
if not follow_symlinks:
|
||||
if isroot and not st.S_ISDIR(orig_st.st_mode):
|
||||
return
|
||||
if not path.samestat(orig_st, stat(topfd)):
|
||||
return
|
||||
|
||||
scandir_it = scandir(topfd)
|
||||
dirs = []
|
||||
nondirs = []
|
||||
@@ -512,31 +557,18 @@ if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
|
||||
|
||||
if topdown:
|
||||
yield toppath, dirs, nondirs, topfd
|
||||
else:
|
||||
stack.append((_fwalk_yield, (toppath, dirs, nondirs, topfd)))
|
||||
|
||||
for name in dirs if entries is None else zip(dirs, entries):
|
||||
try:
|
||||
if not follow_symlinks:
|
||||
if topdown:
|
||||
orig_st = stat(name, dir_fd=topfd, follow_symlinks=False)
|
||||
else:
|
||||
assert entries is not None
|
||||
name, entry = name
|
||||
orig_st = entry.stat(follow_symlinks=False)
|
||||
dirfd = open(name, O_RDONLY | O_NONBLOCK, dir_fd=topfd)
|
||||
except OSError as err:
|
||||
if onerror is not None:
|
||||
onerror(err)
|
||||
continue
|
||||
try:
|
||||
if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
|
||||
dirpath = path.join(toppath, name)
|
||||
yield from _fwalk(dirfd, dirpath, isbytes,
|
||||
topdown, onerror, follow_symlinks)
|
||||
finally:
|
||||
close(dirfd)
|
||||
|
||||
if not topdown:
|
||||
yield toppath, dirs, nondirs, topfd
|
||||
toppath = path.join(toppath, toppath[:0]) # Add trailing slash.
|
||||
if entries is None:
|
||||
stack.extend(
|
||||
(_fwalk_walk, (False, topfd, toppath + name, name, None))
|
||||
for name in dirs[::-1])
|
||||
else:
|
||||
stack.extend(
|
||||
(_fwalk_walk, (False, topfd, toppath + name, name, entry))
|
||||
for name, entry in zip(dirs[::-1], entries[::-1]))
|
||||
|
||||
__all__.append("fwalk")
|
||||
|
||||
@@ -1061,6 +1093,12 @@ def _fspath(path):
|
||||
else:
|
||||
raise TypeError("expected str, bytes or os.PathLike object, "
|
||||
"not " + path_type.__name__)
|
||||
except TypeError:
|
||||
if path_type.__fspath__ is None:
|
||||
raise TypeError("expected str, bytes or os.PathLike object, "
|
||||
"not " + path_type.__name__) from None
|
||||
else:
|
||||
raise
|
||||
if isinstance(path_repr, (str, bytes)):
|
||||
return path_repr
|
||||
else:
|
||||
@@ -1079,6 +1117,8 @@ class PathLike(abc.ABC):
|
||||
|
||||
"""Abstract base class for implementing the file system path protocol."""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
@abc.abstractmethod
|
||||
def __fspath__(self):
|
||||
"""Return the file system path representation of the object."""
|
||||
@@ -1128,3 +1168,17 @@ if name == 'nt':
|
||||
cookie,
|
||||
nt._remove_dll_directory
|
||||
)
|
||||
|
||||
|
||||
if _exists('sched_getaffinity') and sys._get_cpu_count_config() < 0:
|
||||
def process_cpu_count():
|
||||
"""
|
||||
Get the number of CPUs of the current process.
|
||||
|
||||
Return the number of logical CPUs usable by the calling thread of the
|
||||
current process. Return None if indeterminable.
|
||||
"""
|
||||
return len(sched_getaffinity(0))
|
||||
else:
|
||||
# Just an alias to cpu_count() (same docstring)
|
||||
process_cpu_count = cpu_count
|
||||
Vendored
+681
-57
File diff suppressed because it is too large.
Load diff
+50
-14
@@ -62,11 +62,14 @@ pub mod module {
|
||||
#[cfg(not(any(target_os = "redox", target_os = "freebsd")))]
|
||||
#[pyattr]
|
||||
use libc::O_DSYNC;
|
||||
|
||||
#[pyattr]
|
||||
use libc::{O_CLOEXEC, O_NONBLOCK, WNOHANG};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[pyattr]
|
||||
use libc::{O_EVTONLY, O_FSYNC, O_NOFOLLOW_ANY, O_SYMLINK};
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[pyattr]
|
||||
use libc::{O_NDELAY, O_NOCTTY};
|
||||
@@ -80,34 +83,49 @@ pub mod module {
|
||||
|
||||
#[pyattr]
|
||||
const EX_OK: i8 = exitcode::OK as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_USAGE: i8 = exitcode::USAGE as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_DATAERR: i8 = exitcode::DATAERR as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_NOINPUT: i8 = exitcode::NOINPUT as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_NOUSER: i8 = exitcode::NOUSER as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_NOHOST: i8 = exitcode::NOHOST as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_UNAVAILABLE: i8 = exitcode::UNAVAILABLE as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_SOFTWARE: i8 = exitcode::SOFTWARE as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_OSERR: i8 = exitcode::OSERR as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_OSFILE: i8 = exitcode::OSFILE as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_CANTCREAT: i8 = exitcode::CANTCREAT as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_IOERR: i8 = exitcode::IOERR as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_TEMPFAIL: i8 = exitcode::TEMPFAIL as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_PROTOCOL: i8 = exitcode::PROTOCOL as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_NOPERM: i8 = exitcode::NOPERM as i8;
|
||||
|
||||
#[pyattr]
|
||||
const EX_CONFIG: i8 = exitcode::CONFIG as i8;
|
||||
|
||||
@@ -122,6 +140,7 @@ pub mod module {
|
||||
))]
|
||||
#[pyattr]
|
||||
const SCHED_RR: i32 = libc::SCHED_RR;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "linux",
|
||||
@@ -133,6 +152,7 @@ pub mod module {
|
||||
))]
|
||||
#[pyattr]
|
||||
const SCHED_FIFO: i32 = libc::SCHED_FIFO;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "linux",
|
||||
@@ -143,9 +163,11 @@ pub mod module {
|
||||
))]
|
||||
#[pyattr]
|
||||
const SCHED_OTHER: i32 = libc::SCHED_OTHER;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[pyattr]
|
||||
const SCHED_IDLE: i32 = libc::SCHED_IDLE;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[pyattr]
|
||||
const SCHED_BATCH: i32 = libc::SCHED_BATCH;
|
||||
@@ -153,9 +175,11 @@ pub mod module {
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
|
||||
#[pyattr]
|
||||
const POSIX_SPAWN_OPEN: i32 = PosixSpawnFileActionIdentifier::Open as i32;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
|
||||
#[pyattr]
|
||||
const POSIX_SPAWN_CLOSE: i32 = PosixSpawnFileActionIdentifier::Close as i32;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
|
||||
#[pyattr]
|
||||
const POSIX_SPAWN_DUP2: i32 = PosixSpawnFileActionIdentifier::Dup2 as i32;
|
||||
@@ -1099,12 +1123,13 @@ pub mod module {
|
||||
vm.ctx.new_int(euid).into()
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android")))]
|
||||
#[pyfunction]
|
||||
fn setgid(gid: Gid, vm: &VirtualMachine) -> PyResult<()> {
|
||||
unistd::setgid(gid).map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android", target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn setegid(egid: Gid, vm: &VirtualMachine) -> PyResult<()> {
|
||||
unistd::setegid(egid).map_err(|err| err.into_pyexception(vm))
|
||||
@@ -1116,7 +1141,7 @@ pub mod module {
|
||||
.map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn setsid(vm: &VirtualMachine) -> PyResult<()> {
|
||||
unistd::setsid()
|
||||
@@ -1162,18 +1187,19 @@ pub mod module {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android")))]
|
||||
#[pyfunction]
|
||||
fn setuid(uid: Uid) -> nix::Result<()> {
|
||||
unistd::setuid(uid)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android", target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn seteuid(euid: Uid) -> nix::Result<()> {
|
||||
unistd::seteuid(euid)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android", target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn setreuid(ruid: Uid, euid: Uid) -> nix::Result<()> {
|
||||
let ret = unsafe { libc::setreuid(ruid.as_raw(), euid.as_raw()) };
|
||||
@@ -1271,7 +1297,7 @@ pub mod module {
|
||||
unistd::setresgid(rgid, egid, sgid).map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg(not(any(target_os = "wasi", target_os = "android", target_os = "redox")))]
|
||||
#[pyfunction]
|
||||
fn setregid(rgid: Gid, egid: Gid) -> nix::Result<()> {
|
||||
let ret = unsafe { libc::setregid(rgid.as_raw(), egid.as_raw()) };
|
||||
@@ -1602,9 +1628,14 @@ pub mod module {
|
||||
args.spawn(true, vm)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WIFSIGNALED")]
|
||||
fn wifsignaled(status: i32) -> bool {
|
||||
libc::WIFSIGNALED(status)
|
||||
#[pyfunction(name = "WCOREDUMP")]
|
||||
fn wcoredump(status: i32) -> bool {
|
||||
libc::WCOREDUMP(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WIFCONTINUED")]
|
||||
fn wifcontinued(status: i32) -> bool {
|
||||
libc::WIFCONTINUED(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WIFSTOPPED")]
|
||||
@@ -1612,14 +1643,19 @@ pub mod module {
|
||||
libc::WIFSTOPPED(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WIFSIGNALED")]
|
||||
fn wifsignaled(status: i32) -> bool {
|
||||
libc::WIFSIGNALED(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WIFEXITED")]
|
||||
fn wifexited(status: i32) -> bool {
|
||||
libc::WIFEXITED(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WTERMSIG")]
|
||||
fn wtermsig(status: i32) -> i32 {
|
||||
libc::WTERMSIG(status)
|
||||
#[pyfunction(name = "WEXITSTATUS")]
|
||||
fn wexitstatus(status: i32) -> i32 {
|
||||
libc::WEXITSTATUS(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WSTOPSIG")]
|
||||
@@ -1627,9 +1663,9 @@ pub mod module {
|
||||
libc::WSTOPSIG(status)
|
||||
}
|
||||
|
||||
#[pyfunction(name = "WEXITSTATUS")]
|
||||
fn wexitstatus(status: i32) -> i32 {
|
||||
libc::WEXITSTATUS(status)
|
||||
#[pyfunction(name = "WTERMSIG")]
|
||||
fn wtermsig(status: i32) -> i32 {
|
||||
libc::WTERMSIG(status)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
Reference in new issue
Block a user