Skip to content

Commit 6e7819e

Browse files
committed
py/objmodule: Factor common code for calling __init__ on builtin module.
1 parent 27fa988 commit 6e7819e

3 files changed

Lines changed: 27 additions & 24 deletions

File tree

py/builtinimport.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -389,19 +389,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
389389
}
390390
// found weak linked module
391391
module_obj = el->value;
392-
if (MICROPY_MODULE_BUILTIN_INIT) {
393-
// look for __init__ and call it if it exists
394-
// Note: this code doesn't work fully correctly because it allows the
395-
// __init__ function to be called twice if the module is imported by its
396-
// non-weak-link name. Also, this code is duplicated in objmodule.c.
397-
mp_obj_t dest[2];
398-
mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
399-
if (dest[0] != MP_OBJ_NULL) {
400-
mp_call_method_n_kw(0, 0, dest);
401-
// register module so __init__ is not called again
402-
mp_module_register(mod_name, el->value);
403-
}
404-
}
392+
mp_module_call_init(mod_name, module_obj);
405393
} else {
406394
no_exist:
407395
#else

py/objmodule.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,7 @@ mp_obj_t mp_module_get(qstr module_name) {
247247
if (el == NULL) {
248248
return MP_OBJ_NULL;
249249
}
250-
251-
if (MICROPY_MODULE_BUILTIN_INIT) {
252-
// look for __init__ and call it if it exists
253-
mp_obj_t dest[2];
254-
mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
255-
if (dest[0] != MP_OBJ_NULL) {
256-
mp_call_method_n_kw(0, 0, dest);
257-
// register module so __init__ is not called again
258-
mp_module_register(module_name, el->value);
259-
}
260-
}
250+
mp_module_call_init(module_name, el->value);
261251
}
262252

263253
// module found, return it
@@ -268,3 +258,19 @@ void mp_module_register(qstr qst, mp_obj_t module) {
268258
mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
269259
mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module;
270260
}
261+
262+
#if MICROPY_MODULE_BUILTIN_INIT
263+
void mp_module_call_init(qstr module_name, mp_obj_t module_obj) {
264+
// Look for __init__ and call it if it exists
265+
mp_obj_t dest[2];
266+
mp_load_method_maybe(module_obj, MP_QSTR___init__, dest);
267+
if (dest[0] != MP_OBJ_NULL) {
268+
mp_call_method_n_kw(0, 0, dest);
269+
// Register module so __init__ is not called again.
270+
// If a module can be referenced by more than one name (eg due to weak links)
271+
// then __init__ will still be called for each distinct import, and it's then
272+
// up to the particular module to make sure it's __init__ code only runs once.
273+
mp_module_register(module_name, module_obj);
274+
}
275+
}
276+
#endif

py/objmodule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,13 @@ extern const mp_map_t mp_builtin_module_weak_links_map;
3434
mp_obj_t mp_module_get(qstr module_name);
3535
void mp_module_register(qstr qstr, mp_obj_t module);
3636

37+
#if MICROPY_MODULE_BUILTIN_INIT
38+
void mp_module_call_init(qstr module_name, mp_obj_t module_obj);
39+
#else
40+
static inline void mp_module_call_init(qstr module_name, mp_obj_t module_obj) {
41+
(void)module_name;
42+
(void)module_obj;
43+
}
44+
#endif
45+
3746
#endif // MICROPY_INCLUDED_PY_OBJMODULE_H

0 commit comments

Comments
 (0)