mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Add a lazily calculated hash field to PyString
This commit is contained in:
@@ -250,12 +250,9 @@ fn builtin_format(
|
||||
format_spec: OptionalArg<PyStringRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyStringRef> {
|
||||
let format_spec = format_spec.into_option().unwrap_or_else(|| {
|
||||
PyString {
|
||||
value: "".to_string(),
|
||||
}
|
||||
.into_ref(vm)
|
||||
});
|
||||
let format_spec = format_spec
|
||||
.into_option()
|
||||
.unwrap_or_else(|| PyString::from("").into_ref(vm));
|
||||
|
||||
vm.call_method(&value, "__format__", vec![format_spec.into_object()])?
|
||||
.downcast()
|
||||
|
||||
@@ -54,6 +54,7 @@ use unicode_categories::UnicodeCategories;
|
||||
pub struct PyString {
|
||||
// TODO: shouldn't be public
|
||||
pub value: String,
|
||||
hash: Cell<Option<pyhash::PyHash>>,
|
||||
}
|
||||
|
||||
impl PyString {
|
||||
@@ -64,8 +65,15 @@ impl PyString {
|
||||
|
||||
impl From<&str> for PyString {
|
||||
fn from(s: &str) -> PyString {
|
||||
s.to_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for PyString {
|
||||
fn from(s: String) -> PyString {
|
||||
PyString {
|
||||
value: s.to_string(),
|
||||
value: s,
|
||||
hash: Cell::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,16 +88,13 @@ impl fmt::Display for PyString {
|
||||
|
||||
impl TryIntoRef<PyString> for String {
|
||||
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyString>> {
|
||||
Ok(PyString { value: self }.into_ref(vm))
|
||||
Ok(PyString::from(self).into_ref(vm))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryIntoRef<PyString> for &str {
|
||||
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyString>> {
|
||||
Ok(PyString {
|
||||
value: self.to_string(),
|
||||
}
|
||||
.into_ref(vm))
|
||||
Ok(PyString::from(self).into_ref(vm))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +264,14 @@ impl PyString {
|
||||
|
||||
#[pymethod(name = "__hash__")]
|
||||
fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
|
||||
pyhash::hash_value(&self.value)
|
||||
match self.hash.get() {
|
||||
Some(hash) => hash,
|
||||
None => {
|
||||
let hash = pyhash::hash_value(&self.value);
|
||||
self.hash.set(Some(hash));
|
||||
hash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(name = "__len__")]
|
||||
|
||||
@@ -380,7 +380,7 @@ impl PyContext {
|
||||
}
|
||||
|
||||
pub fn new_str(&self, s: String) -> PyObjectRef {
|
||||
PyObject::new(objstr::PyString { value: s }, self.str_type(), None)
|
||||
PyObject::new(objstr::PyString::from(s), self.str_type(), None)
|
||||
}
|
||||
|
||||
pub fn new_bytes(&self, data: Vec<u8>) -> PyObjectRef {
|
||||
|
||||
Reference in New Issue
Block a user