Skip to content

Commit f51a9f6

Browse files
committed
py/builtinimport.c: Add support for built-in packages.
Allows a built-in module to add a sub-module as a member of its globals dict, and allow importing it as "import foo.bar" (or any other variation on the import statement). Note: This does give the slightly surprising behavior that "import foo" followed by "foo.bar.x" will also work. +56 bytes on PYBV11.
1 parent b5ebfb8 commit f51a9f6

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

py/builtinimport.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ STATIC void evaluate_relative_import(mp_int_t level, size_t *mod_len, const char
315315

316316
STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, mp_obj_t outer_module_obj, vstr_t *path, bool override_main) {
317317
mp_import_stat_t stat = MP_IMPORT_STAT_NO_EXIST;
318+
bool store_on_parent = true;
318319

319320
// Exact-match built-in (or already-loaded) takes priority.
320321
mp_obj_t module_obj = mp_module_get_loaded_or_builtin(full_mod_name);
@@ -346,6 +347,21 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
346347
} else {
347348
DEBUG_printf("Searching for sub-module\n");
348349

350+
if (module_obj == MP_OBJ_NULL) {
351+
// See if the outer module has this module as an attr.
352+
// e.g. built-in modules can add modules to their globals dict
353+
// to provide something that behaves like built-in packages.
354+
mp_obj_t dest[2] = { MP_OBJ_NULL };
355+
mp_type_module.attr(outer_module_obj, level_mod_name, dest);
356+
if (dest[0] != MP_OBJ_NULL) {
357+
// Ensure that it's actually a module.
358+
if (mp_obj_get_type(dest[0]) == &mp_type_module) {
359+
module_obj = dest[0];
360+
store_on_parent = false;
361+
}
362+
}
363+
}
364+
349365
// Add the current part of the module name to the path.
350366
vstr_add_char(path, PATH_SEP_CHAR[0]);
351367
vstr_add_str(path, qstr_str(level_mod_name));
@@ -418,7 +434,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
418434
}
419435
}
420436

421-
if (outer_module_obj != MP_OBJ_NULL) {
437+
if (store_on_parent && outer_module_obj != MP_OBJ_NULL) {
422438
// If it's a sub-module (not a built-in one), then make it available on
423439
// the parent module.
424440
mp_store_attr(outer_module_obj, level_mod_name, module_obj);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy