Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
more windows impl
  • Loading branch information
youknowone committed Feb 3, 2026
commit c0f3a09c2b82e66b10e3c9d860950bfe23b4a784
1 change: 0 additions & 1 deletion Lib/test/test_genericpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ def test_exists_fd(self):
os.close(w)
self.assertFalse(self.pathmodule.exists(r))

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_exists_bool(self):
for fd in False, True:
with self.assertWarnsRegex(RuntimeWarning,
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2554,7 +2554,6 @@ def test_fchmod(self):
def test_fchown(self):
self.check(os.fchown, -1, -1)

@unittest.expectedFailure # TODO: RUSTPYTHON; OSError: [Errno 22] Invalid argument: 0
@unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()')
def test_fpathconf(self):
self.assertIn("PC_NAME_MAX", os.pathconf_names)
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,6 @@ def test_get_and_set_scheduler_and_param(self):
param = posix.sched_param(sched_priority=-large)
self.assertRaises(OverflowError, posix.sched_setparam, 0, param)

@unittest.expectedFailureIf(sys.platform == 'linux', "TODO: RUSTPYTHON; TypeError: cannot pickle 'sched_param' object")
@requires_sched
def test_sched_param(self):
param = posix.sched_param(1)
Expand Down
15 changes: 14 additions & 1 deletion crates/vm/src/ospath.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use rustpython_common::crt_fd;

use crate::{
PyObjectRef, PyResult, VirtualMachine,
AsObject, PyObjectRef, PyResult, VirtualMachine,
builtins::{PyBytes, PyStr},
class::StaticType,
convert::{IntoPyException, ToPyException, ToPyObject, TryFromObject},
function::FsPath,
};
Expand Down Expand Up @@ -80,6 +81,18 @@ impl PathConverter {
) -> PyResult<OsPathOrFd<'fd>> {
// Handle fd (before __fspath__ check, like CPython)
if let Some(int) = obj.try_index_opt(vm) {
// Warn if bool is used as a file descriptor
if obj
.class()
.is(crate::builtins::bool_::PyBool::static_type())
{
crate::stdlib::warnings::warn(
vm.ctx.exceptions.runtime_warning,
"bool is used as a file descriptor".to_owned(),
1,
vm,
)?;
}
let fd = int?.try_to_primitive(vm)?;
return unsafe { crt_fd::Borrowed::try_borrow_raw(fd) }
.map(OsPathOrFd::Fd)
Expand Down
48 changes: 45 additions & 3 deletions crates/vm/src/stdlib/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn set_inheritable(fd: BorrowedFd<'_>, inheritable: bool) -> nix::Result<()>
pub mod module {
use crate::{
AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
builtins::{PyDictRef, PyInt, PyListRef, PyStr, PyStrRef, PyTupleRef, PyType},
builtins::{PyDictRef, PyInt, PyListRef, PyStr, PyTupleRef, PyType},
convert::{IntoPyException, ToPyObject, TryFromObject},
exceptions::OSErrorBuilder,
function::{Either, KwArgs, OptionalArg},
Expand All @@ -29,8 +29,14 @@ pub mod module {
warn_if_bool_fd,
},
types::{Constructor, Representable},
utils::ToCString,
};
#[cfg(any(
target_os = "android",
target_os = "freebsd",
target_os = "linux",
target_os = "openbsd"
))]
use crate::{builtins::PyStrRef, utils::ToCString};
use alloc::ffi::CString;
use bitflags::bitflags;
use core::ffi::CStr;
Expand Down Expand Up @@ -281,6 +287,7 @@ pub mod module {

impl TryFromObject for BorrowedFd<'_> {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
crate::stdlib::os::warn_if_bool_fd(&obj, vm)?;
let fd = i32::try_from_object(vm, obj)?;
if fd == -1 {
return Err(io::Error::from_raw_os_error(libc::EBADF).into_pyexception(vm));
Expand Down Expand Up @@ -904,6 +911,37 @@ pub mod module {
self.sched_priority.clone().to_pyobject(vm)
}

#[pymethod]
fn __reduce__(zelf: crate::PyRef<Self>, vm: &VirtualMachine) -> PyTupleRef {
vm.new_tuple((zelf.class().to_owned(), (zelf.sched_priority.clone(),)))
}

#[pymethod]
fn __replace__(
zelf: crate::PyRef<Self>,
args: crate::function::FuncArgs,
vm: &VirtualMachine,
) -> PyResult<Self> {
if !args.args.is_empty() {
return Err(
vm.new_type_error("__replace__() takes no positional arguments".to_owned())
);
}
let sched_priority = match args.kwargs.get("sched_priority") {
Some(v) => v.clone(),
None => zelf.sched_priority.clone(),
};
// Check for unexpected keyword arguments
for key in args.kwargs.keys() {
if key.as_str() != "sched_priority" {
return Err(vm.new_type_error(format!(
"__replace__() got an unexpected keyword argument '{key}'"
)));
}
}
Ok(Self { sched_priority })
}

#[cfg(any(
target_os = "linux",
target_os = "netbsd",
Expand Down Expand Up @@ -2091,7 +2129,11 @@ pub mod module {
let i = match obj.downcast::<PyInt>() {
Ok(int) => int.try_to_primitive(vm)?,
Err(obj) => {
let s = PyStrRef::try_from_object(vm, obj)?;
let s = obj.downcast::<PyStr>().map_err(|_| {
vm.new_type_error(
"configuration names must be strings or integers".to_owned(),
)
})?;
s.as_str()
.parse::<PathconfVar>()
.map_err(|_| vm.new_value_error("unrecognized configuration name"))?
Expand Down