py/builtinimport: Allow builtin modules to be packages.
To use this: - Create a built-in module, and add the module object as a member of the parent module's globals dict. - The submodule can set its `__name__` to either `QSTR_foo_dot_bar` or `QSTR_bar`. The former requires using qstrdefs(port).h to make the qstr. Because `bar` is a member of `foo`'s globals, it is possible to write `import foo` and then immediately use `foo.bar` without importing it explicitly. This means that if `bar` has an `__init__`, it will not be called in this situation, and for that reason, sub-modules should not have `__init__` methods. If this is required, then all initalisation for sub-modules should be done by the top-level module's (i.e. `foo`'s) `__init__` method. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
committed by
Damien George
parent
525557738c
commit
ed90f30dd5
@@ -428,6 +428,20 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
|
||||
} else {
|
||||
DEBUG_printf("Searching for sub-module\n");
|
||||
|
||||
#if MICROPY_MODULE_BUILTIN_SUBPACKAGES
|
||||
// If the outer module is a built-in (because its map is in ROM), then
|
||||
// treat it like a package if it contains this submodule in its
|
||||
// globals dict.
|
||||
mp_obj_module_t *mod = MP_OBJ_TO_PTR(outer_module_obj);
|
||||
if (mod->globals->map.is_fixed) {
|
||||
elem = mp_map_lookup(&mod->globals->map, MP_OBJ_NEW_QSTR(level_mod_name), MP_MAP_LOOKUP);
|
||||
// Also verify that the entry in the globals dict is in fact a module.
|
||||
if (elem && mp_obj_is_type(elem->value, &mp_type_module)) {
|
||||
return elem->value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the outer module is a package, it will have __path__ set.
|
||||
// We can use that as the path to search inside.
|
||||
mp_obj_t dest[2];
|
||||
|
||||
Reference in New Issue
Block a user