mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
fspath try from (#6359)
This commit is contained in:
2
Lib/test/test_os.py
vendored
2
Lib/test/test_os.py
vendored
@@ -1811,7 +1811,6 @@ class MakedirTests(unittest.TestCase):
|
||||
# Issue #25583: A drive root could raise PermissionError on Windows
|
||||
os.makedirs(os.path.abspath('/'), exist_ok=True)
|
||||
|
||||
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.umask not implemented yet for all platforms')
|
||||
@unittest.skipIf(
|
||||
support.is_emscripten or support.is_wasi,
|
||||
"Emscripten's/WASI's umask is a stub."
|
||||
@@ -4653,7 +4652,6 @@ class FDInheritanceTests(unittest.TestCase):
|
||||
os.set_inheritable(fd, False)
|
||||
self.assertEqual(os.get_inheritable(fd), False)
|
||||
|
||||
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
|
||||
def test_get_set_inheritable_badf(self):
|
||||
fd = os_helper.make_bad_fd()
|
||||
|
||||
|
||||
@@ -14,8 +14,26 @@ pub enum FsPath {
|
||||
}
|
||||
|
||||
impl FsPath {
|
||||
pub fn try_from_path_like(
|
||||
obj: PyObjectRef,
|
||||
check_for_nul: bool,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Self> {
|
||||
Self::try_from(
|
||||
obj,
|
||||
check_for_nul,
|
||||
"expected str, bytes or os.PathLike object",
|
||||
vm,
|
||||
)
|
||||
}
|
||||
|
||||
// PyOS_FSPath in CPython
|
||||
pub fn try_from(obj: PyObjectRef, check_for_nul: bool, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
pub fn try_from(
|
||||
obj: PyObjectRef,
|
||||
check_for_nul: bool,
|
||||
msg: &'static str,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Self> {
|
||||
let check_nul = |b: &[u8]| {
|
||||
if !check_for_nul || memchr::memchr(b'\0', b).is_none() {
|
||||
Ok(())
|
||||
@@ -41,13 +59,16 @@ impl FsPath {
|
||||
Ok(pathlike) => return Ok(pathlike),
|
||||
Err(obj) => obj,
|
||||
};
|
||||
let method =
|
||||
vm.get_method_or_type_error(obj.clone(), identifier!(vm, __fspath__), || {
|
||||
format!(
|
||||
"should be string, bytes, os.PathLike or integer, not {}",
|
||||
obj.class().name()
|
||||
)
|
||||
})?;
|
||||
let not_pathlike_error = || format!("{msg}, not {}", obj.class().name());
|
||||
let method = vm.get_method_or_type_error(
|
||||
obj.clone(),
|
||||
identifier!(vm, __fspath__),
|
||||
not_pathlike_error,
|
||||
)?;
|
||||
// If __fspath__ is explicitly set to None, treat it as if it doesn't have __fspath__
|
||||
if vm.is_none(&method) {
|
||||
return Err(vm.new_type_error(not_pathlike_error()));
|
||||
}
|
||||
let result = method.call((), vm)?;
|
||||
match1(result)?.map_err(|result| {
|
||||
vm.new_type_error(format!(
|
||||
@@ -125,6 +146,6 @@ impl TryFromObject for FsPath {
|
||||
}
|
||||
Err(_) => obj,
|
||||
};
|
||||
Self::try_from(obj, true, vm)
|
||||
Self::try_from_path_like(obj, true, vm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,14 @@ impl OsPath {
|
||||
Ok(Self { path, mode })
|
||||
}
|
||||
|
||||
/// Convert an object to OsPath using the os.fspath-style error message.
|
||||
/// This is used by open() which should report "expected str, bytes or os.PathLike object, not"
|
||||
/// instead of "should be string, bytes or os.PathLike, not".
|
||||
pub(crate) fn try_from_fspath(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
let fspath = FsPath::try_from_path_like(obj, true, vm)?;
|
||||
Self::from_fspath(fspath, vm)
|
||||
}
|
||||
|
||||
pub fn as_path(&self) -> &Path {
|
||||
Path::new(&self.path)
|
||||
}
|
||||
@@ -90,7 +98,12 @@ impl AsRef<Path> for OsPath {
|
||||
impl TryFromObject for OsPath {
|
||||
// TODO: path_converter with allow_fd=0 in CPython
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let fspath = FsPath::try_from(obj, true, vm)?;
|
||||
let fspath = FsPath::try_from(
|
||||
obj,
|
||||
true,
|
||||
"should be string, bytes, os.PathLike or integer",
|
||||
vm,
|
||||
)?;
|
||||
Self::from_fspath(fspath, vm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4340,7 +4340,7 @@ mod fileio {
|
||||
}
|
||||
(fd, None)
|
||||
} else {
|
||||
let path = OsPath::try_from_object(vm, name.clone())?;
|
||||
let path = OsPath::try_from_fspath(name.clone(), vm)?;
|
||||
#[cfg(any(unix, target_os = "wasi"))]
|
||||
let fd = crt_fd::open(&path.clone().into_cstring(vm)?, flags, 0o666);
|
||||
#[cfg(windows)]
|
||||
|
||||
@@ -1022,7 +1022,7 @@ pub(super) mod _os {
|
||||
|
||||
#[pyfunction]
|
||||
fn fspath(path: PyObjectRef, vm: &VirtualMachine) -> PyResult<FsPath> {
|
||||
FsPath::try_from(path, false, vm)
|
||||
FsPath::try_from_path_like(path, false, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
Reference in New Issue
Block a user