Skip to content

Commit 0de19ef

Browse files
committed
Fix windows link
1 parent b5847b9 commit 0de19ef

File tree

1 file changed

+30
-14
lines changed
  • crates/vm/src/stdlib

1 file changed

+30
-14
lines changed

crates/vm/src/stdlib/os.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,13 +1267,24 @@ pub(super) mod _os {
12671267
}
12681268
}
12691269

1270-
#[pyfunction]
1271-
fn link(
1270+
#[derive(FromArgs)]
1271+
struct LinkArgs {
1272+
#[pyarg(any)]
12721273
src: OsPath,
1274+
#[pyarg(any)]
12731275
dst: OsPath,
1274-
follow_symlinks: FollowSymlinks,
1275-
vm: &VirtualMachine,
1276-
) -> PyResult<()> {
1276+
#[pyarg(named, name = "follow_symlinks", optional)]
1277+
follow_symlinks: OptionalArg<bool>,
1278+
}
1279+
1280+
#[pyfunction]
1281+
fn link(args: LinkArgs, vm: &VirtualMachine) -> PyResult<()> {
1282+
let LinkArgs {
1283+
src,
1284+
dst,
1285+
follow_symlinks,
1286+
} = args;
1287+
12771288
#[cfg(unix)]
12781289
{
12791290
use std::os::unix::ffi::OsStrExt;
@@ -1282,7 +1293,8 @@ pub(super) mod _os {
12821293
let dst_cstr = std::ffi::CString::new(dst.path.as_os_str().as_bytes())
12831294
.map_err(|_| vm.new_value_error("embedded null byte"))?;
12841295

1285-
let flags = if follow_symlinks.0 {
1296+
let follow = follow_symlinks.into_option().unwrap_or(true);
1297+
let flags = if follow {
12861298
libc::AT_SYMLINK_FOLLOW
12871299
} else {
12881300
0
@@ -1311,15 +1323,19 @@ pub(super) mod _os {
13111323

13121324
#[cfg(not(unix))]
13131325
{
1314-
// On non-Unix platforms, ignore follow_symlinks if it's the default value
1315-
// or raise NotImplementedError if explicitly set to False
1316-
if !follow_symlinks.0 {
1317-
return Err(vm.new_not_implemented_error(
1318-
"link: follow_symlinks unavailable on this platform",
1319-
));
1320-
}
1326+
let src_path = match follow_symlinks.into_option() {
1327+
Some(true) => {
1328+
// Explicit follow_symlinks=True: resolve symlinks
1329+
fs::canonicalize(&src.path)
1330+
.unwrap_or_else(|_| PathBuf::from(src.path.clone()))
1331+
}
1332+
Some(false) | None => {
1333+
// Default or explicit no-follow: native hard_link behavior
1334+
PathBuf::from(src.path.clone())
1335+
}
1336+
};
13211337

1322-
fs::hard_link(&src.path, &dst.path).map_err(|err| {
1338+
fs::hard_link(&src_path, &dst.path).map_err(|err| {
13231339
let builder = err.to_os_error_builder(vm);
13241340
let builder = builder.filename(src.filename(vm));
13251341
let builder = builder.filename2(dst.filename(vm));

0 commit comments

Comments
 (0)