Skip to content

Commit 5569f8d

Browse files
committed
Merge branch 'master' of git://github.com/RustPython/RustPython into wasm-syntax-error-location
2 parents 7b8c890 + 29e9029 commit 5569f8d

29 files changed

+1377
-1398
lines changed

parser/src/python.lalrpop

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,10 +791,24 @@ Power: ast::Expression = {
791791
AtomExpr: ast::Expression = {
792792
<e:Atom> => e,
793793
<f:AtomExpr> "(" <a:ArgumentList> ")" => ast::Expression::Call { function: Box::new(f), args: a.0, keywords: a.1 },
794-
<e:AtomExpr> "[" <s:Subscript> "]" => ast::Expression::Subscript { a: Box::new(e), b: Box::new(s) },
794+
<e:AtomExpr> "[" <s:SubscriptList> "]" => ast::Expression::Subscript { a: Box::new(e), b: Box::new(s) },
795795
<e:AtomExpr> "." <n:Identifier> => ast::Expression::Attribute { value: Box::new(e), name: n },
796796
};
797797

798+
SubscriptList: ast::Expression = {
799+
<s1:Subscript> <s2:("," Subscript)*> ","? => {
800+
if s2.is_empty() {
801+
s1
802+
} else {
803+
let mut dims = vec![s1];
804+
for x in s2 {
805+
dims.push(x.1)
806+
}
807+
ast::Expression::Tuple { elements: dims }
808+
}
809+
}
810+
};
811+
798812
Subscript: ast::Expression = {
799813
<e:Test> => e,
800814
<e1:Test?> ":" <e2:Test?> <e3:SliceOp?> => {

tests/snippets/bools.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
assert bool(1) == True
1717
assert bool({}) == False
1818

19+
assert bool(NotImplemented) == True
20+
assert bool(...) == True
21+
1922
if not 1:
2023
raise BaseException
2124

tests/snippets/builtin_dir.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@ def test():
55

66
a = A()
77

8-
assert "test" in dir(a)
8+
assert "test" in dir(a), "test not in a"
9+
assert "test" in dir(A), "test not in A"
10+
11+
class B(A):
12+
def __dir__(self):
13+
return ('q', 'h')
14+
15+
# Gets sorted and turned into a list
16+
assert ['h', 'q'] == dir(B())
17+
18+
# This calls type.__dir__ so isn't changed (but inheritance works)!
19+
assert 'test' in dir(A)
920

1021
import socket
1122

tests/snippets/dict.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,20 @@ def dict_eq(d1, d2):
1717

1818
a.clear()
1919
assert len(a) == 0
20+
21+
a = {'a': 5, 'b': 6}
22+
res = set()
23+
for value in a.values():
24+
res.add(value)
25+
assert res == set([5,6])
26+
27+
count = 0
28+
for (key, value) in a.items():
29+
assert a[key] == value
30+
count += 1
31+
assert count == len(a)
32+
33+
res = set()
34+
for key in a.keys():
35+
res.add(key)
36+
assert res == set(['a','b'])

tests/snippets/test_re.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,10 @@
44
haystack = "Hello world"
55
needle = 'ello'
66

7-
print(re.search(needle, haystack))
7+
mo = re.search(needle, haystack)
8+
print(mo)
89

10+
# Does not work on python 3.6:
11+
# assert isinstance(mo, re.Match)
12+
assert mo.start() == 1
13+
assert mo.end() == 5

vm/src/builtins.rs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,6 @@ fn dir_locals(vm: &mut VirtualMachine) -> PyObjectRef {
4040
get_locals(vm)
4141
}
4242

43-
fn dir_object(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyObjectRef {
44-
// Gather all members here:
45-
let attributes = objtype::get_attributes(obj);
46-
let mut members: Vec<String> = attributes.into_iter().map(|(n, _o)| n).collect();
47-
48-
// Sort members:
49-
members.sort();
50-
51-
let members_pystr = members.into_iter().map(|m| vm.ctx.new_str(m)).collect();
52-
vm.ctx.new_list(members_pystr)
53-
}
54-
5543
fn builtin_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5644
arg_check!(vm, args, required = [(x, None)]);
5745
match vm.get_method(x.clone(), "__abs__") {
@@ -171,14 +159,16 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
171159
Ok(dir_locals(vm))
172160
} else {
173161
let obj = args.args.into_iter().next().unwrap();
174-
Ok(dir_object(vm, &obj))
162+
let seq = vm.call_method(&obj, "__dir__", vec![])?;
163+
let sorted = builtin_sorted(vm, PyFuncArgs::new(vec![seq], vec![]))?;
164+
Ok(sorted)
175165
}
176166
}
177167

178168
fn builtin_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
179169
arg_check!(vm, args, required = [(x, None), (y, None)]);
180170
match vm.get_method(x.clone(), "__divmod__") {
181-
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
171+
Ok(attrib) => vm.invoke(attrib, vec![y.clone()]),
182172
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for divmod".to_string())),
183173
}
184174
}
@@ -429,16 +419,14 @@ fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
429419
// TODO: this key function looks pretty duplicate. Maybe we can create
430420
// a local function?
431421
let mut x_key = if let Some(f) = &key_func {
432-
let args = PyFuncArgs::new(vec![x.clone()], vec![]);
433-
vm.invoke(f.clone(), args)?
422+
vm.invoke(f.clone(), vec![x.clone()])?
434423
} else {
435424
x.clone()
436425
};
437426

438427
for y in candidates_iter {
439428
let y_key = if let Some(f) = &key_func {
440-
let args = PyFuncArgs::new(vec![y.clone()], vec![]);
441-
vm.invoke(f.clone(), args)?
429+
vm.invoke(f.clone(), vec![y.clone()])?
442430
} else {
443431
y.clone()
444432
};
@@ -479,16 +467,14 @@ fn builtin_min(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
479467
// TODO: this key function looks pretty duplicate. Maybe we can create
480468
// a local function?
481469
let mut x_key = if let Some(f) = &key_func {
482-
let args = PyFuncArgs::new(vec![x.clone()], vec![]);
483-
vm.invoke(f.clone(), args)?
470+
vm.invoke(f.clone(), vec![x.clone()])?
484471
} else {
485472
x.clone()
486473
};
487474

488475
for y in candidates_iter {
489476
let y_key = if let Some(f) = &key_func {
490-
let args = PyFuncArgs::new(vec![y.clone()], vec![]);
491-
vm.invoke(f.clone(), args)?
477+
vm.invoke(f.clone(), vec![y.clone()])?
492478
} else {
493479
y.clone()
494480
};
@@ -566,7 +552,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
566552
);
567553
let pow_method_name = "__pow__";
568554
let result = match vm.get_method(x.clone(), pow_method_name) {
569-
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
555+
Ok(attrib) => vm.invoke(attrib, vec![y.clone()]),
570556
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for pow".to_string())),
571557
};
572558
//Check if the 3rd argument is defined and perform modulus on the result
@@ -576,7 +562,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
576562
Some(mod_value) => {
577563
let mod_method_name = "__mod__";
578564
match vm.get_method(result.expect("result not defined").clone(), mod_method_name) {
579-
Ok(value) => vm.invoke(value, PyFuncArgs::new(vec![mod_value.clone()], vec![])),
565+
Ok(value) => vm.invoke(value, vec![mod_value.clone()]),
580566
Err(..) => {
581567
Err(vm.new_type_error("unsupported operand type(s) for mod".to_string()))
582568
}
@@ -709,7 +695,7 @@ fn builtin_sorted(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
709695
let lst = vm.ctx.new_list(items);
710696

711697
args.shift();
712-
vm.call_method_pyargs(&lst, "sort", args)?;
698+
vm.call_method(&lst, "sort", args)?;
713699
Ok(lst)
714700
}
715701

@@ -843,13 +829,7 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
843829
// Prepare uses full __getattribute__ resolution chain.
844830
let prepare_name = vm.new_str("__prepare__".to_string());
845831
let prepare = vm.get_attribute(metaclass.clone(), prepare_name)?;
846-
let namespace = vm.invoke(
847-
prepare,
848-
PyFuncArgs {
849-
args: vec![name_arg.clone(), bases.clone()],
850-
kwargs: vec![],
851-
},
852-
)?;
832+
let namespace = vm.invoke(prepare, vec![name_arg.clone(), bases.clone()])?;
853833

854834
vm.invoke_with_locals(function, namespace.clone())?;
855835

vm/src/frame.rs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
extern crate rustpython_parser;
2-
3-
use self::rustpython_parser::ast;
41
use std::cell::RefCell;
52
use std::fmt;
63
use std::path::PathBuf;
4+
use std::rc::Rc;
5+
6+
use num_bigint::BigInt;
7+
8+
use rustpython_parser::ast;
79

810
use crate::builtins;
911
use crate::bytecode;
1012
use crate::import::{import, import_module};
1113
use crate::obj::objbool;
1214
use crate::obj::objcode;
1315
use crate::obj::objdict;
16+
use crate::obj::objdict::PyDict;
17+
use crate::obj::objint::PyInt;
1418
use crate::obj::objiter;
1519
use crate::obj::objlist;
1620
use crate::obj::objstr;
@@ -20,8 +24,6 @@ use crate::pyobject::{
2024
TypeProtocol,
2125
};
2226
use crate::vm::VirtualMachine;
23-
use num_bigint::BigInt;
24-
use std::rc::Rc;
2527

2628
/*
2729
* So a scope is a linked list of scopes.
@@ -285,10 +287,14 @@ impl Frame {
285287

286288
let mut out: Vec<Option<BigInt>> = elements
287289
.into_iter()
288-
.map(|x| match x.payload {
289-
PyObjectPayload::Integer { ref value } => Some(value.clone()),
290-
PyObjectPayload::None => None,
291-
_ => panic!("Expect Int or None as BUILD_SLICE arguments, got {:?}", x),
290+
.map(|x| {
291+
if x.is(&vm.ctx.none()) {
292+
None
293+
} else if let Some(i) = x.payload::<PyInt>() {
294+
Some(i.value.clone())
295+
} else {
296+
panic!("Expect Int or None as BUILD_SLICE arguments")
297+
}
292298
})
293299
.collect();
294300

@@ -574,18 +580,15 @@ impl Frame {
574580
}
575581
bytecode::Instruction::PrintExpr => {
576582
let expr = self.pop_value();
577-
match expr.payload {
578-
PyObjectPayload::None => (),
579-
_ => {
580-
let repr = vm.to_repr(&expr)?;
581-
builtins::builtin_print(
582-
vm,
583-
PyFuncArgs {
584-
args: vec![repr],
585-
kwargs: vec![],
586-
},
587-
)?;
588-
}
583+
if !expr.is(&vm.get_none()) {
584+
let repr = vm.to_repr(&expr)?;
585+
builtins::builtin_print(
586+
vm,
587+
PyFuncArgs {
588+
args: vec![repr],
589+
kwargs: vec![],
590+
},
591+
)?;
589592
}
590593
Ok(None)
591594
}
@@ -1125,18 +1128,13 @@ impl fmt::Debug for Frame {
11251128
.map(|elem| format!("\n > {:?}", elem))
11261129
.collect::<Vec<_>>()
11271130
.join("");
1128-
let local_str = match self.scope.locals.payload {
1129-
PyObjectPayload::Dict { ref elements } => {
1130-
objdict::get_key_value_pairs_from_content(&elements.borrow())
1131-
.iter()
1132-
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1133-
.collect::<Vec<_>>()
1134-
.join("")
1135-
}
1136-
ref unexpected => panic!(
1137-
"locals unexpectedly not wrapping a dict! instead: {:?}",
1138-
unexpected
1139-
),
1131+
let local_str = match self.scope.locals.payload::<PyDict>() {
1132+
Some(dict) => objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
1133+
.iter()
1134+
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1135+
.collect::<Vec<_>>()
1136+
.join(""),
1137+
None => panic!("locals unexpectedly not wrapping a dict!",),
11401138
};
11411139
write!(
11421140
f,

vm/src/function.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::fmt;
12
use std::marker::PhantomData;
23
use std::ops::Deref;
34

@@ -21,6 +22,7 @@ use crate::vm::VirtualMachine;
2122
/// A `PyRef<T>` can be directly returned from a built-in function to handle
2223
/// situations (such as when implementing in-place methods such as `__iadd__`)
2324
/// where a reference to the same object must be returned.
25+
#[derive(Clone)]
2426
pub struct PyRef<T> {
2527
// invariant: this obj must always have payload of type T
2628
obj: PyObjectRef,
@@ -81,3 +83,9 @@ impl<T> IntoPyObject for PyRef<T> {
8183
Ok(self.obj)
8284
}
8385
}
86+
87+
impl<T> fmt::Display for PyRef<T> {
88+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89+
self.obj.fmt(f)
90+
}
91+
}

vm/src/obj/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod objiter;
1818
pub mod objlist;
1919
pub mod objmap;
2020
pub mod objmemory;
21+
pub mod objmodule;
2122
pub mod objnone;
2223
pub mod objobject;
2324
pub mod objproperty;

0 commit comments

Comments
 (0)