_locale.localeconv (#6941)

This commit is contained in:
Jeong, YunWon
2026-02-02 02:02:12 +09:00
committed by GitHub
parent 5e732c5e2a
commit d8e582ef6e
2 changed files with 36 additions and 6 deletions

View File

@@ -155,7 +155,6 @@ class _LocaleTests(unittest.TestCase):
if not tested:
self.skipTest('no suitable locales')
@unittest.skipIf(sys.platform in ('darwin', 'win32'), "TODO: RUSTPYTHON thread 'main' (18894384) panicked at crates/stdlib/src/locale.rs:106:14: localeconv always return decodable string: Utf8Error { valid_up_to: 0, error_len: Some(1) }")
@unittest.skipIf(support.linked_to_musl(), "musl libc issue, bpo-46390")
def test_lc_numeric_localeconv(self):
# Test localeconv against known values
@@ -269,7 +268,6 @@ class _LocaleTests(unittest.TestCase):
if not tested:
self.skipTest('no suitable locales')
@unittest.skipIf(sys.platform in ('darwin', 'win32'), "TODO: RUSTPYTHON thread 'main' (18894384) panicked at crates/stdlib/src/locale.rs:106:14: localeconv always return decodable string: Utf8Error { valid_up_to: 0, error_len: Some(1) }")
def test_float_parsing(self):
# Bug #1391872: Test whether float parsing is okay on European
# locales.

View File

@@ -101,10 +101,42 @@ mod _locale {
unsafe fn pystr_from_raw_cstr(vm: &VirtualMachine, raw_ptr: *const libc::c_char) -> PyResult {
let slice = unsafe { CStr::from_ptr(raw_ptr) };
let string = slice
.to_str()
.expect("localeconv always return decodable string");
Ok(vm.new_pyobj(string))
// Fast path: ASCII/UTF-8
if let Ok(s) = slice.to_str() {
return Ok(vm.new_pyobj(s));
}
// On Windows, locale strings use the ANSI code page encoding
#[cfg(windows)]
{
use windows_sys::Win32::Globalization::{CP_ACP, MultiByteToWideChar};
let bytes = slice.to_bytes();
unsafe {
let len = MultiByteToWideChar(
CP_ACP,
0,
bytes.as_ptr(),
bytes.len() as i32,
ptr::null_mut(),
0,
);
if len > 0 {
let mut wide = vec![0u16; len as usize];
MultiByteToWideChar(
CP_ACP,
0,
bytes.as_ptr(),
bytes.len() as i32,
wide.as_mut_ptr(),
len,
);
return Ok(vm.new_pyobj(String::from_utf16_lossy(&wide)));
}
}
}
Ok(vm.new_pyobj(String::from_utf8_lossy(slice.to_bytes()).into_owned()))
}
#[pyattr(name = "Error", once)]