Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 0 additions & 1 deletion Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2350,7 +2350,6 @@ def check_bool(self, f, *args, **kwargs):
with self.assertRaises(RuntimeWarning):
f(fd, *args, **kwargs)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_fdopen(self):
self.check(os.fdopen, encoding="utf-8")
self.check_bool(os.fdopen, encoding="utf-8")
Expand Down
9 changes: 4 additions & 5 deletions crates/stdlib/src/termios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,12 @@ mod termios {
}

fn termios_error(err: std::io::Error, vm: &VirtualMachine) -> PyBaseExceptionRef {
vm.new_exception(
vm.new_os_subtype_error(
error_type(vm),
vec![
err.posix_errno().to_pyobject(vm),
vm.ctx.new_str(err.to_string()).into(),
],
Some(err.posix_errno()),
vm.ctx.new_str(err.to_string()),
)
.upcast()
}

#[pyattr(name = "error", once)]
Expand Down
66 changes: 59 additions & 7 deletions crates/vm/src/stdlib/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,13 +1268,64 @@ pub(super) mod _os {
}

#[pyfunction]
fn link(src: OsPath, dst: OsPath, vm: &VirtualMachine) -> PyResult<()> {
fs::hard_link(&src.path, &dst.path).map_err(|err| {
let builder = err.to_os_error_builder(vm);
let builder = builder.filename(src.filename(vm));
let builder = builder.filename2(dst.filename(vm));
builder.build(vm).upcast()
})
fn link(
src: OsPath,
dst: OsPath,
follow_symlinks: FollowSymlinks,
vm: &VirtualMachine,
) -> PyResult<()> {
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
let src_cstr = std::ffi::CString::new(src.path.as_os_str().as_bytes())
.map_err(|_| vm.new_value_error("embedded null byte"))?;
let dst_cstr = std::ffi::CString::new(dst.path.as_os_str().as_bytes())
.map_err(|_| vm.new_value_error("embedded null byte"))?;

let flags = if follow_symlinks.0 {
libc::AT_SYMLINK_FOLLOW
} else {
0
};

let ret = unsafe {
libc::linkat(
libc::AT_FDCWD,
src_cstr.as_ptr(),
libc::AT_FDCWD,
dst_cstr.as_ptr(),
flags,
)
};

if ret != 0 {
let err = std::io::Error::last_os_error();
let builder = err.to_os_error_builder(vm);
let builder = builder.filename(src.filename(vm));
let builder = builder.filename2(dst.filename(vm));
return Err(builder.build(vm).upcast());
}

Ok(())
}

#[cfg(not(unix))]
{
// On non-Unix platforms, ignore follow_symlinks if it's the default value
// or raise NotImplementedError if explicitly set to False
if !follow_symlinks.0 {
return Err(vm.new_not_implemented_error(
"link: follow_symlinks unavailable on this platform",
));
}

fs::hard_link(&src.path, &dst.path).map_err(|err| {
let builder = err.to_os_error_builder(vm);
let builder = builder.filename(src.filename(vm));
let builder = builder.filename2(dst.filename(vm));
builder.build(vm).upcast()
})
}
}

#[cfg(any(unix, windows))]
Expand Down Expand Up @@ -1842,6 +1893,7 @@ pub(super) mod _os {
SupportFunc::new("access", Some(false), Some(false), None),
SupportFunc::new("chdir", None, Some(false), Some(false)),
// chflags Some, None Some
SupportFunc::new("link", Some(false), Some(false), Some(cfg!(unix))),
SupportFunc::new("listdir", Some(LISTDIR_FD), Some(false), Some(false)),
SupportFunc::new("mkdir", Some(false), Some(MKDIR_DIR_FD), Some(false)),
// mkfifo Some Some None
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/stdlib/warnings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn warn(
if let Ok(module) = vm.import("warnings", 0)
&& let Ok(func) = module.get_attr("warn", vm)
{
let _ = func.call((message, category.to_owned(), stack_level), vm);
func.call((message, category.to_owned(), stack_level), vm)?;
}
Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions crates/vm/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ impl VirtualMachine {
Some(if write { "wb" } else { "rb" }),
crate::stdlib::io::OpenArgs {
buffering: if unbuffered { 0 } else { -1 },
closefd: false,
..Default::default()
},
self,
Expand Down
Loading