mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Dedupe Unix & WASI stdlib (#8635)
Follow up to #8591 because I figured out how to deduplicate the code. This is nicer for future patches that improve WASI support because Unix-likes and WASI can often share the same dispatch functions.
This commit is contained in:
1 parent
39682562b3
commit
7ceada0048
6 files changed
+59
-92
No files matched your search
@@ -37,6 +37,8 @@ pub mod posix;
|
||||
#[cfg(all(feature = "host_env", not(any(unix, windows))))]
|
||||
#[path = "posix_compat.rs"]
|
||||
pub mod posix;
|
||||
#[cfg(all(feature = "host_env", any(unix, target_os = "wasi")))]
|
||||
pub mod posix_unix_like;
|
||||
|
||||
#[cfg(all(
|
||||
feature = "host_env",
|
||||
|
||||
@@ -13,7 +13,7 @@ pub(crate) mod module {
|
||||
function::{ArgMapping, Either, OptionalArg},
|
||||
host_env::crt_fd,
|
||||
ospath::{OsPath, OsPathOrFd},
|
||||
stdlib::os::{_os, DirFd, SupportFunc, TargetIsDirectory},
|
||||
stdlib::os::{_os, DirFd, SupportFunc, SymlinkArgs},
|
||||
};
|
||||
use core::hint::cold_path;
|
||||
use libc::intptr_t;
|
||||
@@ -101,16 +101,6 @@ pub(crate) mod module {
|
||||
host_nt::supports_virtual_terminal()
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
pub(super) struct SymlinkArgs<'fd> {
|
||||
src: OsPath,
|
||||
dst: OsPath,
|
||||
#[pyarg(flatten)]
|
||||
target_is_directory: TargetIsDirectory,
|
||||
#[pyarg(flatten)]
|
||||
_dir_fd: DirFd<'fd, { _os::SYMLINK_DIR_FD as usize }>,
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
pub(super) fn symlink(args: SymlinkArgs<'_>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let src = args.src.to_wide_cstring(vm)?;
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{
|
||||
convert::{IntoPyException, ToPyException, ToPyObject},
|
||||
function::{ArgumentError, FromArgs, FuncArgs},
|
||||
host_env::{crt_fd, posix::RawMode},
|
||||
ospath::OsPath,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use std::{io, path::Path};
|
||||
@@ -123,6 +124,18 @@ impl<const AVAILABLE: usize, KW: DirFdKeyword> FromArgs for DirFd<'_, AVAILABLE,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
pub(crate) struct SymlinkArgs<'fd> {
|
||||
pub src: OsPath,
|
||||
pub dst: OsPath,
|
||||
#[cfg_attr(any(unix, target_os = "wasi"), expect(unused))]
|
||||
#[pyarg(flatten)]
|
||||
pub target_is_directory: TargetIsDirectory,
|
||||
#[cfg_attr(not(unix), expect(unused))]
|
||||
#[pyarg(flatten)]
|
||||
pub dir_fd: DirFd<'fd, { _os::SYMLINK_DIR_FD as usize }>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
pub(super) struct FollowSymlinks(
|
||||
#[pyarg(named, name = "follow_symlinks", default = true)] pub bool,
|
||||
|
||||
@@ -6,6 +6,7 @@ pub use rustpython_host_env::posix::set_inheritable;
|
||||
|
||||
#[pymodule(name = "posix", with(
|
||||
super::os::_os,
|
||||
super::posix_unix_like::_posix_unix_like,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
@@ -23,8 +24,7 @@ pub mod module {
|
||||
function::{ArgMapping, Either, KwArgs, OptionalArg},
|
||||
ospath::{OsPath, OsPathOrFd},
|
||||
stdlib::os::{
|
||||
_os, DirFd, FollowSymlinks, SupportFunc, TargetIsDirectory, fs_metadata,
|
||||
warn_if_bool_fd,
|
||||
_os, DirFd, FollowSymlinks, SupportFunc, SymlinkArgs, fs_metadata, warn_if_bool_fd,
|
||||
},
|
||||
};
|
||||
#[cfg(any(
|
||||
@@ -384,18 +384,6 @@ pub mod module {
|
||||
.map_err(|err| err.to_pyexception(vm))
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn environ(vm: &VirtualMachine) -> PyDictRef {
|
||||
let environ = vm.ctx.new_dict();
|
||||
for (key, value) in crate::host_env::os::vars_os() {
|
||||
let key: PyObjectRef = vm.ctx.new_bytes(key.into_vec()).into();
|
||||
let value: PyObjectRef = vm.ctx.new_bytes(value.into_vec()).into();
|
||||
environ.set_item(&*key, value, vm).unwrap();
|
||||
}
|
||||
|
||||
environ
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn _create_environ(vm: &VirtualMachine) -> PyDictRef {
|
||||
let environ = vm.ctx.new_dict();
|
||||
@@ -407,16 +395,6 @@ pub mod module {
|
||||
environ
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
pub(super) struct SymlinkArgs<'fd> {
|
||||
src: OsPath,
|
||||
dst: OsPath,
|
||||
#[pyarg(flatten)]
|
||||
_target_is_directory: TargetIsDirectory,
|
||||
#[pyarg(flatten)]
|
||||
dir_fd: DirFd<'fd, { _os::SYMLINK_DIR_FD as usize }>,
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
pub(super) fn symlink(args: SymlinkArgs<'_>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let src = args.src.into_cstring(vm)?;
|
||||
@@ -433,17 +411,6 @@ pub mod module {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
#[pyfunction(name = "unlink")]
|
||||
fn remove(
|
||||
path: OsPath,
|
||||
dir_fd: DirFd<'_, { _os::UNLINK_DIR_FD as usize }>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
rustpython_host_env::posix::unlinkat(dir_fd.get_opt(), &path)
|
||||
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[pyfunction]
|
||||
fn fchdir(fd: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
|
||||
@@ -4,38 +4,24 @@
|
||||
|
||||
pub(crate) use module::module_def;
|
||||
|
||||
#[pymodule(name = "posix", with(super::os::_os))]
|
||||
#[pymodule(name = "posix", with(
|
||||
super::os::_os,
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
super::posix_unix_like::_posix_unix_like,
|
||||
))]
|
||||
pub(crate) mod module {
|
||||
use crate::{
|
||||
Py, PyObjectRef, PyResult, VirtualMachine,
|
||||
builtins::PyStrRef,
|
||||
ospath::OsPath,
|
||||
stdlib::os::{_os, DirFd, SupportFunc, TargetIsDirectory},
|
||||
stdlib::os::{_os, DirFd, SupportFunc, SymlinkArgs, TargetIsDirectory},
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
use {crate::convert::IntoPyException, std::fs};
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
use crate::exceptions::OSErrorBuilder;
|
||||
|
||||
#[pyfunction]
|
||||
pub(super) fn access(_path: PyStrRef, _mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
os_unimpl("os.access", vm)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
#[pyfunction]
|
||||
#[pyfunction(name = "unlink")]
|
||||
fn remove(
|
||||
path: OsPath,
|
||||
dir_fd: DirFd<'_, { _os::UNLINK_DIR_FD as usize }>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
rustpython_host_env::posix::unlinkat(dir_fd.get_opt(), &path)
|
||||
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
#[pyfunction]
|
||||
#[pyfunction(name = "unlink")]
|
||||
@@ -44,37 +30,11 @@ pub(crate) mod module {
|
||||
fs::remove_file(&path).map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[allow(unused)]
|
||||
pub(super) struct SymlinkArgs<'a> {
|
||||
src: OsPath,
|
||||
dst: OsPath,
|
||||
#[pyarg(flatten)]
|
||||
_target_is_directory: TargetIsDirectory,
|
||||
#[pyarg(flatten)]
|
||||
_dir_fd: DirFd<'a, { _os::SYMLINK_DIR_FD as usize }>,
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
pub(super) fn symlink(_args: SymlinkArgs<'_>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
os_unimpl("os.symlink", vm)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
#[pyattr]
|
||||
fn environ(vm: &VirtualMachine) -> crate::builtins::PyDictRef {
|
||||
use rustpython_host_env::os::ffi::OsStringExt;
|
||||
|
||||
let environ = vm.ctx.new_dict();
|
||||
for (key, value) in crate::host_env::os::vars_os() {
|
||||
let key: PyObjectRef = vm.ctx.new_bytes(key.into_vec()).into();
|
||||
let value: PyObjectRef = vm.ctx.new_bytes(value.into_vec()).into();
|
||||
environ.set_item(&*key, value, vm).unwrap();
|
||||
}
|
||||
|
||||
environ
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn os_unimpl<T>(func: &str, vm: &VirtualMachine) -> PyResult<T> {
|
||||
Err(vm.new_os_error(format!("{func} is not supported on this platform")))
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#[pymodule(sub)]
|
||||
pub(crate) mod _posix_unix_like {
|
||||
use rustpython_host_env::os::ffi::OsStringExt;
|
||||
|
||||
use crate::{
|
||||
PyObjectRef, PyResult, VirtualMachine,
|
||||
builtins::PyDictRef,
|
||||
exceptions::OSErrorBuilder,
|
||||
ospath::OsPath,
|
||||
stdlib::os::{_os, DirFd},
|
||||
};
|
||||
|
||||
#[pyattr]
|
||||
fn environ(vm: &VirtualMachine) -> PyDictRef {
|
||||
let environ = vm.ctx.new_dict();
|
||||
for (key, value) in crate::host_env::os::vars_os() {
|
||||
let key: PyObjectRef = vm.ctx.new_bytes(key.into_vec()).into();
|
||||
let value: PyObjectRef = vm.ctx.new_bytes(value.into_vec()).into();
|
||||
environ.set_item(&*key, value, vm).unwrap();
|
||||
}
|
||||
|
||||
environ
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
#[pyfunction(name = "unlink")]
|
||||
fn remove(
|
||||
path: OsPath,
|
||||
dir_fd: DirFd<'_, { _os::UNLINK_DIR_FD as usize }>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
rustpython_host_env::posix::unlinkat(dir_fd.get_opt(), &path)
|
||||
.map_err(|err| OSErrorBuilder::with_filename(&err, path, vm))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user