Skip to content

Commit 664554b

Browse files
committed
Fix dir bug - not including object attributes correctly.
1 parent 7cf3135 commit 664554b

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

tests/snippets/builtin_dir.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ def test():
88
assert "test" in dir(a), "test not in a"
99
assert "test" in dir(A), "test not in A"
1010

11+
a.x = 3
12+
assert "x" in dir(a), "x not in a"
13+
1114
class B(A):
1215
def __dir__(self):
1316
return ('q', 'h')

vm/src/obj/objobject.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::objdict::PyDictRef;
22
use super::objlist::PyList;
3-
use super::objstr::PyStringRef;
3+
use super::objstr::{PyString, PyStringRef};
44
use super::objtype;
55
use crate::function::PyFuncArgs;
66
use crate::obj::objproperty::PropertyBuilder;
@@ -117,13 +117,29 @@ fn object_repr(zelf: PyObjectRef, _vm: &VirtualMachine) -> String {
117117
format!("<{} object at 0x{:x}>", zelf.class().name, zelf.get_id())
118118
}
119119

120-
pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyList {
121-
let attributes = get_attributes(&obj);
120+
pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyList> {
121+
let mut attributes: PyAttributes = objtype::get_attributes(obj.class());
122+
123+
// Get instance attributes:
124+
if let Some(dict) = &obj.dict {
125+
for (key, value) in dict {
126+
if let Some(key_string) = key.payload::<PyString>() {
127+
attributes.insert(key_string.to_string(), value.clone());
128+
} else {
129+
return Err(vm.new_type_error(format!(
130+
"Attribute is not a string: {:?}",
131+
vm.to_pystr(&key)?
132+
)));
133+
}
134+
}
135+
}
136+
122137
let attributes: Vec<PyObjectRef> = attributes
123138
.keys()
124139
.map(|k| vm.ctx.new_str(k.to_string()))
125140
.collect();
126-
PyList::from(attributes)
141+
142+
Ok(PyList::from(attributes))
127143
}
128144

129145
fn object_format(
@@ -230,17 +246,3 @@ fn object_getattr(
230246
Ok(None)
231247
}
232248
}
233-
234-
pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
235-
// Get class attributes:
236-
let mut attributes = objtype::get_attributes(obj.class());
237-
238-
// Get instance attributes:
239-
if let Some(dict) = &obj.dict {
240-
for (key, value) in dict {
241-
attributes.insert(key.to_string(), value.clone());
242-
}
243-
}
244-
245-
attributes
246-
}

0 commit comments

Comments
 (0)