Skip to content

Commit 51aa817

Browse files
Merge pull request RustPython#829 from skinny121/unittest_rustpython
RustPython changes for RustPython#824
2 parents 71b6e2a + 307689a commit 51aa817

14 files changed

+90
-30
lines changed

Lib/_collections_abc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
dict_values = type({}.values())
5353
dict_items = type({}.items())
5454
## misc ##
55-
mappingproxy = type(type.__dict__)
55+
# mappingproxy = type(type.__dict__)
5656
# generator = type((lambda: (yield))())
5757
## coroutine ##
5858
# async def _coro(): pass
@@ -688,7 +688,7 @@ def __eq__(self, other):
688688

689689
__reversed__ = None
690690

691-
Mapping.register(mappingproxy)
691+
# Mapping.register(mappingproxy)
692692

693693

694694
class MappingView(Sized):

vm/src/builtins.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@ fn builtin_compile(
102102
}
103103
};
104104

105-
compile::compile(vm, &source, &mode, filename.value.to_string()).map_err(|err| {
106-
let syntax_error = vm.context().exceptions.syntax_error.clone();
107-
vm.new_exception(syntax_error, err.to_string())
108-
})
105+
compile::compile(vm, &source, &mode, filename.value.to_string())
106+
.map_err(|err| vm.new_syntax_error(&err))
109107
}
110108

111109
fn builtin_delattr(obj: PyObjectRef, attr: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
@@ -151,10 +149,8 @@ fn builtin_eval(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
151149
let source = objstr::get_value(source);
152150
// TODO: fix this newline bug:
153151
let source = format!("{}\n", source);
154-
compile::compile(vm, &source, &mode, "<string>".to_string()).map_err(|err| {
155-
let syntax_error = vm.context().exceptions.syntax_error.clone();
156-
vm.new_exception(syntax_error, err.to_string())
157-
})?
152+
compile::compile(vm, &source, &mode, "<string>".to_string())
153+
.map_err(|err| vm.new_syntax_error(&err))?
158154
} else {
159155
return Err(vm.new_type_error("code argument must be str or code object".to_string()));
160156
};
@@ -181,10 +177,8 @@ fn builtin_exec(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
181177
let source = objstr::get_value(source);
182178
// TODO: fix this newline bug:
183179
let source = format!("{}\n", source);
184-
compile::compile(vm, &source, &mode, "<string>".to_string()).map_err(|err| {
185-
let syntax_error = vm.context().exceptions.syntax_error.clone();
186-
vm.new_exception(syntax_error, err.to_string())
187-
})?
180+
compile::compile(vm, &source, &mode, "<string>".to_string())
181+
.map_err(|err| vm.new_syntax_error(&err))?
188182
} else if let Ok(code_obj) = PyCodeRef::try_from_object(vm, source.clone()) {
189183
code_obj
190184
} else {

vm/src/eval.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
extern crate rustpython_parser;
22

3-
use std::error::Error;
4-
53
use crate::compile;
64
use crate::frame::Scope;
75
use crate::pyobject::PyResult;
@@ -13,10 +11,7 @@ pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str)
1311
debug!("Code object: {:?}", bytecode);
1412
vm.run_code_obj(bytecode, scope)
1513
}
16-
Err(err) => {
17-
let syntax_error = vm.context().exceptions.syntax_error.clone();
18-
Err(vm.new_exception(syntax_error, err.description().to_string()))
19-
}
14+
Err(err) => Err(vm.new_syntax_error(&err)),
2015
}
2116
}
2217

vm/src/import.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Import mechanics
33
*/
44

5-
use std::error::Error;
65
use std::path::PathBuf;
76

