From 86a96e722e7700c9b6e0cfa2017f75cc1f64e253 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Tue, 17 Mar 2026 21:52:50 +0900 Subject: [PATCH 1/8] Disallow instantiation of sys.getwindowsversion type Add slot_new to PyWindowsVersion that raises TypeError, matching sys.flags behavior. --- Lib/test/test_sys.py | 1 - crates/vm/src/stdlib/sys.rs | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 89987aeba6e..71c2f7512b1 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -878,7 +878,6 @@ def test_sys_flags_no_instantiation(self): def test_sys_version_info_no_instantiation(self): self.assert_raise_on_new_sys_type(sys.version_info) - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError not raised for getwindowsversion instantiation def test_sys_getwindowsversion_no_instantiation(self): # Skip if not being run on Windows. test.support.get_attribute(sys, "getwindowsversion") diff --git a/crates/vm/src/stdlib/sys.rs b/crates/vm/src/stdlib/sys.rs index 33325c9dc60..72379494ddb 100644 --- a/crates/vm/src/stdlib/sys.rs +++ b/crates/vm/src/stdlib/sys.rs @@ -1807,7 +1807,12 @@ mod sys { #[cfg(windows)] #[pyclass(with(PyStructSequence))] - impl PyWindowsVersion {} + impl PyWindowsVersion { + #[pyslot] + fn slot_new(_cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { + Err(vm.new_type_error("cannot create 'sys.getwindowsversion' instances")) + } + } #[derive(Debug)] #[pystruct_sequence_data(try_from_object)] From b02cdb6f908c74e300dadc9bfaaf353759fbc641 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Tue, 17 Mar 2026 21:52:59 +0900 Subject: [PATCH 2/8] Remove incorrect WSAHOS errno constant WSAHOS was hardcoded as an alias for WSAHOST_NOT_FOUND, but CPython guards it with #ifdef WSAHOS which doesn't exist in modern Windows SDK headers. --- crates/vm/src/stdlib/errno.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/vm/src/stdlib/errno.rs b/crates/vm/src/stdlib/errno.rs index 8e4efbaafe9..42a0231c866 100644 --- a/crates/vm/src/stdlib/errno.rs +++ b/crates/vm/src/stdlib/errno.rs @@ -39,7 +39,7 @@ pub mod errors { WSAENOMORE, WSAENOPROTOOPT, WSAENOTCONN, WSAENOTEMPTY, WSAENOTSOCK, WSAEOPNOTSUPP, WSAEPFNOSUPPORT, WSAEPROCLIM, WSAEPROTONOSUPPORT, WSAEPROTOTYPE, WSAEPROVIDERFAILEDINIT, WSAEREFUSED, WSAEREMOTE, WSAESHUTDOWN, WSAESOCKTNOSUPPORT, - WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, WSAHOST_NOT_FOUND, + WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, WSAID_ACCEPTEX, WSAID_CONNECTEX, WSAID_DISCONNECTEX, WSAID_GETACCEPTEXSOCKADDRS, WSAID_TRANSMITFILE, WSAID_TRANSMITPACKETS, WSAID_WSAPOLL, WSAID_WSARECVMSG, WSANO_DATA, WSANO_RECOVERY, WSANOTINITIALISED, WSAPROTOCOL_LEN, WSASERVICE_NOT_FOUND, @@ -64,8 +64,6 @@ pub mod errors { ETIMEDOUT, ETOOMANYREFS, EUSERS, EWOULDBLOCK, // TODO: EBADF should be here once winerrs are translated to errnos but it messes up some things atm } - #[cfg(windows)] - pub const WSAHOS: i32 = WSAHOST_NOT_FOUND; } #[cfg(any(unix, windows, target_os = "wasi"))] @@ -566,7 +564,7 @@ const ERROR_CODES: &[(&str, i32)] = &[ e!(cfg(windows), WSAEDISCON), e!(cfg(windows), WSAEINTR), e!(cfg(windows), WSAEPROTOTYPE), - e!(cfg(windows), WSAHOS), + // TODO: e!(cfg(windows), WSAHOS), e!(cfg(windows), WSAEADDRINUSE), e!(cfg(windows), WSAEADDRNOTAVAIL), e!(cfg(windows), WSAEALREADY), From d7d6f7aa3ef9ee1bdf05f75ff43493a80e02cfd9 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Tue, 17 Mar 2026 21:53:04 +0900 Subject: [PATCH 3/8] Fix mmap resize to raise OSError instead of SystemError --- Lib/test/test_mmap.py | 1 - crates/stdlib/src/mmap.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 448ea2325fe..ed96be53cca 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -867,7 +867,6 @@ def test_resize_fails_if_mapping_held_elsewhere(self): finally: f.close() - @unittest.expectedFailure # TODO: RUSTPYTHON @unittest.skipUnless(os.name == 'nt', 'requires Windows') def test_resize_succeeds_with_error_for_second_named_mapping(self): """If a more than one mapping exists of the same name, none of them can diff --git a/crates/stdlib/src/mmap.rs b/crates/stdlib/src/mmap.rs index d441a3dd887..7d1eae34998 100644 --- a/crates/stdlib/src/mmap.rs +++ b/crates/stdlib/src/mmap.rs @@ -1181,7 +1181,7 @@ mod mmap { fn resize(&self, _newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> { self.check_resizeable(vm)?; // TODO: implement using mremap on Linux - Err(vm.new_system_error("mmap: resizing not available--no mremap()")) + Err(vm.new_os_error("mmap: resizing not available--no mremap()")) } #[cfg(windows)] @@ -1204,7 +1204,7 @@ mod mmap { // Check if this is a Named mmap - these cannot be resized if let Some(MmapObj::Named(_)) = mmap_guard.as_ref() { - return Err(vm.new_system_error("mmap: cannot resize a named memory mapping")); + return Err(vm.new_os_error("mmap: cannot resize a named memory mapping")); } let is_anonymous = handle == INVALID_HANDLE_VALUE as isize; From 24a17192a03b1f2b726a749e3cdb24724d86e4e0 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Tue, 17 Mar 2026 21:53:12 +0900 Subject: [PATCH 4/8] Fix CreateProcess with empty environment on Windows Empty env dict produced a single null terminator, but CreateProcessW requires a double null for a valid empty environment block. --- Lib/test/test_subprocess.py | 1 - crates/vm/src/stdlib/_winapi.rs | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 824c636dfd1..2ba98616ea6 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1903,7 +1903,6 @@ def test_run_with_pathlike_path_and_arguments(self): res = subprocess.run(args) self.assertEqual(res.returncode, 57) - @unittest.skipIf(mswindows, "TODO: RUSTPYTHON; empty env block fails nondeterministically") @unittest.skipUnless(mswindows, "Maybe test trigger a leak on Ubuntu") def test_run_with_an_empty_env(self): # gh-105436: fix subprocess.run(..., env={}) broken on Windows diff --git a/crates/vm/src/stdlib/_winapi.rs b/crates/vm/src/stdlib/_winapi.rs index 36113f054da..fe2e752b99f 100644 --- a/crates/vm/src/stdlib/_winapi.rs +++ b/crates/vm/src/stdlib/_winapi.rs @@ -445,6 +445,11 @@ mod _winapi { for (_, entry) in entries { out.push(entry); } + // Each entry ends with \0, so one more \0 terminates the block. + // For empty env, we need \0\0 as a valid empty environment block. + if out.is_empty() { + out.push_str("\0"); + } out.push_str("\0"); Ok(out.into_vec()) } From acb11da89915717a6977c223d95659c025d515a0 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Fri, 20 Mar 2026 01:09:50 +0900 Subject: [PATCH 5/8] Revert mmap resize error to SystemError and fix errno.rs formatting mmap resize raises SystemError (not OSError) when mremap is unavailable, matching CPython behavior. test_mmap catches SystemError to skip unsupported resize operations. --- crates/stdlib/src/mmap.rs | 4 ++-- crates/vm/src/stdlib/errno.rs | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/stdlib/src/mmap.rs b/crates/stdlib/src/mmap.rs index 7d1eae34998..d441a3dd887 100644 --- a/crates/stdlib/src/mmap.rs +++ b/crates/stdlib/src/mmap.rs @@ -1181,7 +1181,7 @@ mod mmap { fn resize(&self, _newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> { self.check_resizeable(vm)?; // TODO: implement using mremap on Linux - Err(vm.new_os_error("mmap: resizing not available--no mremap()")) + Err(vm.new_system_error("mmap: resizing not available--no mremap()")) } #[cfg(windows)] @@ -1204,7 +1204,7 @@ mod mmap { // Check if this is a Named mmap - these cannot be resized if let Some(MmapObj::Named(_)) = mmap_guard.as_ref() { - return Err(vm.new_os_error("mmap: cannot resize a named memory mapping")); + return Err(vm.new_system_error("mmap: cannot resize a named memory mapping")); } let is_anonymous = handle == INVALID_HANDLE_VALUE as isize; diff --git a/crates/vm/src/stdlib/errno.rs b/crates/vm/src/stdlib/errno.rs index 42a0231c866..d7a0a222a76 100644 --- a/crates/vm/src/stdlib/errno.rs +++ b/crates/vm/src/stdlib/errno.rs @@ -39,12 +39,11 @@ pub mod errors { WSAENOMORE, WSAENOPROTOOPT, WSAENOTCONN, WSAENOTEMPTY, WSAENOTSOCK, WSAEOPNOTSUPP, WSAEPFNOSUPPORT, WSAEPROCLIM, WSAEPROTONOSUPPORT, WSAEPROTOTYPE, WSAEPROVIDERFAILEDINIT, WSAEREFUSED, WSAEREMOTE, WSAESHUTDOWN, WSAESOCKTNOSUPPORT, - WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, - WSAID_ACCEPTEX, WSAID_CONNECTEX, WSAID_DISCONNECTEX, WSAID_GETACCEPTEXSOCKADDRS, - WSAID_TRANSMITFILE, WSAID_TRANSMITPACKETS, WSAID_WSAPOLL, WSAID_WSARECVMSG, WSANO_DATA, - WSANO_RECOVERY, WSANOTINITIALISED, WSAPROTOCOL_LEN, WSASERVICE_NOT_FOUND, - WSASYS_STATUS_LEN, WSASYSCALLFAILURE, WSASYSNOTREADY, WSATRY_AGAIN, WSATYPE_NOT_FOUND, - WSAVERNOTSUPPORTED, + WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, WSAID_ACCEPTEX, + WSAID_CONNECTEX, WSAID_DISCONNECTEX, WSAID_GETACCEPTEXSOCKADDRS, WSAID_TRANSMITFILE, + WSAID_TRANSMITPACKETS, WSAID_WSAPOLL, WSAID_WSARECVMSG, WSANO_DATA, WSANO_RECOVERY, + WSANOTINITIALISED, WSAPROTOCOL_LEN, WSASERVICE_NOT_FOUND, WSASYS_STATUS_LEN, + WSASYSCALLFAILURE, WSASYSNOTREADY, WSATRY_AGAIN, WSATYPE_NOT_FOUND, WSAVERNOTSUPPORTED, }, }; #[cfg(windows)] From 30e19cd3328d8cf24c86785afe87e3ed6bd4ee1f Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Fri, 20 Mar 2026 04:39:19 +0900 Subject: [PATCH 6/8] Fix named mmap resize to raise OSError and unmark test_sleep expectedFailure Named mmap resize on Windows should raise OSError (not SystemError). Remove expectedFailure mark from TimeEINTRTest.test_sleep as it now passes. --- crates/stdlib/src/mmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/stdlib/src/mmap.rs b/crates/stdlib/src/mmap.rs index d441a3dd887..a99d0cc131d 100644 --- a/crates/stdlib/src/mmap.rs +++ b/crates/stdlib/src/mmap.rs @@ -1204,7 +1204,7 @@ mod mmap { // Check if this is a Named mmap - these cannot be resized if let Some(MmapObj::Named(_)) = mmap_guard.as_ref() { - return Err(vm.new_system_error("mmap: cannot resize a named memory mapping")); + return Err(vm.new_os_error("mmap: cannot resize a named memory mapping")); } let is_anonymous = handle == INVALID_HANDLE_VALUE as isize; From 8b8cacacf10a879f03a85b5b24fe873293ceb57d Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Fri, 20 Mar 2026 21:30:55 +0900 Subject: [PATCH 7/8] Use expectedFailureIf for TimeEINTRTest.test_sleep on Linux test_sleep passes on macOS but fails on Linux due to timing. --- Lib/test/_test_eintr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/_test_eintr.py b/Lib/test/_test_eintr.py index 095ccd032b3..a132f065f4b 100644 --- a/Lib/test/_test_eintr.py +++ b/Lib/test/_test_eintr.py @@ -392,6 +392,7 @@ def test_os_open(self): class TimeEINTRTest(EINTRBaseTest): """ EINTR tests for the time module. """ + @unittest.expectedFailureIf(sys.platform == "linux", "TODO: RUSTPYTHON") def test_sleep(self): t0 = time.monotonic() time.sleep(self.sleep_time) From de0db04c8e682b033be130bb95e3dba0244a9a00 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Sat, 21 Mar 2026 00:38:36 +0900 Subject: [PATCH 8/8] Remove expectedFailure for TimeEINTRTest.test_sleep test_sleep now passes on all platforms. --- Lib/test/_test_eintr.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/_test_eintr.py b/Lib/test/_test_eintr.py index a132f065f4b..095ccd032b3 100644 --- a/Lib/test/_test_eintr.py +++ b/Lib/test/_test_eintr.py @@ -392,7 +392,6 @@ def test_os_open(self): class TimeEINTRTest(EINTRBaseTest): """ EINTR tests for the time module. """ - @unittest.expectedFailureIf(sys.platform == "linux", "TODO: RUSTPYTHON") def test_sleep(self): t0 = time.monotonic() time.sleep(self.sleep_time)