Add strxfrm and strcoll to locale mod (#4603)

This commit is contained in:
John Pham
2023-03-04 01:21:04 +07:00
committed by GitHub
parent d09527b75e
commit f3e9413b2d
2 changed files with 21 additions and 8 deletions

View File

@@ -343,8 +343,7 @@ class TestFrFRNumberFormatting(FrFRCookedTest, BaseFormattingTest):
class TestCollation(unittest.TestCase):
# Test string collation functions
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_strcoll(self):
self.assertLess(locale.strcoll('a', 'b'), 0)
self.assertEqual(locale.strcoll('a', 'a'), 0)
@@ -353,8 +352,7 @@ class TestCollation(unittest.TestCase):
self.assertRaises(ValueError, locale.strcoll, 'a\0', 'a')
self.assertRaises(ValueError, locale.strcoll, 'a', 'a\0')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_strxfrm(self):
self.assertLess(locale.strxfrm('a'), locale.strxfrm('b'))
# embedded null character
@@ -381,8 +379,6 @@ class TestEnUSCollation(BaseLocalizedTest, TestCollation):
is_emscripten or is_wasi,
"musl libc issue on Emscripten/WASI, bpo-46390"
)
# TODO: RUSTPYTHON", strcoll has not been implemented
@unittest.expectedFailure
def test_strcoll_with_diacritic(self):
self.assertLess(locale.strcoll('à', 'b'), 0)
@@ -392,8 +388,6 @@ class TestEnUSCollation(BaseLocalizedTest, TestCollation):
is_emscripten or is_wasi,
"musl libc issue on Emscripten/WASI, bpo-46390"
)
# TODO: RUSTPYTHON", strxfrm has not been implemented
@unittest.expectedFailure
def test_strxfrm_with_diacritic(self):
self.assertLess(locale.strxfrm('à'), locale.strxfrm('b'))

View File

@@ -67,6 +67,25 @@ mod _locale {
)
}
#[pyfunction]
fn strcoll(string1: PyStrRef, string2: PyStrRef, vm: &VirtualMachine) -> PyResult {
let cstr1 = CString::new(string1.as_str()).map_err(|e| e.to_pyexception(vm))?;
let cstr2 = CString::new(string2.as_str()).map_err(|e| e.to_pyexception(vm))?;
Ok(vm.new_pyobj(unsafe { libc::strcoll(cstr1.as_ptr(), cstr2.as_ptr()) }))
}
#[pyfunction]
fn strxfrm(string: PyStrRef, vm: &VirtualMachine) -> PyResult {
// https://github.com/python/cpython/blob/eaae563b6878aa050b4ad406b67728b6b066220e/Modules/_localemodule.c#L390-L442
let n1 = string.byte_len() + 1;
let mut buff: Vec<u8> = vec![0; n1];
let cstr = CString::new(string.as_str()).map_err(|e| e.to_pyexception(vm))?;
let n2 = unsafe { libc::strxfrm(buff.as_mut_ptr() as _, cstr.as_ptr(), n1) };
buff.truncate(n2);
Ok(vm.new_pyobj(String::from_utf8(buff).expect("strxfrm returned invalid utf-8 string")))
}
#[pyfunction]
fn localeconv(vm: &VirtualMachine) -> PyResult<PyDictRef> {
let result = vm.ctx.new_dict();