forked from Rust-related/RustPython
@@ -68,7 +68,7 @@ pub fn hash_float(value: f64) -> PyHash {
|
||||
x as PyHash * value.signum() as PyHash
|
||||
}
|
||||
|
||||
pub fn hash_value<T: Hash>(data: &T) -> PyHash {
|
||||
pub fn hash_value<T: Hash + ?Sized>(data: &T) -> PyHash {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
data.hash(&mut hasher);
|
||||
hasher.finish() as PyHash
|
||||
|
||||
@@ -40,7 +40,7 @@ macro_rules! add_python_function {
|
||||
|
||||
// inserts the first function found in the module into the provided scope.
|
||||
$scope.globals.set_item(
|
||||
&def.obj_name,
|
||||
def.obj_name.as_str(),
|
||||
$vm.context().new_pyfunction(
|
||||
vm::obj::objcode::PyCode::new(*def.clone()).into_ref(&$vm),
|
||||
$scope.clone(),
|
||||
|
||||
@@ -883,9 +883,9 @@ impl PyBytesInner {
|
||||
return self
|
||||
.elements
|
||||
.iter()
|
||||
.cloned()
|
||||
.copied()
|
||||
.filter(|x| *x != b'\t')
|
||||
.collect::<Vec<u8>>();
|
||||
.collect();
|
||||
}
|
||||
|
||||
for i in &self.elements {
|
||||
|
||||
@@ -130,18 +130,16 @@ impl<T: Clone> Dict<T> {
|
||||
}
|
||||
|
||||
/// Store a key
|
||||
pub fn insert<K: DictKey + IntoPyObject + Copy>(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
key: K,
|
||||
value: T,
|
||||
) -> PyResult<()> {
|
||||
pub fn insert<K>(&self, vm: &VirtualMachine, key: K, value: T) -> PyResult<()>
|
||||
where
|
||||
K: DictKey,
|
||||
{
|
||||
// This does not need to be accurate so we can take the lock mutiple times.
|
||||
if self.borrow_value().indices.len() > 2 * self.borrow_value().size {
|
||||
self.resize();
|
||||
}
|
||||
loop {
|
||||
match self.lookup(vm, key)? {
|
||||
match self.lookup(vm, &key)? {
|
||||
LookupResult::Existing(index) => {
|
||||
let mut inner = self.borrow_value_mut();
|
||||
// Update existing key
|
||||
@@ -166,7 +164,7 @@ impl<T: Clone> Dict<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains<K: DictKey + Copy>(&self, vm: &VirtualMachine, key: K) -> PyResult<bool> {
|
||||
pub fn contains<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<bool> {
|
||||
if let LookupResult::Existing(_) = self.lookup(vm, key)? {
|
||||
Ok(true)
|
||||
} else {
|
||||
@@ -176,7 +174,7 @@ impl<T: Clone> Dict<T> {
|
||||
|
||||
/// Retrieve a key
|
||||
#[cfg_attr(feature = "flame-it", flame("Dict"))]
|
||||
pub fn get<K: DictKey + Copy>(&self, vm: &VirtualMachine, key: K) -> PyResult<Option<T>> {
|
||||
pub fn get<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
|
||||
loop {
|
||||
if let LookupResult::Existing(index) = self.lookup(vm, key)? {
|
||||
if let Some(entry) = &self.borrow_value().entries[index] {
|
||||
@@ -304,7 +302,7 @@ impl<T: Clone> Dict<T> {
|
||||
|
||||
/// Lookup the index for the given key.
|
||||
#[cfg_attr(feature = "flame-it", flame("Dict"))]
|
||||
fn lookup<K: DictKey + Copy>(&self, vm: &VirtualMachine, key: K) -> PyResult<LookupResult> {
|
||||
fn lookup<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<LookupResult> {
|
||||
let hash_value = key.do_hash(vm)?;
|
||||
let perturb = hash_value;
|
||||
let mut hash_index: HashIndex = hash_value;
|
||||
@@ -359,7 +357,7 @@ impl<T: Clone> Dict<T> {
|
||||
}
|
||||
|
||||
/// Retrieve and delete a key
|
||||
pub fn pop<K: DictKey + Copy>(&self, vm: &VirtualMachine, key: K) -> PyResult<Option<T>> {
|
||||
pub fn pop<K: DictKey>(&self, vm: &VirtualMachine, key: &K) -> PyResult<Option<T>> {
|
||||
loop {
|
||||
if let LookupResult::Existing(index) = self.lookup(vm, key)? {
|
||||
let mut inner = self.borrow_value_mut();
|
||||
@@ -413,41 +411,41 @@ enum LookupResult {
|
||||
/// the dictionary. Typical usecases are:
|
||||
/// - PyObjectRef -> arbitrary python type used as key
|
||||
/// - str -> string reference used as key, this is often used internally
|
||||
pub trait DictKey {
|
||||
fn do_hash(self, vm: &VirtualMachine) -> PyResult<HashValue>;
|
||||
fn do_is(self, other: &PyObjectRef) -> bool;
|
||||
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool>;
|
||||
pub trait DictKey: IntoPyObject {
|
||||
fn do_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue>;
|
||||
fn do_is(&self, other: &PyObjectRef) -> bool;
|
||||
fn do_eq(&self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool>;
|
||||
}
|
||||
|
||||
/// Implement trait for PyObjectRef such that we can use python objects
|
||||
/// to index dictionaries.
|
||||
impl DictKey for &PyObjectRef {
|
||||
fn do_hash(self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
impl DictKey for PyObjectRef {
|
||||
fn do_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
let raw_hash = vm._hash(self)?;
|
||||
let mut hasher = DefaultHasher::new();
|
||||
raw_hash.hash(&mut hasher);
|
||||
Ok(hasher.finish() as HashValue)
|
||||
}
|
||||
|
||||
fn do_is(self, other: &PyObjectRef) -> bool {
|
||||
fn do_is(&self, other: &PyObjectRef) -> bool {
|
||||
self.is(other)
|
||||
}
|
||||
|
||||
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
fn do_eq(&self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
vm.identical_or_equal(self, other_key)
|
||||
}
|
||||
}
|
||||
|
||||
impl DictKey for &PyStringRef {
|
||||
fn do_hash(self, _vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
impl DictKey for PyStringRef {
|
||||
fn do_hash(&self, _vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
Ok(self.hash())
|
||||
}
|
||||
|
||||
fn do_is(self, other: &PyObjectRef) -> bool {
|
||||
fn do_is(&self, other: &PyObjectRef) -> bool {
|
||||
self.is(other)
|
||||
}
|
||||
|
||||
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
fn do_eq(&self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
if self.is(other_key) {
|
||||
Ok(true)
|
||||
} else if let Some(py_str_value) = other_key.payload::<PyString>() {
|
||||
@@ -458,49 +456,37 @@ impl DictKey for &PyStringRef {
|
||||
}
|
||||
}
|
||||
|
||||
// AsRef<str> fit this case but not possible in rust 1.46
|
||||
|
||||
/// Implement trait for the str type, so that we can use strings
|
||||
/// to index dictionaries.
|
||||
impl DictKey for &str {
|
||||
fn do_hash(self, _vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
fn do_hash(&self, _vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
// follow a similar route as the hashing of PyStringRef
|
||||
let raw_hash = hash::hash_value(&self.to_owned()).to_bigint().unwrap();
|
||||
let raw_hash = hash::hash_value(*self).to_bigint().unwrap();
|
||||
let raw_hash = hash::hash_bigint(&raw_hash);
|
||||
let mut hasher = DefaultHasher::new();
|
||||
raw_hash.hash(&mut hasher);
|
||||
Ok(hasher.finish() as HashValue)
|
||||
}
|
||||
|
||||
fn do_is(self, _other: &PyObjectRef) -> bool {
|
||||
fn do_is(&self, _other: &PyObjectRef) -> bool {
|
||||
// No matter who the other pyobject is, we are never the same thing, since
|
||||
// we are a str, not a pyobject.
|
||||
false
|
||||
}
|
||||
|
||||
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
fn do_eq(&self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
if let Some(py_str_value) = other_key.payload::<PyString>() {
|
||||
Ok(py_str_value.as_str() == self)
|
||||
Ok(py_str_value.as_str() == *self)
|
||||
} else {
|
||||
// Fall back to PyString implementation.
|
||||
let s = vm.new_str(self.to_owned());
|
||||
let s = vm.ctx.new_str(*self);
|
||||
s.do_eq(vm, other_key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DictKey for &String {
|
||||
fn do_hash(self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
self.as_str().do_hash(vm)
|
||||
}
|
||||
|
||||
fn do_is(self, other: &PyObjectRef) -> bool {
|
||||
self.as_str().do_is(other)
|
||||
}
|
||||
|
||||
fn do_eq(self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
|
||||
self.as_str().do_eq(vm, other_key)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Dict, DictKey, VirtualMachine};
|
||||
@@ -513,27 +499,27 @@ mod tests {
|
||||
|
||||
let key1 = vm.new_bool(true);
|
||||
let value1 = vm.new_str("abc".to_owned());
|
||||
dict.insert(&vm, &key1, value1.clone()).unwrap();
|
||||
dict.insert(&vm, key1.clone(), value1.clone()).unwrap();
|
||||
assert_eq!(1, dict.len());
|
||||
|
||||
let key2 = vm.new_str("x".to_owned());
|
||||
let value2 = vm.new_str("def".to_owned());
|
||||
dict.insert(&vm, &key2, value2.clone()).unwrap();
|
||||
dict.insert(&vm, key2.clone(), value2.clone()).unwrap();
|
||||
assert_eq!(2, dict.len());
|
||||
|
||||
dict.insert(&vm, &key1, value2.clone()).unwrap();
|
||||
dict.insert(&vm, key1.clone(), value2.clone()).unwrap();
|
||||
assert_eq!(2, dict.len());
|
||||
|
||||
dict.delete(&vm, &key1).unwrap();
|
||||
assert_eq!(1, dict.len());
|
||||
|
||||
dict.insert(&vm, &key1, value2.clone()).unwrap();
|
||||
dict.insert(&vm, key1.clone(), 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, &"x").unwrap());
|
||||
|
||||
let val = dict.get(&vm, "x").unwrap().unwrap();
|
||||
let val = dict.get(&vm, &"x").unwrap().unwrap();
|
||||
vm.bool_eq(val, value2)
|
||||
.expect("retrieved value must be equal to inserted value.");
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ 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)
|
||||
}
|
||||
|
||||
@@ -996,12 +996,12 @@ impl ExecutingFrame<'_> {
|
||||
return Err(vm.new_type_error(msg));
|
||||
}
|
||||
}
|
||||
map_obj.set_item(&key, value, vm).unwrap();
|
||||
map_obj.set_item(key, value, vm).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (key, value) in self.pop_multiple(2 * size).into_iter().tuples() {
|
||||
map_obj.set_item(&key, value, vm).unwrap();
|
||||
map_obj.set_item(key, value, vm).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,13 @@ impl PyDictRef {
|
||||
let dicted: Result<PyDictRef, _> = dict_obj.clone().downcast();
|
||||
if let Ok(dict_obj) = dicted {
|
||||
for (key, value) in dict_obj {
|
||||
dict.insert(vm, &key, value)?;
|
||||
dict.insert(vm, key, value)?;
|
||||
}
|
||||
} else if let Some(keys) = vm.get_method(dict_obj.clone(), "keys") {
|
||||
let keys = objiter::get_iter(vm, &vm.invoke(&keys?, vec![])?)?;
|
||||
while let Some(key) = objiter::get_next_object(vm, &keys)? {
|
||||
let val = dict_obj.get_item(&key, vm)?;
|
||||
dict.insert(vm, &key, val)?;
|
||||
dict.insert(vm, key, val)?;
|
||||
}
|
||||
} else {
|
||||
let iter = objiter::get_iter(vm, &dict_obj)?;
|
||||
@@ -94,13 +94,13 @@ impl PyDictRef {
|
||||
if objiter::get_next_object(vm, &elem_iter)?.is_some() {
|
||||
return Err(err(vm));
|
||||
}
|
||||
dict.insert(vm, &key, value)?;
|
||||
dict.insert(vm, key, value)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in kwargs.into_iter() {
|
||||
dict.insert(vm, &vm.new_str(key), value)?;
|
||||
dict.insert(vm, vm.new_str(key), value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -111,7 +111,7 @@ impl PyDictRef {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
for (key, value) in dict_other {
|
||||
dict.insert(vm, &key, value)?;
|
||||
dict.insert(vm, key, value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -127,7 +127,7 @@ impl PyDictRef {
|
||||
let value = value.unwrap_or_else(|| vm.ctx.none());
|
||||
for elem in iterable.iter(vm)? {
|
||||
let elem = elem?;
|
||||
dict.insert(vm, &elem, value.clone())?;
|
||||
dict.insert(vm, elem, value.clone())?;
|
||||
}
|
||||
PyDict { entries: dict }.into_ref_with_type(vm, class)
|
||||
}
|
||||
@@ -246,12 +246,12 @@ impl PyDictRef {
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner_setitem_fast(&key, value, vm)
|
||||
self.inner_setitem_fast(key, value, vm)
|
||||
}
|
||||
|
||||
/// Set item variant which can be called with multiple
|
||||
/// key types, such as str to name a notable one.
|
||||
fn inner_setitem_fast<K: DictKey + IntoPyObject + Copy>(
|
||||
fn inner_setitem_fast<K: DictKey>(
|
||||
&self,
|
||||
key: K,
|
||||
value: PyObjectRef,
|
||||
@@ -263,20 +263,20 @@ impl PyDictRef {
|
||||
#[pymethod(magic)]
|
||||
#[cfg_attr(feature = "flame-it", flame("PyDictRef"))]
|
||||
fn getitem(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(value) = self.inner_getitem_option(&key, vm)? {
|
||||
if let Some(value) = self.inner_getitem_option(key.clone(), vm)? {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(vm.new_key_error(key.clone()))
|
||||
Err(vm.new_key_error(key))
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an optional inner item, or an error (can be key error as well)
|
||||
fn inner_getitem_option<K: DictKey + IntoPyObject + Copy>(
|
||||
fn inner_getitem_option<K: DictKey>(
|
||||
&self,
|
||||
key: K,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Option<PyObjectRef>> {
|
||||
if let Some(value) = self.entries.get(vm, key)? {
|
||||
if let Some(value) = self.entries.get(vm, &key)? {
|
||||
return Ok(Some(value));
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ impl PyDictRef {
|
||||
Some(value) => Ok(value),
|
||||
None => {
|
||||
let set_value = default.unwrap_or_else(|| vm.ctx.none());
|
||||
self.entries.insert(vm, &key, set_value.clone())?;
|
||||
self.entries.insert(vm, key, set_value.clone())?;
|
||||
Ok(set_value)
|
||||
}
|
||||
}
|
||||
@@ -378,7 +378,7 @@ impl PyDictRef {
|
||||
Some(value) => Ok(value),
|
||||
None => match default {
|
||||
OptionalArg::Present(default) => Ok(default),
|
||||
OptionalArg::Missing => Err(vm.new_key_error(key.clone())),
|
||||
OptionalArg::Missing => Err(vm.new_key_error(key)),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -407,7 +407,7 @@ impl PyDictRef {
|
||||
let dict = DictContentType::default();
|
||||
|
||||
for (key, value) in attrs {
|
||||
dict.insert(vm, &vm.ctx.new_str(key), value)?;
|
||||
dict.insert(vm, vm.ctx.new_str(key), value)?;
|
||||
}
|
||||
|
||||
Ok(PyDict { entries: dict }.into_ref(vm))
|
||||
@@ -432,7 +432,7 @@ impl PyDictRef {
|
||||
/// python value, or None.
|
||||
/// Note that we can pass any type which implements the DictKey
|
||||
/// trait. Notable examples are String and PyObjectRef.
|
||||
pub fn get_item_option<T: IntoPyObject + DictKey + Copy>(
|
||||
pub fn get_item_option<T: IntoPyObject + DictKey>(
|
||||
&self,
|
||||
key: T,
|
||||
vm: &VirtualMachine,
|
||||
@@ -471,17 +471,15 @@ impl PyDictRef {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemProtocol for PyDictRef {
|
||||
fn get_item<T: IntoPyObject + DictKey + Copy>(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
impl<T> ItemProtocol<T> for PyDictRef
|
||||
where
|
||||
T: DictKey,
|
||||
{
|
||||
fn get_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
self.as_object().get_item(key, vm)
|
||||
}
|
||||
|
||||
fn set_item<T: IntoPyObject + DictKey + Copy>(
|
||||
&self,
|
||||
key: T,
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
fn set_item(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
if self.lease_class().is(&vm.ctx.dict_type()) {
|
||||
self.inner_setitem_fast(key, value, vm)
|
||||
.map(|_| vm.ctx.none())
|
||||
@@ -491,7 +489,7 @@ impl ItemProtocol for PyDictRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn del_item<T: IntoPyObject + DictKey + Copy>(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
fn del_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
self.as_object().del_item(key, vm)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ impl PyFunction {
|
||||
for i in 0..n {
|
||||
let arg_name = &code_object.arg_names[i];
|
||||
let arg = &func_args.args[i];
|
||||
locals.set_item(arg_name, arg.clone(), vm)?;
|
||||
locals.set_item(arg_name.as_str(), arg.clone(), vm)?;
|
||||
}
|
||||
|
||||
// Pack other positional arguments in to *args:
|
||||
@@ -103,7 +103,7 @@ impl PyFunction {
|
||||
}
|
||||
let vararg_value = vm.ctx.new_tuple(last_args);
|
||||
|
||||
locals.set_item(vararg_name, vararg_value, vm)?;
|
||||
locals.set_item(vararg_name.as_str(), vararg_value, vm)?;
|
||||
} else {
|
||||
// Check the number of positional arguments
|
||||
if nargs > nexpected_args {
|
||||
@@ -121,7 +121,7 @@ impl PyFunction {
|
||||
{
|
||||
let d = vm.ctx.new_dict();
|
||||
if let Some(ref kwargs_name) = code_object.varkeywords_name {
|
||||
locals.set_item(kwargs_name, d.as_object().clone(), vm)?;
|
||||
locals.set_item(kwargs_name.as_str(), d.as_object().clone(), vm)?;
|
||||
}
|
||||
Some(d)
|
||||
} else {
|
||||
@@ -143,9 +143,9 @@ impl PyFunction {
|
||||
);
|
||||
}
|
||||
|
||||
locals.set_item(&name, value, vm)?;
|
||||
locals.set_item(name.as_str(), value, vm)?;
|
||||
} else if let Some(d) = &kwargs {
|
||||
d.set_item(&name, value, vm)?;
|
||||
d.set_item(name.as_str(), value, vm)?;
|
||||
} else {
|
||||
return Err(
|
||||
vm.new_type_error(format!("Got an unexpected keyword argument '{}'", name))
|
||||
@@ -189,7 +189,7 @@ impl PyFunction {
|
||||
for (default_index, i) in (required_args..nexpected_args).enumerate() {
|
||||
let arg_name = &code_object.arg_names[i];
|
||||
if !locals.contains_key(arg_name, vm) {
|
||||
locals.set_item(arg_name, defaults[default_index].clone(), vm)?;
|
||||
locals.set_item(arg_name.as_str(), defaults[default_index].clone(), vm)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,8 +199,10 @@ impl PyFunction {
|
||||
for arg_name in &code_object.kwonlyarg_names {
|
||||
if !locals.contains_key(arg_name, vm) {
|
||||
if let Some(kw_only_defaults) = &self.kw_only_defaults {
|
||||
if let Some(default) = kw_only_defaults.get_item_option(arg_name, vm)? {
|
||||
locals.set_item(arg_name, default, vm)?;
|
||||
if let Some(default) =
|
||||
kw_only_defaults.get_item_option(arg_name.as_str(), vm)?
|
||||
{
|
||||
locals.set_item(arg_name.as_str(), default, vm)?;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ impl PySetInner {
|
||||
fn new(iterable: PyIterable, vm: &VirtualMachine) -> PyResult<PySetInner> {
|
||||
let set = PySetInner::default();
|
||||
for item in iterable.iter(vm)? {
|
||||
set.add(&item?, vm)?;
|
||||
set.add(item?, vm)?;
|
||||
}
|
||||
Ok(set)
|
||||
}
|
||||
@@ -177,7 +177,7 @@ impl PySetInner {
|
||||
fn union(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult<PySetInner> {
|
||||
let set = self.clone();
|
||||
for item in other.iter(vm)? {
|
||||
set.add(&item?, vm)?;
|
||||
set.add(item?, vm)?;
|
||||
}
|
||||
|
||||
Ok(set)
|
||||
@@ -188,7 +188,7 @@ impl PySetInner {
|
||||
for item in other.iter(vm)? {
|
||||
let obj = item?;
|
||||
if self.contains(&obj, vm)? {
|
||||
set.add(&obj, vm)?;
|
||||
set.add(obj, vm)?;
|
||||
}
|
||||
}
|
||||
Ok(set)
|
||||
@@ -256,16 +256,16 @@ impl PySetInner {
|
||||
Ok(format!("{{{}}}", str_parts.join(", ")))
|
||||
}
|
||||
|
||||
fn add(&self, item: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn add(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.content.insert(vm, item, ())
|
||||
}
|
||||
|
||||
fn remove(&self, item: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.content.delete(vm, item)
|
||||
fn remove(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.content.delete(vm, &item)
|
||||
}
|
||||
|
||||
fn discard(&self, item: &PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
self.content.delete_if_exists(vm, item)
|
||||
self.content.delete_if_exists(vm, &item)
|
||||
}
|
||||
|
||||
fn clear(&self) {
|
||||
@@ -284,7 +284,7 @@ impl PySetInner {
|
||||
fn update(&self, others: Args<PyIterable>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
for iterable in others {
|
||||
for item in iterable.iter(vm)? {
|
||||
self.add(&item?, vm)?;
|
||||
self.add(item?, vm)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -297,7 +297,7 @@ impl PySetInner {
|
||||
for item in iterable.iter(vm)? {
|
||||
let obj = item?;
|
||||
if temp_inner.contains(&obj, vm)? {
|
||||
self.add(&obj, vm)?;
|
||||
self.add(obj, vm)?;
|
||||
}
|
||||
}
|
||||
temp_inner = self.copy()
|
||||
@@ -518,13 +518,13 @@ impl PySet {
|
||||
|
||||
#[pymethod]
|
||||
pub fn add(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner.add(&item, vm)?;
|
||||
self.inner.add(item, vm)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn remove(&self, item: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.inner.remove(&item, vm)
|
||||
self.inner.remove(item, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -620,7 +620,7 @@ impl PyFrozenSet {
|
||||
) -> PyResult<Self> {
|
||||
let inner = PySetInner::default();
|
||||
for elem in it {
|
||||
inner.add(&elem, vm)?;
|
||||
inner.add(elem, vm)?;
|
||||
}
|
||||
Ok(Self { inner })
|
||||
}
|
||||
|
||||
@@ -993,11 +993,11 @@ impl PyString {
|
||||
Ok(from_str) => {
|
||||
if to_str.len() == from_str.len() {
|
||||
for (c1, c2) in from_str.value.chars().zip(to_str.value.chars()) {
|
||||
new_dict.set_item(&vm.new_int(c1 as u32), vm.new_int(c2 as u32), vm)?;
|
||||
new_dict.set_item(vm.new_int(c1 as u32), vm.new_int(c2 as u32), vm)?;
|
||||
}
|
||||
if let OptionalArg::Present(none_str) = none_str {
|
||||
for c in none_str.value.chars() {
|
||||
new_dict.set_item(&vm.new_int(c as u32), vm.get_none(), vm)?;
|
||||
new_dict.set_item(vm.new_int(c as u32), vm.get_none(), vm)?;
|
||||
}
|
||||
}
|
||||
new_dict.into_pyobject(vm)
|
||||
@@ -1019,14 +1019,14 @@ impl PyString {
|
||||
for (key, val) in dict {
|
||||
if let Some(num) = key.payload::<PyInt>() {
|
||||
new_dict.set_item(
|
||||
&num.as_bigint().to_i32().into_pyobject(vm)?,
|
||||
num.as_bigint().to_i32().into_pyobject(vm)?,
|
||||
val,
|
||||
vm,
|
||||
)?;
|
||||
} else if let Some(string) = key.payload::<PyString>() {
|
||||
if string.len() == 1 {
|
||||
let num_value = string.value.chars().next().unwrap() as u32;
|
||||
new_dict.set_item(&num_value.into_pyobject(vm)?, val, vm)?;
|
||||
new_dict.set_item(num_value.into_pyobject(vm)?, val, vm)?;
|
||||
} else {
|
||||
return Err(vm.new_value_error(
|
||||
"string keys in translate table must be of length 1".to_owned(),
|
||||
|
||||
@@ -114,7 +114,11 @@ impl PySuper {
|
||||
} else {
|
||||
let frame = vm.current_frame().expect("no current frame for super()");
|
||||
if let Some(first_arg) = frame.code.arg_names.get(0) {
|
||||
match frame.scope.get_locals().get_item_option(first_arg, vm)? {
|
||||
match frame
|
||||
.scope
|
||||
.get_locals()
|
||||
.get_item_option(first_arg.as_str(), vm)?
|
||||
{
|
||||
Some(obj) => obj,
|
||||
_ => {
|
||||
return Err(vm.new_type_error(format!(
|
||||
|
||||
@@ -209,7 +209,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_object())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ use num_complex::Complex64;
|
||||
use num_traits::{One, ToPrimitive, Zero};
|
||||
|
||||
use crate::bytecode;
|
||||
use crate::dictdatatype::DictKey;
|
||||
use crate::exceptions::{self, PyBaseExceptionRef};
|
||||
use crate::function::{IntoPyNativeFunc, PyFuncArgs};
|
||||
use crate::obj::objbuiltinfunc::{PyBuiltinFunction, PyBuiltinMethod};
|
||||
@@ -952,32 +951,28 @@ impl<T: TypeProtocol> TypeProtocol for &'_ T {
|
||||
|
||||
/// The python item protocol. Mostly applies to dictionaries.
|
||||
/// Allows getting, setting and deletion of keys-value pairs.
|
||||
pub trait ItemProtocol {
|
||||
fn get_item<T: IntoPyObject + DictKey + Copy>(&self, key: T, vm: &VirtualMachine) -> PyResult;
|
||||
fn set_item<T: IntoPyObject + DictKey + Copy>(
|
||||
&self,
|
||||
key: T,
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult;
|
||||
fn del_item<T: IntoPyObject + DictKey + Copy>(&self, key: T, vm: &VirtualMachine) -> PyResult;
|
||||
pub trait ItemProtocol<T>
|
||||
where
|
||||
T: IntoPyObject + ?Sized,
|
||||
{
|
||||
fn get_item(&self, key: T, vm: &VirtualMachine) -> PyResult;
|
||||
fn set_item(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) -> PyResult;
|
||||
fn del_item(&self, key: T, vm: &VirtualMachine) -> PyResult;
|
||||
}
|
||||
|
||||
impl ItemProtocol for PyObjectRef {
|
||||
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
impl<T> ItemProtocol<T> for PyObjectRef
|
||||
where
|
||||
T: IntoPyObject,
|
||||
{
|
||||
fn get_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
vm.call_method(self, "__getitem__", key.into_pyobject(vm)?)
|
||||
}
|
||||
|
||||
fn set_item<T: IntoPyObject>(
|
||||
&self,
|
||||
key: T,
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
fn set_item(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
vm.call_method(self, "__setitem__", vec![key.into_pyobject(vm)?, value])
|
||||
}
|
||||
|
||||
fn del_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
fn del_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
|
||||
vm.call_method(self, "__delitem__", key.into_pyobject(vm)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ fn dis_compiler_flag_names(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let dict = vm.ctx.new_dict();
|
||||
for (name, flag) in CodeFlags::NAME_MAPPING {
|
||||
dict.set_item(
|
||||
&vm.ctx.new_int(flag.bits()),
|
||||
vm.ctx.new_int(flag.bits()),
|
||||
vm.ctx.new_str((*name).to_owned()),
|
||||
vm,
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
for (name, code) in ERROR_CODES {
|
||||
let name = vm.new_str((*name).to_owned());
|
||||
let code = vm.ctx.new_int(*code);
|
||||
errorcode.set_item(&code, name.clone(), vm).unwrap();
|
||||
errorcode.set_item(code.clone(), name.clone(), vm).unwrap();
|
||||
vm.set_attr(&module, name, code).unwrap();
|
||||
}
|
||||
module
|
||||
|
||||
@@ -1131,7 +1131,7 @@ mod posix {
|
||||
for (key, value) in env::vars_os() {
|
||||
environ
|
||||
.set_item(
|
||||
&vm.ctx.new_bytes(key.into_vec()),
|
||||
vm.ctx.new_bytes(key.into_vec()),
|
||||
vm.ctx.new_bytes(value.into_vec()),
|
||||
vm,
|
||||
)
|
||||
@@ -2254,7 +2254,7 @@ mod nt {
|
||||
|
||||
for (key, value) in env::vars() {
|
||||
environ
|
||||
.set_item(&vm.new_str(key), vm.new_str(value), vm)
|
||||
.set_item(vm.new_str(key), vm.new_str(value), vm)
|
||||
.unwrap();
|
||||
}
|
||||
environ
|
||||
|
||||
@@ -330,7 +330,7 @@ impl PyLocal {
|
||||
zelf.as_object()
|
||||
)))
|
||||
} else {
|
||||
zelf.ldict(vm).set_item(attr.as_object(), value, vm)?;
|
||||
zelf.ldict(vm).set_item(attr.into_object(), value, vm)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -343,7 +343,7 @@ impl PyLocal {
|
||||
zelf.as_object()
|
||||
)))
|
||||
} else {
|
||||
zelf.ldict(vm).del_item(attr.as_object(), vm)?;
|
||||
zelf.ldict(vm).del_item(attr.into_object(), vm)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,8 +213,12 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
|
||||
for pair in object_entries(&Object::from(js_val)) {
|
||||
let (key, val) = pair.expect("iteration over object to not fail");
|
||||
let py_val = js_to_py(vm, val);
|
||||
dict.set_item(&String::from(js_sys::JsString::from(key)), py_val, vm)
|
||||
.unwrap();
|
||||
dict.set_item(
|
||||
String::from(js_sys::JsString::from(key)).as_str(),
|
||||
py_val,
|
||||
vm,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
dict.into_object()
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ impl WASMVirtualMachine {
|
||||
let (key, value) = entry?;
|
||||
let key: String = Object::from(key).to_string().into();
|
||||
attrs
|
||||
.set_item(&key, convert::js_to_py(vm, value), vm)
|
||||
.set_item(key.as_str(), convert::js_to_py(vm, value), vm)
|
||||
.to_js(vm)?;
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ impl WASMVirtualMachine {
|
||||
let sys_modules = vm
|
||||
.get_attribute(vm.sys_module.clone(), "modules")
|
||||
.to_js(vm)?;
|
||||
sys_modules.set_item(&name, module, vm).to_js(vm)?;
|
||||
sys_modules.set_item(name, module, vm).to_js(vm)?;
|
||||
|
||||
Ok(())
|
||||
})?
|
||||
@@ -301,7 +301,7 @@ impl WASMVirtualMachine {
|
||||
let sys_modules = vm
|
||||
.get_attribute(vm.sys_module.clone(), "modules")
|
||||
.to_js(vm)?;
|
||||
sys_modules.set_item(&name, py_module, vm).to_js(vm)?;
|
||||
sys_modules.set_item(name, py_module, vm).to_js(vm)?;
|
||||
|
||||
Ok(())
|
||||
})?
|
||||
|
||||
Reference in New Issue
Block a user