8000 Implement dir on object · rmliddle/RustPython@a9bc374 · GitHub
[go: up one dir, main page]

Skip to content

Commit a9bc374

Browse files
committed
Implement dir on object
1 parent 82226bf commit a9bc374

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

vm/src/builtins.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::collections::HashMap;
44
use std::io::{self, Write};
55

66
use super::compile;
7+
use super::obj::objdict;
78
use super::obj::objstr;
89
use super::obj::objtype;
910
use super::objbool;
@@ -32,14 +33,40 @@ fn dir_locals(vm: &mut VirtualMachine) -> PyObjectRef {
3233
get_locals(vm)
3334
}
3435

35-
fn dir_object(vm: &mut VirtualMachine, _obj: PyObjectRef) -> PyObjectRef {
36-
let d = vm.new_dict();
37-
// TODO: loop over dict of instance, next of class?
38-
// TODO: Implement dir for objects
39-
// for i in obj.iter_items() {
40-
// d.set_item(k, v);
41-
// }
42-
d
36+
fn dir_object(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyObjectRef {
37+
// Gather all members here:
38+
let mut members: Vec<String> = vec![];
39+
40+
// Get class attributes:
41+
let mut base_classes = objtype::base_classes(obj);
42+
base_classes.reverse();
43+
for bc in base_classes {
44+
if let PyObjectKind::Class {
45+
name: _,
46+
dict,
47+
mro: _,
48+
} = &bc.borrow().kind
49+
{
50+
let elements = objdict::get_elements(dict);
51+
for (name, _value) in elements {
52+
members.push(name.to_string());
53+
}
54+
}
55+
}
56+
57+
// Get instance attributes:
58+
if let PyObjectKind::Instance { dict } = &obj.borrow().kind {
59+
let elements = objdict::get_elements(dict);
60+
for (name, _value) in elements {
61+
members.push(name.to_string());
62+
}
63+
}
64+
65+
// Sort members:
66+
members.sort();
67+
68+
let members_pystr = members.into_iter().map(|m| vm.ctx.new_str(m)).collect();
69+
vm.ctx.new_list(members_pystr)
4370
}
4471

4572
// builtin_abs
@@ -115,7 +142,7 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
115142
Ok(dir_locals(vm))
116143
} else {
117144
let obj = args.args.into_iter().next().unwrap();
118-
Ok(dir_object(vm, obj))
145+
Ok(dir_object(vm, &obj))
119146
}
120147
}
121148

vm/src/obj/objtype.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ fn _mro(cls: PyObjectRef) -> Option<Vec<PyObjectRef>> {
5454
}
5555
}
5656

57+
pub fn base_classes(obj: &PyObjectRef) -> Vec<PyObjectRef> {
58+
_mro(obj.typ()).unwrap()
59+
}
60+
5761
pub fn isinstance(obj: &PyObjectRef, cls: PyObjectRef) -> bool {
5862
let mro = _mro(obj.typ()).unwrap();
5963
mro.into_iter().any(|c| c.is(&cls))

0 commit comments

Comments
 (0)
0