Skip to content

Commit 6771fa0

Browse files
committed
path
1 parent abfd148 commit 6771fa0

File tree

5 files changed

+46
-14
lines changed

5 files changed

+46
-14
lines changed

Lib/test/test_os.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,6 @@ def test_exist_ok_existing_directory(self):
18111811
# Issue #25583: A drive root could raise PermissionError on Windows
18121812
os.makedirs(os.path.abspath('/'), exist_ok=True)
18131813

1814-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.umask not implemented yet for all platforms')
18151814
@unittest.skipIf(
18161815
support.is_emscripten or support.is_wasi,
18171816
"Emscripten's/WASI's umask is a stub."
@@ -4653,7 +4652,6 @@ def test_get_set_inheritable_o_path(self):
46534652
os.set_inheritable(fd, False)
46544653
self.assertEqual(os.get_inheritable(fd), False)
46554654

4656-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
46574655
def test_get_set_inheritable_badf(self):
46584656
fd = os_helper.make_bad_fd()
46594657

crates/vm/src/function/fspath.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,26 @@ pub enum FsPath {
1414
}
1515

1616
impl FsPath {
17+
pub fn try_from_path_like(
18+
obj: PyObjectRef,
19+
check_for_nul: bool,
20+
vm: &VirtualMachine,
21+
) -> PyResult<Self> {
22+
Self::try_from(
23+
obj,
24+
check_for_nul,
25+
"expected str, bytes or os.PathLike object",
26+
vm,
27+
)
28+
}
29+
1730
// PyOS_FSPath in CPython
18-
pub fn try_from(obj: PyObjectRef, check_for_nul: bool, vm: &VirtualMachine) -> PyResult<Self> {
31+
pub fn try_from(
32+
obj: PyObjectRef,
33+
check_for_nul: bool,
34+
msg: &'static str,
35+
vm: &VirtualMachine,
36+
) -> PyResult<Self> {
1937
let check_nul = |b: &[u8]| {
2038
if !check_for_nul || memchr::memchr(b'\0', b).is_none() {
2139
Ok(())
@@ -41,13 +59,16 @@ impl FsPath {
4159
Ok(pathlike) => return Ok(pathlike),
4260
Err(obj) => obj,
4361
};
44-
let method =
45-
vm.get_method_or_type_error(obj.clone(), identifier!(vm, __fspath__), || {
46-
format!(
47-
"should be string, bytes, os.PathLike or integer, not {}",
48-
obj.class().name()
49-
)
50-
})?;
62+
let not_pathlike_error = || format!("{msg}, not {}", obj.class().name());
63+
let method = vm.get_method_or_type_error(
64+
obj.clone(),
65+
identifier!(vm, __fspath__),
66+
not_pathlike_error,
67+
)?;
68+
// If __fspath__ is explicitly set to None, treat it as if it doesn't have __fspath__
69+
if vm.is_none(&method) {
70+
return Err(vm.new_type_error(not_pathlike_error()));
71+
}
5172
let result = method.call((), vm)?;
5273
match1(result)?.map_err(|result| {
5374
vm.new_type_error(format!(
@@ -125,6 +146,6 @@ impl TryFromObject for FsPath {
125146
}
126147
Err(_) => obj,
127148
};
128-
Self::try_from(obj, true, vm)
149+
Self::try_from_path_like(obj, true, vm)
129150
}
130151
}

crates/vm/src/ospath.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ impl OsPath {
5555
Ok(Self { path, mode })
5656
}
5757

58+
/// Convert an object to OsPath using the os.fspath-style error message.
59+
/// This is used by open() which should report "expected str, bytes or os.PathLike object, not"
60+
/// instead of "should be string, bytes or os.PathLike, not".
61+
pub(crate) fn try_from_fspath(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
62+
let fspath = FsPath::try_from_path_like(obj, true, vm)?;
63+
Self::from_fspath(fspath, vm)
64+
}
65+
5866
pub fn as_path(&self) -> &Path {
5967
Path::new(&self.path)
6068
}
@@ -90,7 +98,12 @@ impl AsRef<Path> for OsPath {
9098
impl TryFromObject for OsPath {
9199
// TODO: path_converter with allow_fd=0 in CPython
92100
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
93-
let fspath = FsPath::try_from(obj, true, vm)?;
101+
let fspath = FsPath::try_from(
102+
obj,
103+
true,
104+
"should be string, bytes, os.PathLike or integer",
105+
vm,
106+
)?;
94107
Self::from_fspath(fspath, vm)
95108
}
96109
}

crates/vm/src/stdlib/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4340,7 +4340,7 @@ mod fileio {
43404340
}
43414341
(fd, None)
43424342
} else {
4343-
let path = OsPath::try_from_object(vm, name.clone())?;
4343+
let path = OsPath::try_from_fspath(name.clone(), vm)?;
43444344
#[cfg(any(unix, target_os = "wasi"))]
43454345
let fd = crt_fd::open(&path.clone().into_cstring(vm)?, flags, 0o666);
43464346
#[cfg(windows)]

crates/vm/src/stdlib/os.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ pub(super) mod _os {
10031003

10041004
#[pyfunction]
10051005
fn fspath(path: PyObjectRef, vm: &VirtualMachine) -> PyResult<FsPath> {
1006-
FsPath::try_from(path, false, vm)
1006+
FsPath::try_from_path_like(path, false, vm)
10071007
}
10081008

10091009
#[pyfunction]

0 commit comments

Comments
 (0)