Skip to content

Commit 5b63738

Browse files
committed
Fixed RustPython#191, fixes recursive repr() for the standard collections
1 parent d8afc6a commit 5b63738

14 files changed

Lines changed: 117 additions & 106 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/snippets/builtin_dict.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@
44
assert len({"a": "b"}) == 1
55
assert len({"a": "b", "b": 1}) == 2
66
assert len({"a": "b", "b": 1, "a" + "b": 2*2}) == 3
7+
8+
d = {}
9+
d['a'] = d
10+
assert repr(d) == "{'a': {...}}"

tests/snippets/list.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@
3838
pass
3939
else:
4040
assert False, "IndexError was not raised"
41+
42+
recursive = []
43+
recursive.append(recursive)
44+
assert repr(recursive) == "[[...]]"

tests/snippets/set.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,16 @@
2424
assert set([1,2]) < set([1,2,3])
2525
assert not set([1,2]) < set([1,2])
2626
assert not set([1,3]) < set([1,2])
27+
28+
29+
class Hashable(object):
30+
def __init__(self, obj):
31+
self.obj = obj
32+
33+
def __repr__(self):
34+
return repr(self.obj)
35+
36+
37+
recursive = set()
38+
recursive.add(Hashable(recursive))
39+
assert repr(recursive) == "{set(...)}"

tests/snippets/tuple.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@
1919

2020
b = (1,2,3)
2121
assert b.index(2) == 1
22+
23+
recursive_list = []
24+
recursive = (recursive_list,)
25+
recursive_list.append(recursive)
26+
assert repr(recursive) == "([(...)],)"

vm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ regex = "1"
2020
statrs = "0.10.0"
2121
caseless = "0.2.1"
2222
unicode-segmentation = "1.2.1"
23+
lazy_static = "^1.0.1"

vm/src/frame.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ impl fmt::Debug for Frame {
10851085
let stack_str = self
10861086
.stack
10871087
.iter()
1088-
.map(|elem| format!("\n > {}", elem.borrow().str()))
1088+
.map(|elem| format!("\n > {:?}", elem.borrow()))
10891089
.collect::<Vec<_>>()
10901090
.join("");
10911091
let block_str = self
@@ -1099,9 +1099,7 @@ impl fmt::Debug for Frame {
10991099
PyObjectPayload::Dict { ref elements } => {
11001100
objdict::get_key_value_pairs_from_content(elements)
11011101
.iter()
1102-
.map(|elem| {
1103-
format!("\n {} = {}", elem.0.borrow().str(), elem.1.borrow().str())
1104-
})
1102+
.map(|elem| format!("\n {:?} = {:?}", elem.0.borrow(), elem.1.borrow()))
11051103
.collect::<Vec<_>>()
11061104
.join("")
11071105
}

vm/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#[macro_use]
99
extern crate bitflags;
1010
#[macro_use]
11+
extern crate lazy_static;
12+
#[macro_use]
1113
extern crate log;
1214
// extern crate env_logger;
1315
extern crate num_bigint;

vm/src/obj/objdict.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::super::pyobject::{
22
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
33
};
4-
use super::super::vm::VirtualMachine;
4+
use super::super::vm::{ReprGuard, VirtualMachine};
55
use super::objiter;
66
use super::objstr;
77
use super::objtype;
@@ -158,16 +158,21 @@ fn dict_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
158158
fn dict_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
159159
arg_check!(vm, args, required = [(dict_obj, Some(vm.ctx.dict_type()))]);
160160

161-
let elements = get_key_value_pairs(dict_obj);
162-
let mut str_parts = vec![];
163-
for (key, value) in elements {
164-
let s = vm.to_repr(&value)?;
165-
let key_str = objstr::get_value(&key);
166-
let value_str = objstr::get_value(&s);
167-
str_parts.push(format!("{}: {}", key_str, value_str));
168-
}
161+
let s = if let Some(_guard) = ReprGuard::enter(dict_obj) {
162+
let elements = get_key_value_pairs(dict_obj);
163+
let mut str_parts = vec![];
164+
for (key, value) in elements {
165+
let key_repr = vm.to_repr(&key)?;
166+
let value_repr = vm.to_repr(&value)?;
167+
let key_str = objstr::get_value(&key_repr);
168+
let value_str = objstr::get_value(&value_repr);
169+
str_parts.push(format!("{}: {}", key_str, value_str));
170+
}
169171

170-
let s = format!("{{{}}}", str_parts.join(", "));
172+
format!("{{{}}}", str_parts.join(", "))
173+
} else {
174+
"{...}".to_string()
175+
};
171176
Ok(vm.new_str(s))
172177
}
173178

vm/src/obj/objlist.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::super::pyobject::{
22
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
33
};
4-
use super::super::vm::VirtualMachine;
4+
use super::super::vm::{ReprGuard, VirtualMachine};
55
use super::objbool;
66
use super::objint;
77
use super::objsequence::{
@@ -184,14 +184,18 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
184184
fn list_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
185185
arg_check!(vm, args, required = [(o, Some(vm.ctx.list_type()))]);
186186

187-
let elements = get_elements(o);
188-
let mut str_parts = vec![];
189-
for elem in elements.iter() {
190-
let s = vm.to_repr(elem)?;
191-
str_parts.push(objstr::get_value(&s));
192-
}
187+
let s = if let Some(_guard) = ReprGuard::enter(o) {
188+
let elements = get_elements(o);
189+
let mut str_parts = vec![];
190+
for elem in elements.iter() {
191+
let s = vm.to_repr(elem)?;
192+
str_parts.push(objstr::get_value(&s));
193+
}
194+
format!("[{}]", str_parts.join(", "))
195+
} else {
196+
"[...]".to_string()
197+
};
193198

194-
let s = format!("[{}]", str_parts.join(", "));
195199
Ok(vm.new_str(s))
196200
}
197201

0 commit comments

Comments
 (0)