87
use crate::compile;
@@ -25,17 +24,14 @@ fn import_uncached_module(vm: &VirtualMachine, current_path: PathBuf, module: &s
2524
let file_path = find_source(vm, current_path, module)
2625
.map_err(|e| vm.new_exception(notfound_error.clone(), e))?;
2726
let source = util::read_file(file_path.as_path())
28-
.map_err(|e| vm.new_exception(import_error.clone(), e.description().to_string()))?;
27+
.map_err(|e| vm.new_exception(import_error.clone(), e.to_string()))?;
2928
let code_obj = compile::compile(
3029
vm,
3130
&source,
3231
&compile::Mode::Exec,
3332
file_path.to_str().unwrap().to_string(),
3433
)
35-
.map_err(|err| {
36-
let syntax_error = vm.context().exceptions.syntax_error.clone();
37-
vm.new_exception(syntax_error, err.description().to_string())
38-
})?;
34+
.map_err(|err| vm.new_syntax_error(&err))?;
3935
// trace!("Code object: {:?}", code_obj);
4036

4137
let attrs = vm.ctx.new_dict();
@@ -64,12 +60,13 @@ fn find_source(vm: &VirtualMachine, current_path: PathBuf, name: &str) -> Result
6460

6561
paths.insert(0, current_path);
6662

63+
let rel_name = name.replace('.', "/");
6764
let suffixes = [".py", "/__init__.py"];
6865
let mut file_paths = vec![];
6966
for path in paths {
7067
for suffix in suffixes.iter() {
7168
let mut file_path = path.clone();
72-
file_path.push(format!("{}{}", name, suffix));
69+
file_path.push(format!("{}{}", rel_name, suffix));
7370
file_paths.push(file_path);
7471
}
7572
}

vm/src/obj/objclassmethod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub struct PyClassMethod {
99
pub type PyClassMethodRef = PyRef<PyClassMethod>;
1010

1111
impl PyValue for PyClassMethod {
12+
const HAVE_DICT: bool = true;
13+
1214
fn class(vm: &VirtualMachine) -> PyClassRef {
1315
vm.ctx.classmethod_type()
1416
}

vm/src/obj/objfunction.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::frame::Scope;
2+
use crate::function::{Args, KwArgs};
23
use crate::obj::objcode::PyCodeRef;
34
use crate::obj::objdict::PyDictRef;
45
use crate::obj::objtuple::PyTupleRef;
@@ -40,6 +41,10 @@ impl PyValue for PyFunction {
4041
}
4142

4243
impl PyFunctionRef {
44+
fn call(self, args: Args, kwargs: KwArgs, vm: &VirtualMachine) -> PyResult {
45+
vm.invoke(self.into_object(), (&args, &kwargs))
46+
}
47+
4348
fn code(self, _vm: &VirtualMachine) -> PyCodeRef {
4449
self.code.clone()
4550
}
@@ -76,6 +81,7 @@ pub fn init(context: &PyContext) {
7681
let function_type = &context.function_type;
7782
extend_class!(context, function_type, {
7883
"__get__" => context.new_rustfunc(bind_method),
84+
"__call__" => context.new_rustfunc(PyFunctionRef::call),
7985
"__code__" => context.new_property(PyFunctionRef::code),
8086
"__defaults__" => context.new_property(PyFunctionRef::defaults),
8187
"__kwdefaults__" => context.new_property(PyFunctionRef::kwdefaults),

vm/src/obj/objobject.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ pub fn init(context: &PyContext) {
167167
"__ge__" => context.new_rustfunc(object_ge),
168168
"__setattr__" => context.new_rustfunc(object_setattr),
169169
"__delattr__" => context.new_rustfunc(object_delattr),
170-
"__dict__" => context.new_property(object_dict),
170+
"__dict__" =>
171+
PropertyBuilder::new(context)
172+
.add_getter(object_dict)
173+
.add_setter(object_dict_setter)
174+
.create(),
171175
"__dir__" => context.new_rustfunc(object_dir),
172176
"__hash__" => context.new_rustfunc(object_hash),
173177
"__str__" => context.new_rustfunc(object_str),
@@ -203,6 +207,16 @@ fn object_dict(object: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDictRef>
203207
}
204208
}
205209

210+
fn object_dict_setter(
211+
_instance: PyObjectRef,
212+
_value: PyObjectRef,
213+
vm: &VirtualMachine,
214+
) -> PyResult {
215+
Err(vm.new_not_implemented_error(
216+
"Setting __dict__ attribute on am object isn't yet implemented".to_string(),
217+
))
218+
}
219+
206220
fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMachine) -> PyResult {
207221
let name = &name_str.value;
208222
trace!("object.__getattribute__({:?}, {:?})", obj, name);

vm/src/pyobject.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,8 @@ impl PyObject<dyn PyObjectPayload> {
11911191
}
11921192

11931193
pub trait PyValue: fmt::Debug + Sized + 'static {
1194+
const HAVE_DICT: bool = false;
1195+
11941196
fn class(vm: &VirtualMachine) -> PyClassRef;
11951197

11961198
fn into_ref(self, vm: &VirtualMachine) -> PyRef<Self> {
@@ -1203,7 +1205,7 @@ pub trait PyValue: fmt::Debug + Sized + 'static {
12031205
fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyClassRef) -> PyResult<PyRef<Self>> {
12041206
let class = Self::class(vm);
12051207
if objtype::issubclass(&cls, &class) {
1206-
let dict = if cls.is(&class) {
1208+
let dict = if !Self::HAVE_DICT && cls.is(&class) {
12071209
None
12081210
} else {
12091211
Some(vm.ctx.new_dict())

vm/src/stdlib/io.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ fn io_base_cm_exit(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
9595
Ok(vm.get_none())
9696
}
9797

98+
// TODO Check if closed, then if so raise ValueError
99+
fn io_base_flush(_zelf: PyObjectRef, _vm: &VirtualMachine) {}
100+
98101
fn buffered_io_base_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
99102
arg_check!(vm, args, required = [(buffered, None), (raw, None)]);
100103
vm.set_attr(buffered, "raw", raw.clone())?;
@@ -369,7 +372,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
369372
//IOBase the abstract base class of the IO Module
370373
let io_base = py_class!(ctx, "IOBase", ctx.object(), {
371374
"__enter__" => ctx.new_rustfunc(io_base_cm_enter),
372-
"__exit__" => ctx.new_rustfunc(io_base_cm_exit)
375+
"__exit__" => ctx.new_rustfunc(io_base_cm_exit),
376+
"flush" => ctx.new_rustfunc(io_base_flush)
373377
});
374378

375379
// IOBase Subclasses

vm/src/stdlib/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod random;
99
mod re;
1010
pub mod socket;
1111
mod string;
12+
mod thread;
1213
mod time_module;
1314
mod tokenize;
1415
mod types;
@@ -41,6 +42,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
4142
modules.insert("random".to_string(), Box::new(random::make_module));
4243
modules.insert("string".to_string(), Box::new(string::make_module));
4344
modules.insert("struct".to_string(), Box::new(pystruct::make_module));
45+
modules.insert("_thread".to_string(), Box::new(thread::make_module));
4446
modules.insert("time".to_string(), Box::new(time_module::make_module));
4547
modules.insert("tokenize".to_string(), Box::new(tokenize::make_module));
4648
modules.insert("types".to_string(), Box::new(types::make_module));

vm/src/stdlib/thread.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// Implementation of the _thread module, currently noop implementation as RustPython doesn't yet
2+
/// support threading
3+
use super::super::pyobject::PyObjectRef;
4+
use crate::function::PyFuncArgs;
5+
use crate::pyobject::PyResult;
6+
use crate::vm::VirtualMachine;
7+
8+
fn rlock_acquire(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
9+
Ok(vm.get_none())
10+
}
11+
12+
fn rlock_release(_zelf: PyObjectRef, _vm: &VirtualMachine) {}
13+
14+
fn get_ident(_vm: &VirtualMachine) -> u32 {
15+
1
16+
}
17+
18+
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
19+
let ctx = &vm.ctx;
20+
21+
let rlock_type = py_class!(ctx, "_thread.RLock", ctx.object(), {
22+
"acquire" => ctx.new_rustfunc(rlock_acquire),
23+
"release" => ctx.new_rustfunc(rlock_release),
24+
});
25+
26+
py_module!(vm, "_thread", {
27+
"RLock" => rlock_type,
28+
"get_ident" => ctx.new_rustfunc(get_ident)
29+
})
30+
}

vm/src/stdlib/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
3131
py_module!(vm, "types", {
3232
"new_class" => ctx.new_rustfunc(types_new_class),
3333
"FunctionType" => ctx.function_type(),
34+
"MethodType" => ctx.bound_method_type(),
3435
"LambdaType" => ctx.function_type(),
3536
"CodeType" => ctx.code_type(),
3637
"FrameType" => ctx.frame_type()

vm/src/sysmodule.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{env, mem};
33

44
use crate::frame::FrameRef;
55
use crate::function::{OptionalArg, PyFuncArgs};
6+
use crate::obj::objstr::PyStringRef;
67
use crate::pyobject::{ItemProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
78
use crate::vm::VirtualMachine;
89

@@ -39,6 +40,11 @@ fn sys_getsizeof(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
3940
Ok(vm.ctx.new_int(size))
4041
}
4142

43+
// TODO implement string interning, this will be key for performance
44+
fn sys_intern(value: PyStringRef, _vm: &VirtualMachine) -> PyStringRef {
45+
value
46+
}
47+
4248
pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectRef) {
4349
let ctx = &vm.ctx;
4450

@@ -130,13 +136,15 @@ settrace() -- set the global debug tracing function
130136
"argv" => argv(ctx),
131137
"getrefcount" => ctx.new_rustfunc(sys_getrefcount),
132138
"getsizeof" => ctx.new_rustfunc(sys_getsizeof),
139+
"intern" => ctx.new_rustfunc(sys_intern),
133140
"maxsize" => ctx.new_int(std::usize::MAX),
134141
"path" => path,
135142
"ps1" => ctx.new_str(">>>>> ".to_string()),
136143
"ps2" => ctx.new_str("..... ".to_string()),
137144
"__doc__" => ctx.new_str(sys_doc.to_string()),
138145
"_getframe" => ctx.new_rustfunc(getframe),
139146
"modules" => modules.clone(),
147+
"warnoptions" => ctx.new_list(vec![]),
140148
});
141149

142150
modules.set_item("sys", module.clone(), vm).unwrap();

vm/src/vm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ impl VirtualMachine {
234234
self.new_exception(overflow_error, msg)
235235
}
236236

237+
pub fn new_syntax_error<T: ToString>(&self, msg: &T) -> PyObjectRef {
238+
let syntax_error = self.ctx.exceptions.syntax_error.clone();
239+
self.new_exception(syntax_error, msg.to_string())
240+
}
241+
237242
pub fn get_none(&self) -> PyObjectRef {
238243
self.ctx.none()
239244
}

0 commit comments

Comments
 (0)