| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,8 +21,8 @@ use crate::obj::objslice::PySlice; | |||
| 21 | 21 | use crate::obj::objstr; | |
| 22 | 22 | use crate::obj::objtype; | |
| 23 | 23 | use crate::pyobject::{ | |
| 24 | - AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, | ||
| 25 | - TryFromObject, TypeProtocol, | ||
| 24 | + DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TryFromObject, | ||
| 25 | + TypeProtocol, | ||
| 26 | 26 | }; | |
| 27 | 27 | use crate::vm::VirtualMachine; | |
| 28 | 28 | ||
@@ -810,13 +810,10 @@ impl Frame { | |||
| 810 | 810 | // If we're importing a symbol, look it up and use it, otherwise construct a module and return | |
| 811 | 811 | // that | |
| 812 | 812 | let obj = match symbol { | |
| 813 | - Some(symbol) => module.get_attr(symbol).map_or_else( | ||
| 814 | - || { | ||
| 815 | - let import_error = vm.context().exceptions.import_error.clone(); | ||
| 816 | - Err(vm.new_exception(import_error, format!("cannot import name '{}'", symbol))) | ||
| 817 | - }, | ||
| 818 | - Ok, | ||
| 819 | - ), | ||
| 813 | + Some(symbol) => vm.get_attribute(module, symbol.as_str()).map_err(|_| { | ||
| 814 | + let import_error = vm.context().exceptions.import_error.clone(); | ||
| 815 | + vm.new_exception(import_error, format!("cannot import name '{}'", symbol)) | ||
| 816 | + }), | ||
| 820 | 817 | None => Ok(module), | |
| 821 | 818 | }; | |
| 822 | 819 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,7 +8,7 @@ use std::path::PathBuf; | |||
| 8 | 8 | use crate::compile; | |
| 9 | 9 | use crate::frame::Scope; | |
| 10 | 10 | use crate::obj::{objsequence, objstr}; | |
| 11 | - use crate::pyobject::{AttributeProtocol, DictProtocol, PyResult}; | ||
| 11 | + use crate::pyobject::{DictProtocol, PyResult}; | ||
| 12 | 12 | use crate::util; | |
| 13 | 13 | use crate::vm::VirtualMachine; | |
| 14 | 14 | ||
@@ -54,7 +54,7 @@ pub fn import_module( | |||
| 54 | 54 | module_name: &str, | |
| 55 | 55 | ) -> PyResult { | |
| 56 | 56 | // First, see if we already loaded the module: | |
| 57 | - let sys_modules = vm.sys_module.get_attr("modules").unwrap(); | ||
| 57 | + let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules")?; | ||
| 58 | 58 | if let Some(module) = sys_modules.get_item(module_name) { | |
| 59 | 59 | return Ok(module); | |
| 60 | 60 | } | |
@@ -63,8 +63,12 @@ pub fn import_module( | |||
| 63 | 63 | Ok(module) | |
| 64 | 64 | } | |
| 65 | 65 | ||
| 66 | - fn find_source(vm: &VirtualMachine, current_path: PathBuf, name: &str) -> Result<PathBuf, String> { | ||
| 67 | - let sys_path = vm.sys_module.get_attr("path").unwrap(); | ||
| 66 | + fn find_source( | ||
| 67 | + vm: &mut VirtualMachine, | ||
| 68 | + current_path: PathBuf, | ||
| 69 | + name: &str, | ||
| 70 | + ) -> Result<PathBuf, String> { | ||
| 71 | + let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap(); | ||
| 68 | 72 | let mut paths: Vec<PathBuf> = objsequence::get_elements(&sys_path) | |
| 69 | 73 | .iter() | |
| 70 | 74 | .map(|item| PathBuf::from(objstr::get_value(item))) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,43 +1,42 @@ | |||
| 1 | - use crate::function::PyFuncArgs; | ||
| 2 | - use crate::pyobject::{AttributeProtocol, PyContext, PyResult, TypeProtocol}; | ||
| 1 | + use super::objtype::PyClassRef; | ||
| 2 | + use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue}; | ||
| 3 | 3 | use crate::vm::VirtualMachine; | |
| 4 | 4 | ||
| 5 | - pub fn init(context: &PyContext) { | ||
| 6 | - let classmethod_type = &context.classmethod_type; | ||
| 7 | - extend_class!(context, classmethod_type, { | ||
| 8 | - "__get__" => context.new_rustfunc(classmethod_get), | ||
| 9 | - "__new__" => context.new_rustfunc(classmethod_new) | ||
| 10 | - }); | ||
| 5 | + #[derive(Clone, Debug)] | ||
| 6 | + pub struct PyClassMethod { | ||
| 7 | + pub callable: PyObjectRef, | ||
| 11 | 8 | } | |
| 9 | + pub type PyClassMethodRef = PyRef<PyClassMethod>; | ||
| 12 | 10 | ||
| 13 | - fn classmethod_get(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | ||
| 14 | - trace!("classmethod.__get__ {:?}", args.args); | ||
| 15 | - arg_check!( | ||
| 16 | - vm, | ||
| 17 | - args, | ||
| 18 | - required = [ | ||
| 19 | - (cls, Some(vm.ctx.classmethod_type())), | ||
| 20 | - (_inst, None), | ||
| 21 | - (owner, None) | ||
| 22 | - ] | ||
| 23 | - ); | ||
| 24 | - match cls.get_attr("function") { | ||
| 25 | - Some(function) => { | ||
| 26 | - let py_obj = owner.clone(); | ||
| 27 | - let py_method = vm.ctx.new_bound_method(function, py_obj); | ||
| 28 | - Ok(py_method) | ||
| 29 | - } | ||
| 30 | - None => Err(vm.new_attribute_error( | ||
| 31 | - "Attribute Error: classmethod must have 'function' attribute".to_string(), | ||
| 32 | - )), | ||
| 11 | + impl PyValue for PyClassMethod { | ||
| 12 | + fn class(vm: &mut VirtualMachine) -> PyObjectRef { | ||
| 13 | + vm.ctx.classmethod_type() | ||
| 33 | 14 | } | |
| 34 | 15 | } | |
| 35 | 16 | ||
| 36 | - fn classmethod_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | ||
| 37 | - trace!("classmethod.__new__ {:?}", args.args); | ||
| 38 | - arg_check!(vm, args, required = [(cls, None), (callable, None)]); | ||
| 17 | + impl PyClassMethodRef { | ||
| 18 | + fn new( | ||
| 19 | + cls: PyClassRef, | ||
| 20 | + callable: PyObjectRef, | ||
| 21 | + vm: &mut VirtualMachine, | ||
| 22 | + ) -> PyResult<PyClassMethodRef> { | ||
| 23 | + PyClassMethod { | ||
| 24 | + callable: callable.clone(), | ||
| 25 | + } | ||
| 26 | + .into_ref_with_type(vm, cls) | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + fn get(self, _inst: PyObjectRef, owner: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { | ||
| 30 | + Ok(vm | ||
| 31 | + .ctx | ||
| 32 | + .new_bound_method(self.callable.clone(), owner.clone())) | ||
| 33 | + } | ||
| 34 | + } | ||
| 39 | 35 | ||
| 40 | - let py_obj = vm.ctx.new_instance(cls.clone(), None); | ||
| 41 | - vm.ctx.set_attr(&py_obj, "function", callable.clone()); | ||
| 42 | - Ok(py_obj) | ||
| 36 | + pub fn init(context: &PyContext) { | ||
| 37 | + let classmethod_type = &context.classmethod_type; | ||
| 38 | + extend_class!(context, classmethod_type, { | ||
| 39 | + "__get__" => context.new_rustfunc(PyClassMethodRef::get), | ||
| 40 | + "__new__" => context.new_rustfunc(PyClassMethodRef::new) | ||
| 41 | + }); | ||
| 43 | 42 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,40 +1,40 @@ | |||
| 1 | - use crate::function::PyFuncArgs; | ||
| 2 | - use crate::pyobject::{AttributeProtocol, PyContext, PyResult, TypeProtocol}; | ||
| 1 | + use super::objtype::PyClassRef; | ||
| 2 | + use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue}; | ||
| 3 | 3 | use crate::vm::VirtualMachine; | |
| 4 | 4 | ||
| 5 | - pub fn init(context: &PyContext) { | ||
| 6 | - let staticmethod_type = &context.staticmethod_type; | ||
| 7 | - extend_class!(context, staticmethod_type, { | ||
| 8 | - "__get__" => context.new_rustfunc(staticmethod_get), | ||
| 9 | - "__new__" => context.new_rustfunc(staticmethod_new), | ||
| 10 | - }); | ||
| 5 | + #[derive(Clone, Debug)] | ||
| 6 | + pub struct PyStaticMethod { | ||
| 7 | + pub callable: PyObjectRef, | ||
| 11 | 8 | } | |
| 9 | + pub type PyStaticMethodRef = PyRef<PyStaticMethod>; | ||
| 12 | 10 | ||
| 13 | - // `staticmethod` methods. | ||
| 14 | - fn staticmethod_get(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | ||
| 15 | - trace!("staticmethod.__get__ {:?}", args.args); | ||
| 16 | - arg_check!( | ||
| 17 | - vm, | ||
| 18 | - args, | ||
| 19 | - required = [ | ||
| 20 | - (cls, Some(vm.ctx.staticmethod_type())), | ||
| 21 | - (_inst, None), | ||
| 22 | - (_owner, None) | ||
| 23 | - ] | ||
| 24 | - ); | ||
| 25 | - match cls.get_attr("function") { | ||
| 26 | - Some(function) => Ok(function), | ||
| 27 | - None => Err(vm.new_attribute_error( | ||
| 28 | - "Attribute Error: staticmethod must have 'function' attribute".to_string(), | ||
| 29 | - )), | ||
| 11 | + impl PyValue for PyStaticMethod { | ||
| 12 | + fn class(vm: &mut VirtualMachine) -> PyObjectRef { | ||
| 13 | + vm.ctx.staticmethod_type() | ||
| 30 | 14 | } | |
| 31 | 15 | } | |
| 32 | 16 | ||
| 33 | - fn staticmethod_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | ||
| 34 | - trace!("staticmethod.__new__ {:?}", args.args); | ||
| 35 | - arg_check!(vm, args, required = [(cls, None), (callable, None)]); | ||
| 17 | + impl PyStaticMethodRef { | ||
| 18 | + fn new( | ||
| 19 | + cls: PyClassRef, | ||
| 20 | + callable: PyObjectRef, | ||
| 21 | + vm: &mut VirtualMachine, | ||
| 22 | + ) -> PyResult<PyStaticMethodRef> { | ||
| 23 | + PyStaticMethod { | ||
| 24 | + callable: callable.clone(), | ||
| 25 | + } | ||
| 26 | + .into_ref_with_type(vm, cls) | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + fn get(self, _inst: PyObjectRef, _owner: PyObjectRef, _vm: &mut VirtualMachine) -> PyResult { | ||
| 30 | + Ok(self.callable.clone()) | ||
| 31 | + } | ||
| 32 | + } | ||
| 36 | 33 | ||
| 37 | - let py_obj = vm.ctx.new_instance(cls.clone(), None); | ||
| 38 | - vm.ctx.set_attr(&py_obj, "function", callable.clone()); | ||
| 39 | - Ok(py_obj) | ||
| 34 | + pub fn init(context: &PyContext) { | ||
| 35 | + let staticmethod_type = &context.staticmethod_type; | ||
| 36 | + extend_class!(context, staticmethod_type, { | ||
| 37 | + "__get__" => context.new_rustfunc(PyStaticMethodRef::get), | ||
| 38 | + "__new__" => context.new_rustfunc(PyStaticMethodRef::new), | ||
| 39 | + }); | ||
| 40 | 40 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,8 +20,7 @@ use crate::obj::objbytes; | |||
| 20 | 20 | use crate::obj::objint; | |
| 21 | 21 | use crate::obj::objstr; | |
| 22 | 22 | use crate::pyobject::{ | |
| 23 | - AttributeProtocol, BufferProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, | ||
| 24 | - TypeProtocol, | ||
| 23 | + BufferProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, | ||
| 25 | 24 | }; | |
| 26 | 25 | use crate::vm::VirtualMachine; | |
| 27 | 26 | ||
@@ -165,7 +164,7 @@ fn file_io_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |||
| 165 | 164 | ||
| 166 | 165 | fn file_io_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |
| 167 | 166 | arg_check!(vm, args, required = [(file_io, None)]); | |
| 168 | - let py_name = file_io.get_attr("name").unwrap(); | ||
| 167 | + let py_name = vm.get_attribute(file_io.clone(), "name")?; | ||
| 169 | 168 | let f = match File::open(objstr::get_value(&py_name)) { | |
| 170 | 169 | Ok(v) => Ok(v), | |
| 171 | 170 | Err(_) => Err(vm.new_type_error("Error opening file".to_string())), | |
@@ -200,7 +199,7 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |||
| 200 | 199 | let py_length = vm.call_method(obj, "__len__", PyFuncArgs::default())?; | |
| 201 | 200 | let length = objint::get_value(&py_length).to_u64().unwrap(); | |
| 202 | 201 | ||
| 203 | - let file_no = file_io.get_attr("fileno").unwrap(); | ||
| 202 | + let file_no = vm.get_attribute(file_io.clone(), "fileno")?; | ||
| 204 | 203 | let raw_fd = objint::get_value(&file_no).to_i64().unwrap(); | |
| 205 | 204 | ||
| 206 | 205 | //extract unix file descriptor. | |
@@ -230,7 +229,7 @@ fn file_io_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |||
| 230 | 229 | required = [(file_io, None), (obj, Some(vm.ctx.bytes_type()))] | |
| 231 | 230 | ); | |
| 232 | 231 | ||
| 233 | - let file_no = file_io.get_attr("fileno").unwrap(); | ||
| 232 | + let file_no = vm.get_attribute(file_io.clone(), "fileno")?; | ||
| 234 | 233 | let raw_fd = objint::get_value(&file_no).to_i64().unwrap(); | |
| 235 | 234 | ||
| 236 | 235 | //unsafe block - creates file handle from the UNIX file descriptor | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,14 +12,12 @@ use regex::{Match, Regex}; | |||
| 12 | 12 | use crate::function::PyFuncArgs; | |
| 13 | 13 | use crate::import; | |
| 14 | 14 | use crate::obj::objstr; | |
| 15 | - use crate::pyobject::{ | ||
| 16 | - AttributeProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, | ||
| 17 | - }; | ||
| 15 | + use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol}; | ||
| 18 | 16 | use crate::vm::VirtualMachine; | |
| 19 | 17 | ||
| 20 | 18 | impl PyValue for Regex { | |
| 21 | 19 | fn class(vm: &mut VirtualMachine) -> PyObjectRef { | |
| 22 | - vm.import("re").unwrap().get_attr("Pattern").unwrap() | ||
| 20 | + vm.class("re", "Pattern") | ||
| 23 | 21 | } | |
| 24 | 22 | } | |
| 25 | 23 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,7 +57,7 @@ fn sys_getsizeof(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { | |||
| 57 | 57 | Ok(vm.ctx.new_int(size)) | |
| 58 | 58 | } | |
| 59 | 59 | ||
| 60 | - pub fn make_module(ctx: &PyContext) -> PyObjectRef { | ||
| 60 | + pub fn make_module(ctx: &PyContext, builtins: PyObjectRef) -> PyObjectRef { | ||
| 61 | 61 | let path_list = match env::var_os("PYTHONPATH") { | |
| 62 | 62 | Some(paths) => env::split_paths(&paths) | |
| 63 | 63 | .map(|path| { | |
@@ -156,6 +156,7 @@ settrace() -- set the global debug tracing function | |||
| 156 | 156 | }); | |
| 157 | 157 | ||
| 158 | 158 | modules.set_item(&ctx, sys_name, sys_mod.clone()); | |
| 159 | + modules.set_item(&ctx, "builtins", builtins); | ||
| 159 | 160 | ctx.set_attr(&sys_mod, "modules", modules); | |
| 160 | 161 | ||
| 161 | 162 | sys_mod | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -58,11 +58,7 @@ impl VirtualMachine { | |||
| 58 | 58 | ||
| 59 | 59 | // Hard-core modules: | |
| 60 | 60 | let builtins = builtins::make_module(&ctx); | |
| 61 | - let sysmod = sysmodule::make_module(&ctx); | ||
| 62 | - | ||
| 63 | - // Add builtins as builtins module: | ||
| 64 | - let modules = sysmod.get_attr("modules").unwrap(); | ||
| 65 | - modules.set_item(&ctx, "builtins", builtins.clone()); | ||
| 61 | + let sysmod = sysmodule::make_module(&ctx, builtins.clone()); | ||
| 66 | 62 | ||
| 67 | 63 | let stdlib_inits = stdlib::get_module_inits(); | |
| 68 | 64 | VirtualMachine { | |
@@ -109,10 +105,11 @@ impl VirtualMachine { | |||
| 109 | 105 | } | |
| 110 | 106 | ||
| 111 | 107 | pub fn class(&mut self, module: &str, class: &str) -> PyObjectRef { | |
| 112 | - self.import(module) | ||
| 113 | - .unwrap_or_else(|_| panic!("unable to import {}", module)) | ||
| 114 | - .get_attr(class) | ||
| 115 | - .unwrap_or_else(|| panic!("module {} has no class {}", module, class)) | ||
| 108 | + let module = self | ||
| 109 | + .import(module) | ||
| 110 | + .unwrap_or_else(|_| panic!("unable to import {}", module)); | ||
| 111 | + self.get_attribute(module.clone(), class) | ||
| 112 | + .unwrap_or_else(|_| panic!("module {} has no class {}", module, class)) | ||
| 116 | 113 | } | |
| 117 | 114 | ||
| 118 | 115 | /// Create a new python string object. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments