Skip to content

Commit 48b0a17

Browse files
committed
Merge branch 'master' into coolreader18/proc-macro-span-errors
2 parents dc63fc8 + 615a121 commit 48b0a17

16 files changed

+212
-131
lines changed

src/main.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,8 @@ fn main() {
6565
}
6666

6767
fn _run_string(vm: &VirtualMachine, source: &str, source_path: String) -> PyResult {
68-
let code_obj =
69-
compile::compile(vm, source, &compile::Mode::Exec, source_path).map_err(|err| {
70-
let syntax_error = vm.context().exceptions.syntax_error.clone();
71-
vm.new_exception(syntax_error, err.to_string())
72-
})?;
68+
let code_obj = compile::compile(vm, source, &compile::Mode::Exec, source_path)
69+
.map_err(|err| vm.new_syntax_error(&err))?;
7370
// trace!("Code object: {:?}", code_obj.borrow());
7471
let vars = vm.ctx.new_scope(); // Keep track of local variables
7572
vm.run_code_obj(code_obj, vars)
@@ -120,8 +117,7 @@ fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> Result<(), Com
120117
// Don't inject syntax errors for line continuation
121118
Err(err @ CompileError::Parse(ParseError::EOF(_))) => Err(err),
122119
Err(err) => {
123-
let syntax_error = vm.context().exceptions.syntax_error.clone();
124-
let exc = vm.new_exception(syntax_error, format!("{}", err));
120+
let exc = vm.new_syntax_error(&err);
125121
print_exception(vm, &exc);
126122
Err(err)
127123
}

tests/snippets/builtin_slice.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
b = [1, 2]
1212

1313
assert b[:] == [1, 2]
14+
assert b[slice(None)] == [1, 2]
1415
assert b[: 2 ** 100] == [1, 2]
1516
assert b[-2 ** 100 :] == [1, 2]
1617
assert b[2 ** 100 :] == []
@@ -60,6 +61,12 @@
6061
assert slice_c.stop == 5
6162
assert slice_c.step == 2
6263

64+
a = object()
65+
slice_d = slice(a, "v", 1.0)
66+
assert slice_d.start is a
67+
assert slice_d.stop == "v"
68+
assert slice_d.step == 1.0
69+
6370

6471
class SubScript(object):
6572
def __getitem__(self, item):
@@ -74,6 +81,18 @@ def __setitem__(self, key, value):
7481
ss[:1] = 1
7582

7683

84+
class CustomIndex:
85+
def __init__(self, x):
86+
self.x = x
87+
88+
def __index__(self):
89+
return self.x
90+
91+
92+
assert c[CustomIndex(1):CustomIndex(3)] == [1, 2]
93+
assert d[CustomIndex(1):CustomIndex(3)] == "23"
94+
95+
7796
def test_all_slices():
7897
"""
7998
test all possible slices except big number

tests/snippets/global_nonlocal.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,13 @@ def b():
1111
b()
1212
assert a == 4
1313

14+
def x():
15+
def y():
16+
nonlocal b
17+
b = 3
18+
b = 2
19+
y()
20+
return b
21+
22+
res = x()
23+
assert res == 3, str(res)

tests/snippets/import.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from import_target import func as aliased_func, other_func as aliased_other_func
44
from import_star import *
55

6+
import import_mutual1
67
assert import_target.X == import_target.func()
78
assert import_target.X == func()
89

tests/snippets/import_mutual1.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# Mutual recursive import:
3+
import import_mutual2
4+

tests/snippets/import_mutual2.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
# Mutual recursive import:
3+
import import_mutual1

tests/snippets/stdlib_os.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ def __exit__(self, exc_type, exc_val, exc_tb):
5151
assert ENV_KEY in os.environ
5252
assert os.getenv(ENV_KEY) == ENV_VALUE
5353
del os.environ[ENV_KEY]
54-
os.unsetenv(ENV_KEY)
5554
assert ENV_KEY not in os.environ
5655
assert os.getenv(ENV_KEY) == None
56+
57+
if os.name == "posix":
58+
os.putenv(ENV_KEY, ENV_VALUE)
59+
os.unsetenv(ENV_KEY)
60+
assert os.getenv(ENV_KEY) == None

vm/src/bytecode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub type Label = usize;
4141
#[derive(Debug, Clone, PartialEq)]
4242
pub enum NameScope {
4343
Local,
44+
NonLocal,
4445
Global,
4546
}
4647

vm/src/compile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ impl Compiler {
179179
let role = self.lookup_name(name);
180180
match role {
181181
SymbolRole::Global => bytecode::NameScope::Global,
182+
SymbolRole::Nonlocal => bytecode::NameScope::NonLocal,
182183
_ => bytecode::NameScope::Local,
183184
}
184185
}
185186

186187
fn load_name(&mut self, name: &str) {
187-
// TODO: if global, do something else!
188188
let scope = self.scope_for_name(name);
189189
self.emit(Instruction::LoadName {
190190
name: name.to_string(),

vm/src/frame.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use std::cell::RefCell;
22
use std::fmt;
33
use std::rc::Rc;
44

5-
use num_bigint::BigInt;
6-
75
use rustpython_parser::ast;
86

97
use crate::builtins;
@@ -12,7 +10,6 @@ use crate::function::PyFuncArgs;
1210
use crate::obj::objbool;
1311
use crate::obj::objcode::PyCodeRef;
1412
use crate::obj::objdict::{PyDict, PyDictRef};
15-
use crate::obj::objint::PyInt;
1613
use crate::obj::objiter;
1714
use crate::obj::objlist;
1815
use crate::obj::objslice::PySlice;
@@ -129,6 +126,7 @@ pub trait NameProtocol {
129126
fn store_name(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
130127
fn delete_name(&self, vm: &VirtualMachine, name: &str);
131128
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef>;
129+
fn store_cell(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
132130
fn load_global(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef>;
133131
fn store_global(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
134132
}
@@ -157,6 +155,16 @@ impl NameProtocol for Scope {
157155
None
158156
}
159157

158+
fn store_cell(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef) {
159+
self.locals
160+
.iter()
161+
.skip(1)
162+
.next()
163+
.expect("no outer scope for non-local")
164+
.set_item(name, value, vm)
165+
.unwrap();
166+
}
167+
160168
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
161169
self.get_locals().set_item(key, value, vm).unwrap();
162170
}
@@ -435,26 +443,21 @@ impl Frame {
435443
}
436444
bytecode::Instruction::BuildSlice { size } => {
437445
assert!(*size == 2 || *size == 3);
438-
let elements = self.pop_multiple(*size);
439446

440-
let mut out: Vec<Option<BigInt>> = elements
441-
.into_iter()
442-
.map(|x| {
443-
if x.is(&vm.ctx.none()) {
444-
None
445-
} else if let Some(i) = x.payload::<PyInt>() {
446-
Some(i.as_bigint().clone())
447-
} else {
448-
panic!("Expect Int or None as BUILD_SLICE arguments")
449-
}
450-
})
451-
.collect();
452-
453-
let start = out[0].take();
454-
let stop = out[1].take();
455-
let step = if out.len() == 3 { out[2].take() } else { None };
447+
let step = if *size == 3 {
448+
Some(self.pop_value())
449+
} else {
450+
None
451+
};
452+
let stop = self.pop_value();
453+
let start = self.pop_value();
456454

457-
let obj = PySlice { start, stop, step }.into_ref(vm);
455+
let obj = PySlice {
456+
start: Some(start),
457+
stop,
458+
step,
459+
}
460+
.into_ref(vm);
458461
self.push_value(obj.into_object());
459462
Ok(None)
460463
}
@@ -1037,8 +1040,11 @@ impl Frame {
10371040
bytecode::NameScope::Global => {
10381041
self.scope.store_global(vm, name, obj);
10391042
}
1043+
bytecode::NameScope::NonLocal => {
1044+
self.scope.store_cell(vm, name, obj);
1045+
}
10401046
bytecode::NameScope::Local => {
1041-
self.scope.store_name(&vm, name, obj);
1047+
self.scope.store_name(vm, name, obj);
10421048
}
10431049
}
10441050
Ok(None)
@@ -1057,6 +1063,7 @@ impl Frame {
10571063
) -> FrameResult {
10581064
let optional_value = match name_scope {
10591065
bytecode::NameScope::Global => self.scope.load_global(vm, name),
1066+
bytecode::NameScope::NonLocal => self.scope.load_cell(vm, name),
10601067
bytecode::NameScope::Local => self.scope.load_name(&vm, name),
10611068
};
10621069

0 commit comments

Comments
 (0)