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: 1 addition & 0 deletions .cspell.dict/cpython.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ prec
preinitialized
PYTHREAD_NAME
SA_ONSTACK
SOABI
stackdepth
stringlib
structseq
Expand Down
7 changes: 0 additions & 7 deletions Lib/test/test_genericpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,6 @@ def test_invalid_paths(self):
with self.assertRaisesRegex(ValueError, 'embedded null'):
func(b'/tmp\x00abcds')

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_samestat_on_symlink(self):
return super().test_samestat_on_symlink()

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_samefile_on_symlink(self):
return super().test_samefile_on_symlink()

# Following TestCase is not supposed to be run from test_genericpath.
# It is inherited by other test modules (ntpath, posixpath).
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -6384,7 +6384,6 @@ def rotator(source, dest):
rh.close()

class TimedRotatingFileHandlerTest(BaseFileTest):
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
@unittest.skipIf(support.is_wasi, "WASI does not have /dev/null.")
def test_should_not_rollover(self):
# See bpo-45401. Should only ever rollover regular files
Expand Down
10 changes: 0 additions & 10 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1458,8 +1458,6 @@ def test_isfile_named_pipe(self):
finally:
_winapi.CloseHandle(h)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.skipIf(sys.platform != 'win32', "windows only")
def test_con_device(self):
self.assertFalse(os.path.isfile(r"\\.\CON"))
Expand Down Expand Up @@ -1527,14 +1525,6 @@ def test_expandvars(self):
def test_expandvars_nonascii(self):
return super().test_expandvars_nonascii()

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_samefile_on_symlink(self):
return super().test_samefile_on_symlink()

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_samestat_on_symlink(self):
return super().test_samestat_on_symlink()


class PathLikeTests(NtpathTestCase):

Expand Down
6 changes: 0 additions & 6 deletions Lib/test/test_shutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,6 @@ def test_dont_copy_file_onto_link_to_itself(self):
finally:
shutil.rmtree(TESTFN, ignore_errors=True)

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; AssertionError: SameFileError not raised for copyfile')
@os_helper.skip_unless_symlink
def test_dont_copy_file_onto_symlink_to_itself(self):
# bug 851123.
Expand Down Expand Up @@ -2577,7 +2576,6 @@ def test_destinsrc_false_positive(self):
finally:
os_helper.rmtree(TESTFN)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
@mock_rename
def test_move_file_symlink(self):
Expand All @@ -2587,7 +2585,6 @@ def test_move_file_symlink(self):
self.assertTrue(os.path.islink(self.dst_file))
self.assertTrue(os.path.samefile(self.src_file, self.dst_file))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
@mock_rename
def test_move_file_symlink_to_dir(self):
Expand All @@ -2611,7 +2608,6 @@ def test_move_dangling_symlink(self):
self.assertTrue(os.path.islink(dst_link))
self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
@mock_rename
def test_move_dir_symlink(self):
Expand Down Expand Up @@ -2687,12 +2683,10 @@ def _test_move_symlink_to_dir_into_dir(self, dst):
self.assertTrue(os.path.samefile(self.dst_dir, dst_link))
self.assertTrue(os.path.exists(src))

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
def test_move_symlink_to_dir_into_dir(self):
self._test_move_symlink_to_dir_into_dir(self.dst_dir)

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@os_helper.skip_unless_symlink
def test_move_symlink_to_dir_into_symlink_to_dir(self):
dst = os.path.join(self.src_dir, 'otherlinktodir')
Expand Down
14 changes: 14 additions & 0 deletions crates/vm/src/stdlib/nt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,20 @@ pub(crate) mod module {
Ok(())
}

unsafe extern "C" {
fn _umask(mask: i32) -> i32;
}

#[pyfunction]
fn umask(mask: i32, vm: &VirtualMachine) -> PyResult<i32> {
let result = unsafe { _umask(mask) };
if result < 0 {
Err(errno_err(vm))
} else {
Ok(result)
}
}

