Refactor DictKey - Remove &PyObject / PyObjectRef

This commit is contained in:
Jeong Yunwon committed 2022-05-16 18:14:19 +09:00
1 parent f335d60657
commit 8a2cd2ba08
29 files changed
+229 -202

No files matched your search

+2 -2
View File
@@ -74,7 +74,7 @@ mod _bisect {
while lo < hi {
// Handles issue 13496.
let mid = (lo + hi) / 2;
if a.get_item(mid, vm)?
if a.get_item(&mid, vm)?
.rich_compare_bool(&x, PyComparisonOp::Lt, vm)?
{
lo = mid + 1;
@@ -104,7 +104,7 @@ mod _bisect {
while lo < hi {
// Handles issue 13496.
let mid = (lo + hi) / 2;
if x.rich_compare_bool(&*a.get_item(mid, vm)?, PyComparisonOp::Lt, vm)? {
if x.rich_compare_bool(&*a.get_item(&mid, vm)?, PyComparisonOp::Lt, vm)? {
hi = mid;
} else {
lo = mid + 1;
+6 -2
View File
@@ -33,8 +33,12 @@ mod decl {
fn compiler_flag_names(vm: &VirtualMachine) -> PyDictRef {
let dict = vm.ctx.new_dict();
for (name, flag) in CodeFlags::NAME_MAPPING {
dict.set_item(vm.new_pyobj(flag.bits()), vm.ctx.new_str(*name).into(), vm)
.unwrap();
dict.set_item(
&*vm.new_pyobj(flag.bits()),
vm.ctx.new_str(*name).into(),
vm,
)
.unwrap();
}
dict
}
+41 -46
View File
@@ -86,8 +86,8 @@ impl PyDict {
if let Some(keys) = vm.get_method(other.clone(), "keys") {
let keys = vm.invoke(&keys?, ())?.get_iter(vm)?;
while let PyIterReturn::Return(key) = keys.next(vm)? {
let val = other.get_item(key.clone(), vm)?;
dict.insert(vm, key, val)?;
let val = other.get_item(&*key, vm)?;
dict.insert(vm, &*key, val)?;
}
} else {
let iter = other.get_iter(vm)?;
@@ -105,7 +105,7 @@ impl PyDict {
if matches!(elem_iter.next(vm)?, PyIterReturn::Return(_)) {
return Err(err(vm));
}
dict.insert(vm, key, value)?;
dict.insert(vm, &*key, value)?;
}
}
Ok(())
@@ -118,7 +118,7 @@ impl PyDict {
) -> PyResult<()> {
let dict_size = &dict_other.size();
for (key, value) in &dict_other {
dict.insert(vm, key, value)?;
dict.insert(vm, &*key, value)?;
}
if dict_other.entries.has_changed_size(dict_size) {
return Err(vm.new_runtime_error("dict mutated during update".to_owned()));
@@ -146,7 +146,7 @@ impl PyDict {
(zelf, other)
};
for (k, v1) in subset {
match superset.get_item_opt(k, vm)? {
match superset.get_item_opt(&*k, vm)? {
Some(v2) => {
if v1.is(&v2) {
continue;
@@ -169,18 +169,18 @@ impl PyDict {
/// Set item variant which can be called with multiple
/// key types, such as str to name a notable one.
pub(crate) fn inner_setitem<K: DictKey + ToPyObject>(
pub(crate) fn inner_setitem<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
self.entries.insert(vm, key, value)
}
pub(crate) fn inner_delitem<K: DictKey + ToPyObject>(
pub(crate) fn inner_delitem<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
vm: &VirtualMachine,
) -> PyResult<()> {
self.entries.delete(vm, key)
@@ -192,22 +192,21 @@ impl PyDict {
key: PyObjectRef,
default: impl FnOnce() -> PyObjectRef,
) -> PyResult {
self.entries.setdefault(vm, key, default)
self.entries.setdefault(vm, &*key, default)
}
pub fn from_attributes(attrs: PyAttributes, vm: &VirtualMachine) -> PyResult<Self> {
let dict = DictContentType::default();
for (key, value) in attrs {
dict.insert(vm, vm.new_pyobj(key), value)?;
dict.insert(vm, key.as_str(), value)?;
}
Ok(PyDict { entries: dict })
}
pub fn contains_key<K: ToPyObject>(&self, key: K, vm: &VirtualMachine) -> bool {
let key = key.to_pyobject(vm);
self.entries.contains(vm, &key).unwrap()
pub fn contains_key<K: DictKey + ?Sized>(&self, key: &K, vm: &VirtualMachine) -> bool {
self.entries.contains(vm, key).unwrap()
}
pub fn size(&self) -> dictdatatype::DictSize {
@@ -263,7 +262,7 @@ impl PyDict {
}
Err(pyobj) => {
for key in iterable.iter(vm)? {
pyobj.set_item(key?, value.clone(), vm)?;
pyobj.set_item(&*key?, value.clone(), vm)?;
}
Ok(pyobj)
}
@@ -304,12 +303,12 @@ impl PyDict {
#[pymethod(magic)]
fn contains(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
self.entries.contains(vm, &key)
self.entries.contains(vm, &*key)
}
#[pymethod(magic)]
fn delitem(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.inner_delitem(key, vm)
self.inner_delitem(&*key, vm)
}
#[pymethod]
@@ -334,13 +333,13 @@ impl PyDict {
#[pymethod(magic)]
fn setitem(&self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.inner_setitem(key, value, vm)
self.inner_setitem(&*key, value, vm)
}
#[pymethod(magic)]
#[cfg_attr(feature = "flame-it", flame("PyDictRef"))]
fn getitem(zelf: PyRef<Self>, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
zelf.inner_getitem(key, vm)
zelf.inner_getitem(&*key, vm)
}
#[pymethod]
@@ -350,7 +349,7 @@ impl PyDict {
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
match self.entries.get(vm, &key)? {
match self.entries.get(vm, &*key)? {
Some(value) => Ok(value),
None => Ok(default.unwrap_or_none(vm)),
}
@@ -364,7 +363,7 @@ impl PyDict {
vm: &VirtualMachine,
) -> PyResult {
self.entries
.setdefault(vm, key, || default.unwrap_or_none(vm))
.setdefault(vm, &*key, || default.unwrap_or_none(vm))
}
#[pymethod]
@@ -385,7 +384,7 @@ impl PyDict {
Self::merge_object(&self.entries, dict_obj, vm)?;
}
for (key, value) in kwargs.into_iter() {
self.entries.insert(vm, vm.new_pyobj(key), value)?;
self.entries.insert(vm, &key, value)?;
}
Ok(())
}
@@ -425,7 +424,7 @@ impl PyDict {
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
match self.entries.pop(vm, &key)? {
match self.entries.pop(vm, &*key)? {
Some(value) => Ok(value),
None => default.ok_or_else(|| vm.new_key_error(key)),
}
@@ -523,25 +522,25 @@ impl Py<PyDict> {
self.class().is(&vm.ctx.types.dict_type)
}
fn missing_opt<K: DictKey + ToPyObject>(
fn missing_opt<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
vm.get_method(self.to_owned().into(), "__missing__")
.map(|methods| vm.invoke(&methods?, (key,)))
.map(|methods| vm.invoke(&methods?, (key.to_pyobject(vm),)))
.transpose()
}
#[inline]
fn inner_getitem<K: DictKey + ToPyObject + Clone>(
fn inner_getitem<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
if let Some(value) = self.entries.get(vm, &key)? {
if let Some(value) = self.entries.get(vm, key)? {
Ok(value)
} else if let Some(value) = self.missing_opt(key.clone(), vm)? {
} else if let Some(value) = self.missing_opt(key, vm)? {
Ok(value)
} else {
Err(vm.new_key_error(key.to_pyobject(vm)))
@@ -558,16 +557,16 @@ impl Py<PyDict> {
attrs
}
pub fn get_item_opt<K: DictKey + ToPyObject + Clone>(
pub fn get_item_opt<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
if self.exact_dict(vm) {
self.entries.get(vm, &key)
self.entries.get(vm, key)
// FIXME: check __missing__?
} else {
match self.as_object().get_item(key.clone(), vm) {
match self.as_object().get_item(key, vm) {
Ok(value) => Ok(Some(value)),
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {
self.missing_opt(key, vm)
@@ -577,11 +576,7 @@ impl Py<PyDict> {
}
}
pub fn get_item<K: DictKey + ToPyObject + Clone>(
&self,
key: K,
vm: &VirtualMachine,
) -> PyResult {
pub fn get_item<K: DictKey + ?Sized>(&self, key: &K, vm: &VirtualMachine) -> PyResult {
if self.exact_dict(vm) {
self.inner_getitem(key, vm)
} else {
@@ -589,9 +584,9 @@ impl Py<PyDict> {
}
}
pub fn set_item<K: DictKey + ToPyObject>(
pub fn set_item<K: DictKey + ?Sized>(
&self,
key: K,
key: &K,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -602,7 +597,7 @@ impl Py<PyDict> {
}
}
pub fn del_item<K: DictKey + ToPyObject>(&self, key: K, vm: &VirtualMachine) -> PyResult<()> {
pub fn del_item<K: DictKey + ?Sized>(&self, key: &K, vm: &VirtualMachine) -> PyResult<()> {
if self.exact_dict(vm) {
self.inner_delitem(key, vm)
} else {
@@ -610,17 +605,17 @@ impl Py<PyDict> {
}
}
pub fn get_chain<K: ToPyObject + DictKey + Clone>(
pub fn get_chain<K: DictKey + ?Sized>(
&self,
other: &Self,
key: K,
key: &K,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let self_exact = self.exact_dict(vm);
let other_exact = other.exact_dict(vm);
if self_exact && other_exact {
self.entries.get_chain(&other.entries, vm, &key)
} else if let Some(value) = self.get_item_opt(key.clone(), vm)? {
self.entries.get_chain(&other.entries, vm, key)
} else if let Some(value) = self.get_item_opt(key, vm)? {
Ok(Some(value))
} else {
other.get_item_opt(key, vm)
+1 -1
View File
@@ -128,7 +128,7 @@ impl IterNext for PyReverseSequenceIterator {
fn next(zelf: &crate::Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
zelf.internal
.lock()
.rev_next(|obj, pos| PyIterReturn::from_getitem_result(obj.get_item(pos, vm), vm))
.rev_next(|obj, pos| PyIterReturn::from_getitem_result(obj.get_item(&pos, vm), vm))
}
}
+2 -2
View File
@@ -137,7 +137,7 @@ impl PyFunction {
}
*slot = Some(value);
} else if let Some(kwargs) = kwargs.as_ref() {
kwargs.set_item(name, value, vm)?;
kwargs.set_item(&name, value, vm)?;
} else if argpos(0..code.posonlyarg_count, &name).is_some() {
posonly_passed_as_kwarg.push(name);
} else {
@@ -242,7 +242,7 @@ impl PyFunction {
.filter(|(slot, _)| slot.is_none())
{
if let Some(defaults) = &get_defaults!().1 {
if let Some(default) = defaults.get_item_opt(kwarg.clone(), vm)? {
if let Some(default) = defaults.get_item_opt(&*kwarg, vm)? {
*slot = Some(default);
continue;
}
+1 -1
View File
@@ -188,7 +188,7 @@ pub(crate) fn get_jit_args<'a>(
let arg_idx = i + func.code.arg_count;
if !jit_args.is_set(arg_idx) {
let default = kw_only_defaults
.get_item(name.clone(), vm)
.get_item(&*name, vm)
.map_err(|_| ArgsError::NotAllArgsPassed)
.and_then(|obj| get_jit_value(vm, &obj))?;
jit_args.set(arg_idx, default)?;
+1 -1
View File
@@ -249,7 +249,7 @@ fn subs_tvars(
})
.collect::<Vec<_>>();
let sub_args: PyObjectRef = PyTuple::new_ref(sub_args, &vm.ctx).into();
Some(obj.get_item(sub_args, vm))
Some(obj.get_item(&*sub_args, vm))
} else {
None
}
+1 -1
View File
@@ -67,7 +67,7 @@ impl PyMappingProxy {
let key = PyStrRef::try_from_object(vm, key)?;
class.attributes.read().get(key.as_str()).cloned()
}
MappingProxyInner::Dict(obj) => obj.get_item(key, vm).ok(),
MappingProxyInner::Dict(obj) => obj.get_item(&*key, vm).ok(),
};
Ok(opt)
}
+4 -6
View File
@@ -174,7 +174,7 @@ impl PySetInner {
) -> PyResult<PySetInner> {
let set = self.copy();
for item in other.iter(vm)? {
set.content.delete_if_exists(vm, &item?)?;
set.content.delete_if_exists(vm, &*item?)?;
}
Ok(set)
}
@@ -231,13 +231,11 @@ impl PySetInner {
}
fn add(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.content.insert(vm, item, ())
self.content.insert(vm, &*item, ())
}
fn remove(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.retry_op_with_frozenset(&item, vm, |item, vm| {
self.content.delete(vm, item.to_owned())
})
self.retry_op_with_frozenset(&item, vm, |item, vm| self.content.delete(vm, item))
}
fn discard(&self, item: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
@@ -293,7 +291,7 @@ impl PySetInner {
fn difference_update(&self, others: PosArgs<ArgIterable>, vm: &VirtualMachine) -> PyResult<()> {
for iterable in others {
for item in iterable.iter(vm)? {
self.content.delete_if_exists(vm, &item?)?;
self.content.delete_if_exists(vm, &*item?)?;
}
}
Ok(())
+10 -5
View File
@@ -1147,7 +1147,7 @@ impl PyStr {
let mut translated = String::new();
for c in self.as_str().chars() {
match table.get_item((c as u32).to_pyobject(vm), vm) {
match table.get_item(&*(c as u32).to_pyobject(vm), vm) {
Ok(value) => {
if let Some(text) = value.payload::<PyStr>() {
translated.push_str(text.as_str());
@@ -1188,14 +1188,14 @@ impl PyStr {
if to_str.len() == from_str.len() {
for (c1, c2) in from_str.as_str().chars().zip(to_str.as_str().chars()) {
new_dict.set_item(
vm.new_pyobj(c1 as u32),
&*vm.new_pyobj(c1 as u32),
vm.new_pyobj(c2 as u32),
vm,
)?;
}
if let OptionalArg::Present(none_str) = none_str {
for c in none_str.as_str().chars() {
new_dict.set_item(vm.new_pyobj(c as u32), vm.ctx.none(), vm)?;
new_dict.set_item(&*vm.new_pyobj(c as u32), vm.ctx.none(), vm)?;
}
}
Ok(new_dict.to_pyobject(vm))
@@ -1215,12 +1215,17 @@ impl PyStr {
match dict_or_str.downcast::<PyDict>() {
Ok(dict) => {
for (key, val) in dict {
// FIXME: ints are key-compatible
if let Some(num) = key.payload::<PyInt>() {
new_dict.set_item(num.as_bigint().to_i32().to_pyobject(vm), val, vm)?;
new_dict.set_item(
&*num.as_bigint().to_i32().to_pyobject(vm),
val,
vm,
)?;
} else if let Some(string) = key.payload::<PyStr>() {
if string.len() == 1 {
let num_value = string.as_str().chars().next().unwrap() as u32;
new_dict.set_item(num_value.to_pyobject(vm), val, vm)?;
new_dict.set_item(&*num_value.to_pyobject(vm), val, vm)?;
} else {
return Err(vm.new_value_error(
"string keys in translate table must be of length 1".to_owned(),
+107 -65
View File
@@ -252,13 +252,13 @@ impl<T: Clone> Dict<T> {
}
/// Store a key
pub fn insert<K>(&self, vm: &VirtualMachine, key: K, value: T) -> PyResult<()>
pub fn insert<K>(&self, vm: &VirtualMachine, key: &K, value: T) -> PyResult<()>
where
K: DictKey + ToPyObject,
K: DictKey + ?Sized,
{
let hash = key.key_hash(vm)?;
let _removed = loop {
let (entry_index, index_index) = self.lookup(vm, &key, hash, None)?;
let (entry_index, index_index) = self.lookup(vm, key, hash, None)?;
let mut inner = self.write();
if let IndexEntry::Index(index) = entry_index {
// Update existing key
@@ -285,19 +285,19 @@ impl<T: Clone> Dict<T> {
Ok(())
}
pub fn contains<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<bool> {
pub fn contains<K: DictKey + ?Sized>(&self, vm: &VirtualMachine, key: &K) -> PyResult<bool> {
let (entry, _) = self.lookup(vm, key, key.key_hash(vm)?, None)?;
Ok(matches!(entry, IndexEntry::Index(_)))
}
/// Retrieve a key
#[cfg_attr(feature = "flame-it", flame("Dict"))]
pub fn get<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
pub fn get<K: DictKey + ?Sized>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
let hash = key.key_hash(vm)?;
self._get_inner(vm, key, hash)
}
fn _get_inner<K: DictKey>(
fn _get_inner<K: DictKey + ?Sized>(
&self,
vm: &VirtualMachine,
key: &K,
@@ -325,7 +325,7 @@ impl<T: Clone> Dict<T> {
Ok(ret)
}
pub fn get_chain<K: DictKey>(
pub fn get_chain<K: DictKey + ?Sized>(
&self,
other: &Self,
vm: &VirtualMachine,
@@ -353,11 +353,11 @@ impl<T: Clone> Dict<T> {
}
/// Delete a key
pub fn delete<K>(&self, vm: &VirtualMachine, key: K) -> PyResult<()>
pub fn delete<K>(&self, vm: &VirtualMachine, key: &K) -> PyResult<()>
where
K: DictKey + ToPyObject,
K: DictKey + ?Sized,
{
if self.delete_if_exists(vm, &key)? {
if self.delete_if_exists(vm, key)? {
Ok(())
} else {
Err(vm.new_key_error(key.to_pyobject(vm)))
@@ -366,7 +366,7 @@ impl<T: Clone> Dict<T> {
pub fn delete_if_exists<K>(&self, vm: &VirtualMachine, key: &K) -> PyResult<bool>
where
K: DictKey,
K: DictKey + ?Sized,
{
self.delete_if(vm, key, |_| Ok(true))
}
@@ -375,7 +375,7 @@ impl<T: Clone> Dict<T> {
/// the dict's internal mutex is held
pub(crate) fn delete_if<K, F>(&self, vm: &VirtualMachine, key: &K, pred: F) -> PyResult<bool>
where
K: DictKey,
K: DictKey + ?Sized,
F: Fn(&T) -> PyResult<bool>,
{
let hash = key.key_hash(vm)?;
@@ -408,14 +408,14 @@ impl<T: Clone> Dict<T> {
Ok(())
}
pub fn setdefault<K, F>(&self, vm: &VirtualMachine, key: K, default: F) -> PyResult<T>
pub fn setdefault<K, F>(&self, vm: &VirtualMachine, key: &K, default: F) -> PyResult<T>
where
K: DictKey + ToPyObject,
K: DictKey + ?Sized,
F: FnOnce() -> T,
{
let hash = key.key_hash(vm)?;
let res = loop {
let lookup = self.lookup(vm, &key, hash, None)?;
let lookup = self.lookup(vm, key, hash, None)?;
let (entry, index_index) = lookup;
if let IndexEntry::Index(index) = entry {
let inner = self.read();
@@ -444,16 +444,16 @@ impl<T: Clone> Dict<T> {
pub fn setdefault_entry<K, F>(
&self,
vm: &VirtualMachine,
key: K,
key: &K,
default: F,
) -> PyResult<(PyObjectRef, T)>
where
K: DictKey + ToPyObject,
K: DictKey + ?Sized,
F: FnOnce() -> T,
{
let hash = key.key_hash(vm)?;
let res = loop {
let lookup = self.lookup(vm, &key, hash, None)?;
let lookup = self.lookup(vm, key, hash, None)?;
let (entry, index_index) = lookup;
if let IndexEntry::Index(index) = entry {
let inner = self.read();
@@ -533,7 +533,7 @@ impl<T: Clone> Dict<T> {
/// Lookup the index for the given key.
#[cfg_attr(feature = "flame-it", flame("Dict"))]
fn lookup<K: DictKey>(
fn lookup<K: DictKey + ?Sized>(
&self,
vm: &VirtualMachine,
key: &K,
@@ -630,7 +630,7 @@ impl<T: Clone> Dict<T> {
}
/// Retrieve and delete a key
pub fn pop<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
pub fn pop<K: DictKey + ?Sized>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
let hash_value = key.key_hash(vm)?;
let removed = loop {
let lookup = self.lookup(vm, key, hash_value, None)?;
@@ -671,6 +671,11 @@ type LookupResult = (IndexEntry, IndexIndex);
/// - PyObjectRef -> arbitrary python type used as key
/// - str -> string reference used as key, this is often used internally
pub trait DictKey {
type Owned: ToPyObject;
fn _to_owned(&self, vm: &VirtualMachine) -> Self::Owned;
fn to_pyobject(&self, vm: &VirtualMachine) -> PyObjectRef {
self._to_owned(vm).to_pyobject(vm)
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue>;
fn key_is(&self, other: &PyObject) -> bool;
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool>;
@@ -679,45 +684,13 @@ pub trait DictKey {
/// Implement trait for PyObjectRef such that we can use python objects
/// to index dictionaries.
impl DictKey for PyObjectRef {
#[inline]
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
(**self).key_hash(vm)
}
#[inline]
fn key_is(&self, other: &PyObject) -> bool {
(**self).key_is(other)
}
#[inline]
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
(**self).key_eq(vm, other_key)
}
#[inline]
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
(**self).key_as_isize(vm)
}
}
impl DictKey for &PyObject {
#[inline]
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
(**self).key_hash(vm)
}
#[inline]
fn key_is(&self, other: &PyObject) -> bool {
(**self).key_is(other)
}
#[inline]
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
(**self).key_eq(vm, other_key)
}
#[inline]
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
(**self).key_as_isize(vm)
}
}
impl DictKey for PyObject {
type Owned = PyObjectRef;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.to_owned()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
self.hash(vm)
}
@@ -736,6 +709,12 @@ impl DictKey for PyObject {
}
impl DictKey for Py<PyStr> {
type Owned = PyStrRef;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.to_owned()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
Ok(self.hash(vm))
}
@@ -760,6 +739,12 @@ impl DictKey for Py<PyStr> {
}
impl DictKey for PyStrRef {
type Owned = Self;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.clone()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
Ok(self.hash(vm))
}
@@ -784,6 +769,12 @@ impl DictKey for PyStrRef {
}
impl DictKey for PyRefExact<PyStr> {
type Owned = Self;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.clone()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
(**self).key_hash(vm)
}
@@ -803,6 +794,12 @@ impl DictKey for PyRefExact<PyStr> {
/// Implement trait for the str type, so that we can use strings
/// to index dictionaries.
impl DictKey for &str {
type Owned = String;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
(**self).to_owned()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
// follow a similar route as the hashing of PyStrRef
Ok(vm.state.hash_secret.hash_str(*self))
@@ -829,7 +826,46 @@ impl DictKey for &str {
}
}
impl DictKey for str {
type Owned = String;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.to_owned()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
// follow a similar route as the hashing of PyStrRef
Ok(vm.state.hash_secret.hash_str(self))
}
fn key_is(&self, _other: &PyObject) -> bool {
// No matter who the other pyobject is, we are never the same thing, since
// we are a str, not a pyobject.
false
}
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
if let Some(pystr) = str_exact(other_key, vm) {
Ok(pystr.as_str() == self)
} else {
// Fall back to PyObjectRef implementation.
let s = vm.ctx.new_str(self);
s.key_eq(vm, other_key)
}
}
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
Err(vm.new_type_error("'str' object cannot be interpreted as an integer".to_owned()))
}
}
impl DictKey for String {
type Owned = String;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
self.clone()
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
self.as_str().key_hash(vm)
}
@@ -848,6 +884,12 @@ impl DictKey for String {
}
impl DictKey for usize {
type Owned = usize;
#[inline]
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
*self
}
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
Ok(vm.state.hash_secret.hash_value(self))
}
@@ -902,25 +944,25 @@ mod tests {
let key1 = vm.new_pyobj(true);
let value1 = vm.new_pyobj(ascii!("abc"));
dict.insert(&vm, key1.clone(), value1.clone()).unwrap();
dict.insert(&vm, &*key1, value1.clone()).unwrap();
assert_eq!(1, dict.len());
let key2 = vm.new_pyobj(ascii!("x"));
let value2 = vm.new_pyobj(ascii!("def"));
dict.insert(&vm, key2.clone(), value2.clone()).unwrap();
dict.insert(&vm, &*key2, value2.clone()).unwrap();
assert_eq!(2, dict.len());
dict.insert(&vm, key1.clone(), value2.clone()).unwrap();
dict.insert(&vm, &*key1, value2.clone()).unwrap();
assert_eq!(2, dict.len());
dict.delete(&vm, key1.clone()).unwrap();
dict.delete(&vm, &*key1).unwrap();
assert_eq!(1, dict.len());
dict.insert(&vm, key1.clone(), value2.clone()).unwrap();
dict.insert(&vm, &*key1, value2.clone()).unwrap();
assert_eq!(2, dict.len());
assert_eq!(true, dict.contains(&vm, &key1).unwrap());
assert_eq!(true, dict.contains(&vm, &"x").unwrap());
assert_eq!(true, dict.contains(&vm, &*key1).unwrap());
assert_eq!(true, dict.contains(&vm, "x").unwrap());
let val = dict.get(&vm, &"x").unwrap().unwrap();
vm.bool_eq(&val, &value2)
+3 -3
View File
@@ -812,10 +812,10 @@ impl FormatString {
argument = argument.get_attr(attribute.as_str(), vm)?;
}
FieldNamePart::Index(index) => {
argument = argument.get_item(index, vm)?;
argument = argument.get_item(&index, vm)?;
}
FieldNamePart::StringIndex(index) => {
argument = argument.get_item(index, vm)?;
argument = argument.get_item(&index, vm)?;
}
}
}
@@ -877,7 +877,7 @@ impl FormatString {
FieldType::Auto | FieldType::Index(_) => {
Err(vm.new_value_error("Format string contains positional fields".to_owned()))
}
FieldType::Keyword(keyword) => dict.get_item(keyword, vm),
FieldType::Keyword(keyword) => dict.get_item(&keyword, vm),
})
}
}
+17 -15
View File
@@ -17,7 +17,7 @@ use crate::{
scope::Scope,
stdlib::builtins,
vm::PyMethod,
AsObject, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
};
use indexmap::IndexMap;
use itertools::Itertools;
@@ -543,7 +543,7 @@ impl ExecutingFrame<'_> {
bytecode::Instruction::StoreGlobal(idx) => {
let value = self.pop_value();
self.globals
.set_item(self.code.names[*idx as usize].clone(), value, vm)?;
.set_item(&*self.code.names[*idx as usize].clone(), value, vm)?;
Ok(None)
}
bytecode::Instruction::StoreDeref(i) => {
@@ -572,7 +572,7 @@ impl ExecutingFrame<'_> {
}
bytecode::Instruction::DeleteGlobal(idx) => {
let name = &self.code.names[*idx as usize];
match self.globals.del_item(name.clone(), vm) {
match self.globals.del_item(&*name, vm) {
Ok(()) => {}
Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {
return Err(
@@ -695,7 +695,7 @@ impl ExecutingFrame<'_> {
};
let key = self.pop_value();
let value = self.pop_value();
dict.set_item(key, value, vm)?;
dict.set_item(&*key, value, vm)?;
Ok(None)
}
bytecode::Instruction::MapAddRev { i } => {
@@ -707,7 +707,7 @@ impl ExecutingFrame<'_> {
};
let value = self.pop_value();
let key = self.pop_value();
dict.set_item(key, value, vm)?;
dict.set_item(&*key, value, vm)?;
Ok(None)
}
bytecode::Instruction::BinaryOperation { op } => self.execute_binop(vm, *op),
@@ -1097,10 +1097,12 @@ impl ExecutingFrame<'_> {
}
#[inline]
fn load_global_or_builtin(&self, name: &PyStrRef, vm: &VirtualMachine) -> PyResult {
fn load_global_or_builtin(&self, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
self.globals
.get_chain(self.builtins, name.clone(), vm)?
.ok_or_else(|| vm.new_name_error(format!("name '{}' is not defined", name), name))
.get_chain(self.builtins, name, vm)?
.ok_or_else(|| {
vm.new_name_error(format!("name '{}' is not defined", name), &name.to_owned())
})
}
#[cfg_attr(feature = "flame-it", flame("Frame"))]
@@ -1153,7 +1155,7 @@ impl ExecutingFrame<'_> {
.clone()
.get_attr("modules", vm)
.map_err(|_| err())?;
sys_modules.get_item(full_mod_name, vm).map_err(|_| err())
sys_modules.get_item(&full_mod_name, vm).map_err(|_| err())
}
#[cfg_attr(feature = "flame-it", flame("Frame"))]
@@ -1260,7 +1262,7 @@ impl ExecutingFrame<'_> {
fn execute_subscript(&mut self, vm: &VirtualMachine) -> FrameResult {
let b_ref = self.pop_value();
let a_ref = self.pop_value();
let value = a_ref.get_item(b_ref, vm)?;
let value = a_ref.get_item(&*b_ref, vm)?;
self.push_value(value);
Ok(None)
}
@@ -1269,14 +1271,14 @@ impl ExecutingFrame<'_> {
let idx = self.pop_value();
let obj = self.pop_value();
let value = self.pop_value();
obj.set_item(idx, value, vm)?;
obj.set_item(&*idx, value, vm)?;
Ok(None)
}
fn execute_delete_subscript(&mut self, vm: &VirtualMachine) -> FrameResult {
let idx = self.pop_value();
let obj = self.pop_value();
obj.del_item(idx, vm)?;
obj.del_item(&*idx, vm)?;
Ok(None)
}
@@ -1298,7 +1300,7 @@ impl ExecutingFrame<'_> {
for (key, value) in dict {
#[allow(clippy::collapsible_if)]
if for_call {
if map_obj.contains_key(key.clone(), vm) {
if map_obj.contains_key(&*key, vm) {
let key_repr = &key.repr(vm)?;
let msg = format!(
"got multiple values for keyword argument {}",
@@ -1307,12 +1309,12 @@ impl ExecutingFrame<'_> {
return Err(vm.new_type_error(msg));
}
}
map_obj.set_item(key, value, vm)?;
map_obj.set_item(&*key, value, vm)?;
}
}
} else {
for (key, value) in self.pop_multiple(2 * size).tuples() {
map_obj.set_item(key, value, vm)?;
map_obj.set_item(&*key, value, vm)?;
}
}
+1 -2
View File
@@ -1,7 +1,6 @@
use crate::{
builtins::{PyStr, PyTypeRef},
common::lock::PyRwLock,
convert::ToPyObject,
PyRef, PyRefExact,
};
use std::ops::Deref;
@@ -89,7 +88,7 @@ mod sealed {
}
/// A sealed marker trait for `DictKey` types that always become an exact instance of `str`
pub trait Internable: sealed::SealedInternable + crate::dictdatatype::DictKey + ToPyObject {
pub trait Internable: sealed::SealedInternable + crate::dictdatatype::DictKey {
fn as_str(&self) -> &str;
fn into_pyref(self, str_type: PyTypeRef) -> PyRefExact<PyStr>;
}
+10 -20
View File
@@ -133,7 +133,7 @@ impl PyObject {
#[cfg_attr(feature = "flame-it", flame)]
pub fn generic_setattr(
&self,
attr_name: PyStrRef,
attr_name: PyStrRef, // TODO: Py<PyStr>
value: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -148,9 +148,9 @@ impl PyObject {
if let Some(dict) = self.dict() {
if let Some(value) = value {
dict.set_item(attr_name, value, vm)?;
dict.set_item(&*attr_name, value, vm)?;
} else {
dict.del_item(attr_name.clone(), vm).map_err(|e| {
dict.del_item(&*attr_name, vm).map_err(|e| {
if e.fast_isinstance(&vm.ctx.exceptions.key_error) {
vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
@@ -197,8 +197,7 @@ impl PyObject {
{
drop(descr_cls);
let cls = obj_cls.into_owned().into();
return descr_get(descr, Some(self.to_pyobject(vm)), Some(cls), vm)
.map(Some);
return descr_get(descr, Some(self.to_owned()), Some(cls), vm).map(Some);
}
}
drop(descr_cls);
@@ -221,14 +220,13 @@ impl PyObject {
match descr_get {
Some(descr_get) => {
let cls = obj_cls.into_owned().into();
descr_get(attr, Some(self.to_pyobject(vm)), Some(cls), vm).map(Some)
descr_get(attr, Some(self.to_owned()), Some(cls), vm).map(Some)
}
None => Ok(Some(attr)),
}
} else if let Some(getter) = obj_cls.get_attr("__getattr__") {
drop(obj_cls);
vm.invoke(&getter, (self.to_pyobject(vm), name_str))
.map(Some)
vm.invoke(&getter, (self.to_owned(), name_str)).map(Some)
} else {
Ok(None)
}
@@ -515,11 +513,7 @@ impl PyObject {
.ok_or_else(|| vm.new_type_error(format!("object of type '{}' has no len()", &self)))?
}
pub fn get_item<K: DictKey + ToPyObject + Clone>(
&self,
needle: K,
vm: &VirtualMachine,
) -> PyResult {
pub fn get_item<K: DictKey + ?Sized>(&self, needle: &K, vm: &VirtualMachine) -> PyResult {
if let Some(dict) = self.downcast_ref_if_exact::<PyDict>(vm) {
return dict.get_item(needle, vm);
}
@@ -547,9 +541,9 @@ impl PyObject {
}
}
pub fn set_item<K: DictKey + ToPyObject>(
pub fn set_item<K: DictKey + ?Sized>(
&self,
needle: K,
needle: &K,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -574,11 +568,7 @@ impl PyObject {
}
}
pub fn del_item<K: DictKey + ToPyObject>(
&self,
needle: K,
vm: &VirtualMachine,
) -> PyResult<()> {
pub fn del_item<K: DictKey + ?Sized>(&self, needle: &K, vm: &VirtualMachine) -> PyResult<()> {
if let Some(dict) = self.downcast_ref_if_exact::<PyDict>(vm) {
return dict.del_item(needle, vm);
}
+1 -1
View File
@@ -205,7 +205,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
// Although JSON keys must be strings, implementation accepts any keys
// and can be reused by other deserializers without such limit
while let Some((key_obj, value)) = access.next_entry_seed(self.clone(), self.clone())? {
dict.set_item(key_obj, value, self.vm).unwrap();
dict.set_item(&*key_obj, value, self.vm).unwrap();
}
Ok(dict.into())
}
+1 -3
View File
@@ -13,9 +13,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
for (name, code) in ERROR_CODES {
let name = vm.ctx.new_str(*name);
let code = vm.new_pyobj(*code);
errorcode
.set_item(code.clone(), name.clone().into(), vm)
.unwrap();
errorcode.set_item(&*code, name.clone().into(), vm).unwrap();
module.set_attr(name, code, vm).unwrap();
}
module
+1 -1
View File
@@ -76,7 +76,7 @@ mod _imp {
let name = spec.get_attr("name", vm)?;
let name = PyStrRef::try_from_object(vm, name)?;
if let Ok(module) = sys_modules.get_item(name.clone(), vm) {
if let Ok(module) = sys_modules.get_item(&*name, vm) {
Ok(module)
} else if let Some(make_module_func) = vm.state.module_inits.get(name.as_str()) {
Ok(make_module_func(vm))
+1 -5
View File
@@ -201,11 +201,7 @@ mod decl {
)),
});
// Marshalled tuples are always in format key:value.
dict.insert(
vm,
items.get(0).unwrap().clone(),
items.get(1).unwrap().clone(),
)?;
dict.insert(vm, &**items.get(0).unwrap(), items.get(1).unwrap().clone())?;
}
Ok(PyDict::from_entries(dict))
}
+1 -3
View File
@@ -80,9 +80,7 @@ pub(crate) mod module {
let environ = vm.ctx.new_dict();
for (key, value) in env::vars() {
environ
.set_item(vm.new_pyobj(key), vm.new_pyobj(value), vm)
.unwrap();
environ.set_item(&key, vm.new_pyobj(value), vm).unwrap();
}
environ
}
+5 -5
View File
@@ -226,13 +226,13 @@ mod _operator {
/// Remove the value of a at index b.
#[pyfunction]
fn delitem(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
a.del_item(b, vm)
a.del_item(&*b, vm)
}
/// Return the value of a at index b.
#[pyfunction]
fn getitem(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
a.get_item(b, vm)
a.get_item(&*b, vm)
}
/// Return the number of occurrences of b in a.
@@ -255,7 +255,7 @@ mod _operator {
c: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
a.set_item(b, c, vm)
a.set_item(&*b, c, vm)
}
/// Return an estimate of the number of items in obj.
@@ -565,12 +565,12 @@ mod _operator {
fn call(zelf: &Py<Self>, obj: Self::Args, vm: &VirtualMachine) -> PyResult {
// Handle case where we only have one attribute.
if zelf.items.len() == 1 {
return obj.get_item(zelf.items[0].clone(), vm);
return obj.get_item(&*zelf.items[0], vm);
}
// Build tuple and call get_single on each element in attrs.
let mut results = Vec::with_capacity(zelf.items.len());
for item in &zelf.items {
results.push(obj.get_item(item.clone(), vm)?);
results.push(obj.get_item(&**item, vm)?);
}
Ok(vm.ctx.new_tuple(results).into())
}
+1 -1
View File
@@ -291,7 +291,7 @@ pub mod module {
for (key, value) in env::vars_os() {
let key: PyObjectRef = vm.ctx.new_bytes(key.into_vec()).into();
let value: PyObjectRef = vm.ctx.new_bytes(value.into_vec()).into();
environ.set_item(key, value, vm).unwrap();
environ.set_item(&*key, value, vm).unwrap();
}
environ
+1 -1
View File
@@ -51,7 +51,7 @@ pub(crate) mod module {
for (key, value) in env::vars_os() {
let key: PyObjectRef = vm.ctx.new_bytes(key.into_vec()).into();
let value: PyObjectRef = vm.ctx.new_bytes(value.into_vec()).into();
environ.set_item(key, value, vm).unwrap();
environ.set_item(&*key, value, vm).unwrap();
}
environ
+2 -2
View File
@@ -725,7 +725,7 @@ mod _sre {
.and_then(|x| self.get_slice(x, str_drive, vm))
.map(|x| x.to_pyobject(vm))
.unwrap_or_else(|| default.clone());
dict.set_item(key, value, vm)?;
dict.set_item(&*key, value, vm)?;
}
Ok(dict)
})
@@ -750,7 +750,7 @@ mod _sre {
} else {
self.pattern
.groupindex
.get_item_opt(group, vm)
.get_item_opt(&*group, vm)
.ok()??
.downcast::<PyInt>()
.ok()?
+2 -2
View File
@@ -371,9 +371,9 @@ pub(crate) mod _thread {
} else {
let dict = zelf.ldict(vm);
if let Some(value) = value {
dict.set_item(attr, value, vm)?;
dict.set_item(&attr, value, vm)?;
} else {
dict.del_item(attr, vm)?;
dict.del_item(&attr, vm)?;
}
Ok(())
}
+1 -1
View File
@@ -54,7 +54,7 @@ mod _weakref {
vm: &VirtualMachine,
) -> PyResult<()> {
dict._as_dict_inner()
.delete_if(vm, &key, |wr| {
.delete_if(vm, &*key, |wr| {
let wr = wr
.payload::<PyWeak>()
.ok_or_else(|| vm.new_type_error("not a weakref".to_owned()))?;
+1 -1
View File
@@ -56,7 +56,7 @@ impl PyMethod {
};
if let Some(dict) = obj.dict() {
if let Some(attr) = dict.get_item_opt(name.clone(), vm)? {
if let Some(attr) = dict.get_item_opt(&*name, vm)? {
return Ok(Self::Attribute(attr));
}
}
+1 -1
View File
@@ -410,7 +410,7 @@ impl VirtualMachine {
None
} else {
let sys_modules = self.sys_module.get_attr("modules", self)?;
sys_modules.get_item(module.clone(), self).ok()
sys_modules.get_item(&*module, self).ok()
};
match cached_module {
+3 -3
View File
@@ -229,7 +229,7 @@ impl WASMVirtualMachine {
pub fn add_to_scope(&self, name: String, value: JsValue) -> Result<(), JsValue> {
self.with_vm(move |vm, StoredVirtualMachine { ref scope, .. }| {
let value = convert::js_to_py(vm, value);
scope.globals.set_item(name, value, vm).into_js(vm)
scope.globals.set_item(&name, value, vm).into_js(vm)
})?
}
@@ -296,7 +296,7 @@ impl WASMVirtualMachine {
let module = vm.new_module(&name, attrs, None);
let sys_modules = vm.sys_module.get_attr("modules", vm).into_js(vm)?;
sys_modules.set_item(name, module, vm).into_js(vm)?;
sys_modules.set_item(&name, module, vm).into_js(vm)?;
Ok(())
})?
@@ -315,7 +315,7 @@ impl WASMVirtualMachine {
}
let sys_modules = vm.sys_module.get_attr("modules", vm).into_js(vm)?;
sys_modules.set_item(name, py_module, vm).into_js(vm)?;
sys_modules.set_item(&name, py_module, vm).into_js(vm)?;
Ok(())
})?