Skip to content

Commit 3678a6b

Browse files
committed
py/modbuiltins: Make built-in dir support the __dir__ special method.
If MICROPY_PY_ALL_SPECIAL_METHODS is enabled then dir() will now delegate to the special method __dir__ if the object it is listing has this method.
1 parent 29d28c2 commit 3678a6b

3 files changed

Lines changed: 19 additions & 0 deletions

File tree

‎py/makeqstrdata.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ def parse_input_headers(infiles):
114114
if ident == "":
115115
# Sort empty qstr above all still
116116
order = -200000
117+
elif ident == "__dir__":
118+
# Put __dir__ after empty qstr for builtin dir() to work
119+
order = -190000
117120
elif ident.startswith("__"):
118121
order -= 100000
119122
qstrs[ident] = (order, ident, qstr)

‎py/modbuiltins.c‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ STATIC mp_obj_t mp_builtin_dir(size_t n_args, const mp_obj_t *args) {
190190
mp_obj_t dest[2];
191191
mp_load_method_protected(args[0], i, dest, false);
192192
if (dest[0] != MP_OBJ_NULL) {
193+
#if MICROPY_PY_ALL_SPECIAL_METHODS
194+
// Support for __dir__: see if we can dispatch to this special method
195+
// This relies on MP_QSTR__dir__ being first after MP_QSTR_
196+
if (i == MP_QSTR___dir__ && dest[1] != MP_OBJ_NULL) {
197+
return mp_call_method_n_kw(0, 0, dest);
198+
}
199+
#endif
193200
mp_obj_list_append(dir, MP_OBJ_NEW_QSTR(i));
194201
}
195202
}

‎tests/basics/special_methods2.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ def __isub__(self, other):
9494
print("__isub__ called")
9595
return self
9696

97+
def __dir__(self):
98+
return ['a', 'b', 'c']
99+
97100
cud1 = Cud()
98101
cud2 = Cud()
99102

@@ -113,6 +116,12 @@ def __isub__(self, other):
113116
cud1 += cud2
114117
cud1 -= cud2
115118

119+
# test that dir() delegates to __dir__ special method
120+
print(dir(cud1))
121+
122+
# test that dir() does not delegate to __dir__ for the type
123+
print('a' in dir(Cud))
124+
116125
# TODO: the following operations are not supported on every ports
117126
#
118127
# ne is not supported, !(eq) is called instead

0 commit comments

Comments
 (0)