pub(crate) fn support_funcs() -> Vec<SupportFunc> {
Vec::new()
}
Expand Down
11 changes: 11 additions & 0 deletions crates/vm/src/stdlib/sysconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@ pub(crate) mod sysconfig {
#[pyfunction]
fn config_vars(vm: &VirtualMachine) -> PyDictRef {
let vars = vm.ctx.new_dict();

// FIXME: This is an entirely wrong implementation of EXT_SUFFIX.
// EXT_SUFFIX must be a string starting with "." for pip compatibility
// Using ".pyd" causes pip's _generic_abi() to fall back to _cpython_abis()
vars.set_item("EXT_SUFFIX", ".pyd".to_pyobject(vm), vm)
.unwrap();
vars.set_item("SOABI", vm.ctx.none(), vm).unwrap();

vars.set_item("Py_GIL_DISABLED", true.to_pyobject(vm), vm)
.unwrap();
vars.set_item("Py_DEBUG", false.to_pyobject(vm), vm)
.unwrap();
Comment on lines +10 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the sysconfig.rs file to see its full context
wc -l crates/vm/src/stdlib/sysconfig.rs

Repository: RustPython/RustPython

Length of output: 186


🏁 Script executed:

# Check the complete sysconfig.rs file and its module definition
cat -n crates/vm/src/stdlib/sysconfig.rs

Repository: RustPython/RustPython

Length of output: 186


🏁 Script executed:

# Search for how sysconfig is registered/loaded and any platform guards
rg -n "sysconfig" crates/vm/src/stdlib/ --type rust -B 3 -A 3

Repository: RustPython/RustPython

Length of output: 186


🏁 Script executed:

# Check for platform-specific gates on sysconfig module
rg -n "#\[cfg" crates/vm/src/stdlib/sysconfig.rs

Repository: RustPython/RustPython

Length of output: 186


🏁 Script executed:

# Search for EXT_SUFFIX usage across the codebase
rg -n "EXT_SUFFIX" crates/vm/src/ --type rust -B 2 -A 2

Repository: RustPython/RustPython

Length of output: 186


🌐 Web query:

CPython sysconfig EXT_SUFFIX platform specific Windows Unix macOS

💡 Result:

Short summary — what EXT_SUFFIX is and platform differences, and how to get it:

  • EXT_SUFFIX is the filename suffix used for compiled Python extension modules (shared objects) for the current build — e.g. on POSIX you usually get .cpython-XY... .so (includes the SOABI), on Windows you get .pyd (often with a platform/ABI tag like .cp37-win_amd64.pyd when full suffix is available). [1][2]

  • How CPython exposes it:

    • sysconfig.get_config_var('EXT_SUFFIX') — canonical API to query the extension suffix. On many Unix/macOS builds this returns the full tagged suffix (e.g. ".cpython-39m-darwin.so"). On some Windows builds it may return only ".pyd" (SOABI may be None). [2][5]
    • If you need the fuller Windows tag (e.g. ".cp37-win_amd64.pyd"), distutils.sysconfig.get_config_var('EXT_SUFFIX') historically returned the full value on Windows in some builds (useful as a fallback). Note: distutils is deprecated but still present in many Python versions; prefer sysconfig when possible. [0]
  • Practical snippet:

    • import sysconfig; ext = sysconfig.get_config_var('EXT_SUFFIX')
    • fallback (Windows): import distutils.sysconfig; ext = distutils.sysconfig.get_config_var('EXT_SUFFIX') if ext is None or ext == '.pyd' else ext. [0][1]

References:

  • Python sysconfig docs (describe get_config_var / get_platform / usage). [1][2]
  • StackOverflow discussion showing Windows behavior and distutils fallback. [0]

Sources:
[0] StackOverflow — "Python generate SOABI/Extension Suffix (pep 3149) for Windows".
[1] Python docs — sysconfig (library documentation).
[2] Python docs — Configure/using Python (notes on platform/config).


🌐 Web query:

RustPython sysconfig module EXT_SUFFIX implementation

💡 Result:

Do you want (a) the RustPython source location that implements sysconfig/EXT_SUFFIX, (b) an explanation of how EXT_SUFFIX should behave (CPython behaviour), or (c) help implementing/fixing EXT_SUFFIX in RustPython?


Hardcoded .pyd EXT_SUFFIX will break on Unix/macOS platforms.

EXT_SUFFIX must be platform-specific: Windows uses .pyd, while Unix/macOS require .cpython-XY-{platform}.so with SOABI included. The current hardcoded .pyd value will cause extension module discovery to fail on non-Windows platforms.

Ensure either:

  1. This module is Windows-only (gated with #[cfg(windows)]), or
  2. EXT_SUFFIX is set conditionally based on the target platform, with appropriate SOABI values for Unix/macOS
🤖 Prompt for AI Agents
crates/vm/src/stdlib/sysconfig.rs lines 10-21: the code hardcodes EXT_SUFFIX to
".pyd" which is only valid on Windows and misses SOABI for Unix/macOS; change
this by gating the Windows-specific assignment behind #[cfg(windows)] (or
runtime cfg!(windows)) and for non-Windows targets set EXT_SUFFIX to a
dot-prefixed SO filename (e.g. the cpython-style suffix that includes
ABI/version and platform) and populate SOABI with the corresponding value;
ensure EXT_SUFFIX always begins with '.' for pip compatibility and
unwrap/error-handle setters as before.


vars
}
}
Loading
Loading