Files
RustPython/vm/src/utils.rs
Daniel Chiquito bf461cdebc Use CPython hash algorithm for frozenset
The original hash algorithm just XOR'd all the hashes of the elements of
the set, which is problematic. The CPython algorithm is required to pass
the tests.

- Replace `PyFrozenSet::hash` with CPython's algorithm
- Remove unused `hash_iter_unorded` functions
- Add `frozenset` benchmark
- Enable tests
- Lower performance expectations on effectiveness test
- Adjust `slot::hash_wrapper` so that it doesn't rehash the computed
  hash value in the process of converting PyInt to PyHash.
2024-02-09 21:02:40 -05:00

73 lines
1.8 KiB
Rust

use crate::{
builtins::PyStr,
convert::{ToPyException, ToPyObject},
PyObjectRef, PyResult, VirtualMachine,
};
pub fn hash_iter<'a, I: IntoIterator<Item = &'a PyObjectRef>>(
iter: I,
vm: &VirtualMachine,
) -> PyResult<rustpython_common::hash::PyHash> {
vm.state.hash_secret.hash_iter(iter, |obj| obj.hash(vm))
}
impl ToPyObject for std::convert::Infallible {
fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
match self {}
}
}
pub trait ToCString {
fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString>;
}
impl ToCString for &str {
fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString> {
std::ffi::CString::new(*self).map_err(|err| err.to_pyexception(vm))
}
}
impl ToCString for PyStr {
fn to_cstring(&self, vm: &VirtualMachine) -> PyResult<std::ffi::CString> {
std::ffi::CString::new(self.as_ref()).map_err(|err| err.to_pyexception(vm))
}
}
pub(crate) fn collection_repr<'a, I>(
class_name: Option<&str>,
prefix: &str,
suffix: &str,
iter: I,
vm: &VirtualMachine,
) -> PyResult<String>
where
I: std::iter::Iterator<Item = &'a PyObjectRef>,
{
let mut repr = String::new();
if let Some(name) = class_name {
repr.push_str(name);
repr.push('(');
}
repr.push_str(prefix);
{
let mut parts_iter = iter.map(|o| o.repr(vm));
repr.push_str(
parts_iter
.next()
.transpose()?
.expect("this is not called for empty collection")
.as_str(),
);
for part in parts_iter {
repr.push_str(", ");
repr.push_str(part?.as_str());
}
}
repr.push_str(suffix);
if class_name.is_some() {
repr.push(')');
}
Ok(repr)
}