mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Eliminate ctx.set_attr.
This commit is contained in:
@@ -669,7 +669,12 @@ fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
// builtin_vars
|
||||
|
||||
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
let py_mod = py_module!(ctx, "__builtins__", {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let open = ctx.none();
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let open = ctx.new_rustfunc(io_open);
|
||||
|
||||
py_module!(ctx, "__builtins__", {
|
||||
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146
|
||||
"__name__" => ctx.new_str(String::from("__main__")),
|
||||
|
||||
@@ -715,6 +720,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
"min" => ctx.new_rustfunc(builtin_min),
|
||||
"object" => ctx.object(),
|
||||
"oct" => ctx.new_rustfunc(builtin_oct),
|
||||
"open" => open,
|
||||
"ord" => ctx.new_rustfunc(builtin_ord),
|
||||
"next" => ctx.new_rustfunc(builtin_next),
|
||||
"pow" => ctx.new_rustfunc(builtin_pow),
|
||||
@@ -759,12 +765,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
"ZeroDivisionError" => ctx.exceptions.zero_division_error.clone(),
|
||||
"KeyError" => ctx.exceptions.key_error.clone(),
|
||||
"OSError" => ctx.exceptions.os_error.clone(),
|
||||
});
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
ctx.set_attr(&py_mod, "open", ctx.new_rustfunc(io_open));
|
||||
|
||||
py_mod
|
||||
})
|
||||
}
|
||||
|
||||
pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
@@ -801,6 +802,6 @@ pub fn builtin_build_class_(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResu
|
||||
"__call__",
|
||||
vec![name_arg, bases, namespace.into_object()],
|
||||
)?;
|
||||
cells.set_item(&vm.ctx, "__class__", class.clone());
|
||||
cells.set_item("__class__", class.clone(), vm);
|
||||
Ok(class)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ fn exception_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
vm.new_str("No msg".to_string())
|
||||
};
|
||||
let traceback = vm.ctx.new_list(Vec::new());
|
||||
vm.ctx.set_attr(&zelf, "msg", msg);
|
||||
vm.ctx.set_attr(&zelf, "__traceback__", traceback);
|
||||
vm.set_attr(&zelf, "msg", msg)?;
|
||||
vm.set_attr(&zelf, "__traceback__", traceback)?;
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
|
||||
@@ -132,21 +132,21 @@ pub trait NameProtocol {
|
||||
impl NameProtocol for Scope {
|
||||
fn load_name(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
|
||||
for dict in self.locals.iter() {
|
||||
if let Some(value) = dict.get_item(name) {
|
||||
if let Some(value) = dict.get_item(name, vm) {
|
||||
return Some(value);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(value) = self.globals.get_item(name) {
|
||||
if let Some(value) = self.globals.get_item(name, vm) {
|
||||
return Some(value);
|
||||
}
|
||||
|
||||
vm.get_attribute(vm.builtins.clone(), name).ok()
|
||||
}
|
||||
|
||||
fn load_cell(&self, _vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
|
||||
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
|
||||
for dict in self.locals.iter().skip(1) {
|
||||
if let Some(value) = dict.get_item(name) {
|
||||
if let Some(value) = dict.get_item(name, vm) {
|
||||
return Some(value);
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ impl NameProtocol for Scope {
|
||||
}
|
||||
|
||||
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
|
||||
self.get_locals().set_item(&vm.ctx, key, value)
|
||||
self.get_locals().set_item(key, value, vm)
|
||||
}
|
||||
|
||||
fn delete_name(&self, _vm: &VirtualMachine, key: &str) {
|
||||
@@ -392,11 +392,11 @@ impl Frame {
|
||||
// Take all key-value pairs from the dict:
|
||||
let dict_elements = objdict::get_key_value_pairs(&obj);
|
||||
for (key, value) in dict_elements.iter() {
|
||||
map_obj.set_item(&vm.ctx, &objstr::get_value(key), value.clone());
|
||||
map_obj.set_item(key.clone(), value.clone(), vm);
|
||||
}
|
||||
} else {
|
||||
let key = self.pop_value();
|
||||
map_obj.set_item(&vm.ctx, &objstr::get_value(&key), obj)
|
||||
map_obj.set_item(key, obj, vm)
|
||||
}
|
||||
}
|
||||
self.push_value(map_obj.into_object());
|
||||
@@ -585,7 +585,7 @@ impl Frame {
|
||||
let scope = self.scope.clone();
|
||||
let obj = vm.ctx.new_function(code_obj, scope, defaults);
|
||||
|
||||
vm.ctx.set_attr(&obj, "__annotations__", annotations);
|
||||
vm.set_attr(&obj, "__annotations__", annotations)?;
|
||||
|
||||
self.push_value(obj);
|
||||
Ok(None)
|
||||
|
||||
@@ -39,7 +39,7 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
|
||||
// trace!("Code object: {:?}", code_obj);
|
||||
|
||||
let attrs = vm.ctx.new_dict();
|
||||
attrs.set_item(&vm.ctx, "__name__", vm.new_str(module.to_string()));
|
||||
attrs.set_item("__name__", vm.new_str(module.to_string()), vm);
|
||||
vm.run_code_obj(code_obj, Scope::new(None, attrs.clone()))?;
|
||||
Ok(vm.ctx.new_module(module, attrs))
|
||||
}
|
||||
|
||||
@@ -114,15 +114,15 @@ macro_rules! no_kwargs {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! py_module {
|
||||
( $ctx:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)* }) => {
|
||||
{
|
||||
let py_mod = $ctx.new_module($module_name, $ctx.new_dict());
|
||||
$(
|
||||
$ctx.set_attr(&py_mod, $name, $value);
|
||||
)*
|
||||
py_mod
|
||||
}
|
||||
}
|
||||
( $ctx:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)* }) => {{
|
||||
let mut attributes = $crate::pyobject::PyAttributes::new();
|
||||
$(
|
||||
let value: PyObjectRef = $value.into();
|
||||
attributes.insert($name.to_string(), value);
|
||||
)*
|
||||
let module_dict = $crate::obj::objdict::PyDictRef::from_attributes($ctx, attributes);
|
||||
$ctx.new_module($module_name, module_dict)
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@@ -131,7 +131,7 @@ macro_rules! py_class {
|
||||
{
|
||||
let py_class = $ctx.new_class($class_name, $class_base);
|
||||
$(
|
||||
$ctx.set_attr(&py_class, $name, $value);
|
||||
py_class.set_str_attr($name, $value);
|
||||
)*
|
||||
py_class
|
||||
}
|
||||
@@ -143,7 +143,7 @@ macro_rules! extend_class {
|
||||
( $ctx:expr, $class:expr, { $($name:expr => $value:expr),* $(,)* }) => {
|
||||
let class = $class;
|
||||
$(
|
||||
$ctx.set_attr(class, $name, $value);
|
||||
class.set_str_attr($name, $value);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +43,6 @@ impl PyValue for PyBytes {
|
||||
|
||||
// Fill bytes class methods:
|
||||
pub fn init(context: &PyContext) {
|
||||
let bytes_type = context.bytes_type.as_object();
|
||||
|
||||
let bytes_doc =
|
||||
"bytes(iterable_of_ints) -> bytes\n\
|
||||
bytes(string, encoding[, errors]) -> bytes\n\
|
||||
@@ -56,7 +54,7 @@ pub fn init(context: &PyContext) {
|
||||
- any object implementing the buffer API.\n \
|
||||
- an integer";
|
||||
|
||||
extend_class!(context, bytes_type, {
|
||||
extend_class!(context, &context.bytes_type, {
|
||||
"__new__" => context.new_rustfunc(bytes_new),
|
||||
"__eq__" => context.new_rustfunc(PyBytesRef::eq),
|
||||
"__lt__" => context.new_rustfunc(PyBytesRef::lt),
|
||||
|
||||
@@ -80,8 +80,7 @@ impl PyCodeRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let code_type = context.code_type.as_object();
|
||||
extend_class!(context, code_type, {
|
||||
extend_class!(context, &context.code_type, {
|
||||
"__new__" => context.new_rustfunc(PyCodeRef::new),
|
||||
"__repr__" => context.new_rustfunc(PyCodeRef::repr),
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::fmt;
|
||||
|
||||
use crate::function::{KwArgs, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
DictProtocol, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
DictProtocol, IntoPyObject, PyAttributes, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
@@ -58,7 +58,7 @@ impl PyDictRef {
|
||||
if let OptionalArg::Present(dict_obj) = dict_obj {
|
||||
if objtype::isinstance(&dict_obj, &vm.ctx.dict_type()) {
|
||||
for (needle, value) in get_key_value_pairs(&dict_obj) {
|
||||
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
|
||||
dict.set_item(needle, value, vm);
|
||||
}
|
||||
} else {
|
||||
let iter = objiter::get_iter(vm, &dict_obj)?;
|
||||
@@ -77,13 +77,12 @@ impl PyDictRef {
|
||||
if objiter::get_next_object(vm, &elem_iter)?.is_some() {
|
||||
return Err(err(vm));
|
||||
}
|
||||
dict.set_item(&vm.ctx, &objstr::get_value(&needle), value);
|
||||
dict.set_item(needle, value, vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (needle, value) in kwargs.into_iter() {
|
||||
let py_needle = vm.new_str(needle);
|
||||
dict.set_item(&vm.ctx, &objstr::get_value(&py_needle), value);
|
||||
dict.set_item(vm.new_str(needle), value, vm);
|
||||
}
|
||||
Ok(dict)
|
||||
}
|
||||
@@ -181,7 +180,7 @@ impl PyDictRef {
|
||||
}
|
||||
|
||||
fn setitem(self, needle: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) {
|
||||
self.set_item(&vm.ctx, &objstr::get_value(&needle), value)
|
||||
self.set_item(needle, value, vm)
|
||||
}
|
||||
|
||||
fn getitem(self, key: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -216,6 +215,23 @@ impl PyDictRef {
|
||||
}
|
||||
}
|
||||
|
||||
// Used during module initialisation when vm isn't available.
|
||||
pub fn from_attributes(ctx: &PyContext, attributes: PyAttributes) -> PyDictRef {
|
||||
let dict = ctx.new_dict();
|
||||
for (key_str, value) in attributes.into_iter() {
|
||||
dict.unsafe_str_insert(&key_str, value, ctx);
|
||||
}
|
||||
dict
|
||||
}
|
||||
|
||||
// Pub needed for some nasty edge cases.
|
||||
// It will be unsafe if there are entries in the dictionary that compare equal.
|
||||
pub fn unsafe_str_insert(&self, key: &str, value: PyObjectRef, ctx: &PyContext) {
|
||||
self.entries
|
||||
.borrow_mut()
|
||||
.insert(key.to_string(), (ctx.new_str(key.to_string()), value));
|
||||
}
|
||||
|
||||
/// Take a python dictionary and convert it to attributes.
|
||||
pub fn to_attributes(self) -> PyAttributes {
|
||||
let mut attrs = PyAttributes::new();
|
||||
@@ -228,12 +244,14 @@ impl PyDictRef {
|
||||
}
|
||||
|
||||
impl DictProtocol for PyDictRef {
|
||||
fn contains_key(&self, k: &str) -> bool {
|
||||
self.entries.borrow().get(k).is_some()
|
||||
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
|
||||
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
|
||||
self.entries.borrow().get(key_str).is_some()
|
||||
}
|
||||
|
||||
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
|
||||
match self.entries.borrow().get(k) {
|
||||
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef> {
|
||||
let key_str = &objstr::get_value(&key.into_pyobject(vm).unwrap());
|
||||
match self.entries.borrow().get(key_str) {
|
||||
Some(v) => Some(v.1.clone()),
|
||||
None => None,
|
||||
}
|
||||
@@ -244,10 +262,11 @@ impl DictProtocol for PyDictRef {
|
||||
}
|
||||
|
||||
// Item set/get:
|
||||
fn set_item(&self, ctx: &PyContext, key_str: &str, v: PyObjectRef) {
|
||||
let key = ctx.new_str(key_str.to_string());
|
||||
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) {
|
||||
let key = key.into_pyobject(vm).unwrap();
|
||||
let key_str = &objstr::get_value(&key);
|
||||
let elements = &mut self.entries.borrow_mut();
|
||||
elements.insert(key_str.to_string(), (key.clone(), v.clone()));
|
||||
elements.insert(key_str.to_string(), (key.clone(), value));
|
||||
}
|
||||
|
||||
fn del_item(&self, key: &str) {
|
||||
|
||||
@@ -3,8 +3,7 @@ use crate::pyobject::{PyContext, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ellipsis_type = context.ellipsis_type.as_object();
|
||||
extend_class!(context, ellipsis_type, {
|
||||
extend_class!(context, &context.ellipsis_type, {
|
||||
"__new__" => context.new_rustfunc(ellipsis_new),
|
||||
"__repr__" => context.new_rustfunc(ellipsis_repr)
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ pub fn new_memory_view(
|
||||
bytes_object: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyMemoryViewRef> {
|
||||
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
|
||||
vm.set_attr(cls.as_object(), "obj", bytes_object.clone())?;
|
||||
PyMemoryView { obj: bytes_object }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ fn object_setattr(
|
||||
}
|
||||
|
||||
if let Some(ref dict) = obj.clone().dict {
|
||||
dict.set_item(&vm.ctx, &attr_name.value, value);
|
||||
dict.set_item(attr_name, value, vm);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(vm.new_attribute_error(format!(
|
||||
@@ -208,7 +208,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(obj_attr) = object_getattr(&obj, &name) {
|
||||
if let Some(obj_attr) = object_getattr(&obj, &name, &vm) {
|
||||
Ok(obj_attr)
|
||||
} else if let Some(attr) = objtype::class_get_attr(&cls, &name) {
|
||||
vm.call_get_descriptor(attr, obj)
|
||||
@@ -219,9 +219,9 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach
|
||||
}
|
||||
}
|
||||
|
||||
fn object_getattr(obj: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
|
||||
fn object_getattr(obj: &PyObjectRef, attr_name: &str, vm: &VirtualMachine) -> Option<PyObjectRef> {
|
||||
if let Some(ref dict) = obj.dict {
|
||||
dict.get_item(attr_name)
|
||||
dict.get_item(attr_name, vm)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -762,6 +762,12 @@ impl IntoPyObject for &str {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for &String {
|
||||
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
|
||||
Ok(vm.ctx.new_str(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
PyStringRef::extend_class(ctx, &ctx.str_type);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ fn super_new(
|
||||
} else {
|
||||
let frame = vm.current_frame().expect("no current frame for super()");
|
||||
if let Some(first_arg) = frame.code.arg_names.get(0) {
|
||||
match vm.get_locals().get_item(first_arg) {
|
||||
match vm.get_locals().get_item(first_arg, vm) {
|
||||
Some(obj) => obj.clone(),
|
||||
_ => {
|
||||
return Err(vm
|
||||
|
||||
@@ -162,6 +162,13 @@ impl PyClassRef {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// This is used for class initialisation where the vm is not yet available.
|
||||
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
|
||||
self.attributes
|
||||
.borrow_mut()
|
||||
.insert(attr_name.to_string(), value.into());
|
||||
}
|
||||
|
||||
fn subclasses(self, _vm: &VirtualMachine) -> PyList {
|
||||
let mut subclasses = self.subclasses.borrow_mut();
|
||||
subclasses.retain(|x| x.upgrade().is_some());
|
||||
|
||||
@@ -684,24 +684,6 @@ impl PyContext {
|
||||
.into_ref()
|
||||
}
|
||||
|
||||
pub fn set_attr<'a, T: Into<&'a PyObjectRef>, V: Into<PyObjectRef>>(
|
||||
&'a self,
|
||||
obj: T,
|
||||
attr_name: &str,
|
||||
value: V,
|
||||
) {
|
||||
let obj = obj.into();
|
||||
if let Some(PyClass { ref attributes, .. }) = obj.payload::<PyClass>() {
|
||||
attributes
|
||||
.borrow_mut()
|
||||
.insert(attr_name.to_string(), value.into());
|
||||
} else if let Some(ref dict) = obj.dict {
|
||||
dict.set_item(self, attr_name, value.into());
|
||||
} else {
|
||||
unimplemented!("set_attr unimplemented for: {:?}", obj);
|
||||
};
|
||||
}
|
||||
|
||||
pub fn unwrap_constant(&self, value: &bytecode::Constant) -> PyObjectRef {
|
||||
match *value {
|
||||
bytecode::Constant::Integer { ref value } => self.new_int(value.clone()),
|
||||
@@ -931,16 +913,14 @@ impl<T> TypeProtocol for PyRef<T> {
|
||||
}
|
||||
|
||||
pub trait DictProtocol {
|
||||
fn contains_key(&self, k: &str) -> bool;
|
||||
fn get_item(&self, k: &str) -> Option<PyObjectRef>;
|
||||
fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool;
|
||||
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> Option<PyObjectRef>;
|
||||
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)>;
|
||||
fn set_item(&self, ctx: &PyContext, key: &str, v: PyObjectRef);
|
||||
fn set_item<T: IntoPyObject>(&self, key: T, value: PyObjectRef, vm: &VirtualMachine);
|
||||
fn del_item(&self, key: &str);
|
||||
}
|
||||
|
||||
pub trait ItemProtocol {
|
||||
// // Move: doesn't really belong in this protocol.
|
||||
// fn get_key_value_pairs(&self, vm: &VirtualMachine) -> PyResult<PyListIterator>;
|
||||
fn get_item<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> PyResult<PyObjectRef>;
|
||||
fn set_item<T: IntoPyObject>(
|
||||
&self,
|
||||
@@ -1280,7 +1260,7 @@ pub trait PyClassImpl: PyClassDef {
|
||||
fn extend_class(ctx: &PyContext, class: &PyClassRef) {
|
||||
Self::impl_extend_class(ctx, class);
|
||||
if let Some(doc) = Self::DOC {
|
||||
ctx.set_attr(class, "__doc__", ctx.new_str(doc.into()));
|
||||
class.set_str_attr("__doc__", ctx.new_str(doc.into()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ fn io_base_cm_exit(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn buffered_io_base_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(buffered, None), (raw, None)]);
|
||||
vm.ctx.set_attr(buffered, "raw", raw.clone());
|
||||
vm.set_attr(buffered, "raw", raw.clone())?;
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
@@ -148,10 +148,10 @@ fn file_io_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let args = vec![name.clone(), vm.ctx.new_int(os_mode)];
|
||||
let file_no = os::os_open(vm, PyFuncArgs::new(args, vec![]))?;
|
||||
|
||||
vm.ctx.set_attr(file_io, "name", name.clone());
|
||||
vm.ctx.set_attr(file_io, "fileno", file_no);
|
||||
vm.ctx.set_attr(file_io, "closefd", vm.new_bool(false));
|
||||
vm.ctx.set_attr(file_io, "closed", vm.new_bool(false));
|
||||
vm.set_attr(file_io, "name", name.clone())?;
|
||||
vm.set_attr(file_io, "fileno", file_no)?;
|
||||
vm.set_attr(file_io, "closefd", vm.new_bool(false))?;
|
||||
vm.set_attr(file_io, "closed", vm.new_bool(false))?;
|
||||
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
@@ -215,7 +215,7 @@ fn file_io_readinto(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
let updated = os::raw_file_number(f.into_inner());
|
||||
vm.ctx.set_attr(file_io, "fileno", vm.ctx.new_int(updated));
|
||||
vm.set_attr(file_io, "fileno", vm.ctx.new_int(updated))?;
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ fn file_io_write(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(len) => {
|
||||
//reset raw fd on the FileIO object
|
||||
let updated = os::raw_file_number(handle);
|
||||
vm.ctx.set_attr(file_io, "fileno", vm.ctx.new_int(updated));
|
||||
vm.set_attr(file_io, "fileno", vm.ctx.new_int(updated))?;
|
||||
|
||||
//return number of bytes written
|
||||
Ok(vm.ctx.new_int(len))
|
||||
@@ -273,7 +273,7 @@ fn text_io_wrapper_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
required = [(text_io_wrapper, None), (buffer, None)]
|
||||
);
|
||||
|
||||
vm.ctx.set_attr(text_io_wrapper, "buffer", buffer.clone());
|
||||
vm.set_attr(text_io_wrapper, "buffer", buffer.clone())?;
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
|
||||
Some(PyString { ref value }) => value.clone(),
|
||||
_ => unimplemented!("map keys must be strings"),
|
||||
};
|
||||
dict.set_item(&self.vm.ctx, &key, value);
|
||||
dict.set_item(&key, value, self.vm);
|
||||
}
|
||||
Ok(dict.into_object())
|
||||
}
|
||||
@@ -208,8 +208,10 @@ pub fn de_pyobject(vm: &VirtualMachine, s: &str) -> PyResult {
|
||||
.unwrap();
|
||||
let json_decode_error = json_decode_error.downcast().unwrap();
|
||||
let exc = vm.new_exception(json_decode_error, format!("{}", err));
|
||||
vm.ctx.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()));
|
||||
vm.ctx.set_attr(&exc, "colno", vm.ctx.new_int(err.column()));
|
||||
vm.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()))
|
||||
.unwrap();
|
||||
vm.set_attr(&exc, "colno", vm.ctx.new_int(err.column()))
|
||||
.unwrap();
|
||||
exc
|
||||
})
|
||||
}
|
||||
|
||||
@@ -114,24 +114,22 @@ fn os_error(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
let py_mod = py_module!(ctx, "os", {
|
||||
let os_name = if cfg!(windows) {
|
||||
"nt".to_string()
|
||||
} else {
|
||||
"posix".to_string()
|
||||
};
|
||||
|
||||
py_module!(ctx, "os", {
|
||||
"open" => ctx.new_rustfunc(os_open),
|
||||
"close" => ctx.new_rustfunc(os_close),
|
||||
"error" => ctx.new_rustfunc(os_error),
|
||||
"name" => ctx.new_str(os_name),
|
||||
"O_RDONLY" => ctx.new_int(0),
|
||||
"O_WRONLY" => ctx.new_int(1),
|
||||
"O_RDWR" => ctx.new_int(2),
|
||||
"O_NONBLOCK" => ctx.new_int(4),
|
||||
"O_APPEND" => ctx.new_int(8),
|
||||
"O_CREAT" => ctx.new_int(512)
|
||||
});
|
||||
|
||||
if cfg!(windows) {
|
||||
ctx.set_attr(&py_mod, "name", ctx.new_str("nt".to_string()));
|
||||
} else {
|
||||
// Assume we're on a POSIX system
|
||||
ctx.set_attr(&py_mod, "name", ctx.new_str("posix".to_string()));
|
||||
}
|
||||
|
||||
py_mod
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{env, mem};
|
||||
|
||||
use crate::frame::FrameRef;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/*
|
||||
@@ -124,8 +124,7 @@ setrecursionlimit() -- set the max recursion depth for the interpreter
|
||||
settrace() -- set the global debug tracing function
|
||||
";
|
||||
let modules = ctx.new_dict();
|
||||
let sys_name = "sys";
|
||||
let sys_mod = py_module!(ctx, sys_name, {
|
||||
let sys_mod = py_module!(ctx, "sys", {
|
||||
"argv" => argv(ctx),
|
||||
"getrefcount" => ctx.new_rustfunc(sys_getrefcount),
|
||||
"getsizeof" => ctx.new_rustfunc(sys_getsizeof),
|
||||
@@ -135,11 +134,11 @@ settrace() -- set the global debug tracing function
|
||||
"ps2" => ctx.new_str("..... ".to_string()),
|
||||
"__doc__" => ctx.new_str(sys_doc.to_string()),
|
||||
"_getframe" => ctx.new_rustfunc(getframe),
|
||||
"modules" => modules.clone(),
|
||||
});
|
||||
|
||||
modules.set_item(&ctx, sys_name, sys_mod.clone());
|
||||
modules.set_item(&ctx, "builtins", builtins);
|
||||
ctx.set_attr(&sys_mod, "modules", modules);
|
||||
modules.unsafe_str_insert("sys", sys_mod.clone(), &ctx);
|
||||
modules.unsafe_str_insert("builtins", builtins, &ctx);
|
||||
|
||||
sys_mod
|
||||
}
|
||||
|
||||
24
vm/src/vm.rs
24
vm/src/vm.rs
@@ -419,7 +419,7 @@ impl VirtualMachine {
|
||||
for i in 0..n {
|
||||
let arg_name = &code_object.arg_names[i];
|
||||
let arg = &args.args[i];
|
||||
locals.set_item(&self.ctx, arg_name, arg.clone());
|
||||
locals.set_item(arg_name, arg.clone(), self);
|
||||
}
|
||||
|
||||
// Pack other positional arguments in to *args:
|
||||
@@ -432,7 +432,7 @@ impl VirtualMachine {
|
||||
}
|
||||
let vararg_value = self.ctx.new_tuple(last_args);
|
||||
|
||||
locals.set_item(&self.ctx, vararg_name, vararg_value);
|
||||
locals.set_item(vararg_name, vararg_value, self);
|
||||
}
|
||||
bytecode::Varargs::Unnamed => {
|
||||
// just ignore the rest of the args
|
||||
@@ -452,7 +452,7 @@ impl VirtualMachine {
|
||||
let kwargs = match code_object.varkeywords {
|
||||
bytecode::Varargs::Named(ref kwargs_name) => {
|
||||
let d = self.ctx.new_dict();
|
||||
locals.set_item(&self.ctx, kwargs_name, d.as_object().clone());
|
||||
locals.set_item(kwargs_name, d.as_object().clone(), self);
|
||||
Some(d)
|
||||
}
|
||||
bytecode::Varargs::Unnamed => Some(self.ctx.new_dict()),
|
||||
@@ -464,15 +464,15 @@ impl VirtualMachine {
|
||||
// Check if we have a parameter with this name:
|
||||
if code_object.arg_names.contains(&name) || code_object.kwonlyarg_names.contains(&name)
|
||||
{
|
||||
if locals.contains_key(&name) {
|
||||
if locals.contains_key(&name, self) {
|
||||
return Err(
|
||||
self.new_type_error(format!("Got multiple values for argument '{}'", name))
|
||||
);
|
||||
}
|
||||
|
||||
locals.set_item(&self.ctx, &name, value);
|
||||
locals.set_item(&name, value, self);
|
||||
} else if let Some(d) = &kwargs {
|
||||
d.set_item(&self.ctx, &name, value);
|
||||
d.set_item(&name, value, self);
|
||||
} else {
|
||||
return Err(
|
||||
self.new_type_error(format!("Got an unexpected keyword argument '{}'", name))
|
||||
@@ -499,7 +499,7 @@ impl VirtualMachine {
|
||||
let mut missing = vec![];
|
||||
for i in 0..required_args {
|
||||
let variable_name = &code_object.arg_names[i];
|
||||
if !locals.contains_key(variable_name) {
|
||||
if !locals.contains_key(variable_name, self) {
|
||||
missing.push(variable_name)
|
||||
}
|
||||
}
|
||||
@@ -515,12 +515,8 @@ impl VirtualMachine {
|
||||
// the default if we don't already have a value
|
||||
for (default_index, i) in (required_args..nexpected_args).enumerate() {
|
||||
let arg_name = &code_object.arg_names[i];
|
||||
if !locals.contains_key(arg_name) {
|
||||
locals.set_item(
|
||||
&self.ctx,
|
||||
arg_name,
|
||||
available_defaults[default_index].clone(),
|
||||
);
|
||||
if !locals.contains_key(arg_name, self) {
|
||||
locals.set_item(arg_name, available_defaults[default_index].clone(), self);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -528,7 +524,7 @@ impl VirtualMachine {
|
||||
// Check if kw only arguments are all present:
|
||||
let kwdefs: HashMap<String, String> = HashMap::new();
|
||||
for arg_name in &code_object.kwonlyarg_names {
|
||||
if !locals.contains_key(arg_name) {
|
||||
if !locals.contains_key(arg_name, self) {
|
||||
if kwdefs.contains_key(arg_name) {
|
||||
// If not yet specified, take the default value
|
||||
unimplemented!();
|
||||
|
||||
Reference in New Issue
Block a user