Skip to content

Commit 2a874dc

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 0dd89c6 commit 2a874dc

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

py/builtinimport.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
354354
DEBUG_printf("Previous path: =%.*s=\n", (int)vstr_len(&path), vstr_str(&path));
355355

356356
mp_import_stat_t stat = MP_IMPORT_STAT_NO_EXIST;
357+
bool store_on_parent = true;
357358

358359
// Exact-match built-in (or already-loaded) takes priority.
359360
mp_obj_t module_obj = mp_module_get(mod_name);
@@ -377,7 +378,20 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
377378
} else {
378379
DEBUG_printf("Searching for sub-module\n");
379380

380-
// TODO: packages for built-ins?
381+
if (module_obj == MP_OBJ_NULL) {
382+
// See if the outer module has this module as an attr.
383+
// e.g. built-in modules can add modules to their globals dict
384+
// to provide something that behaves like built-in packages.
385+
mp_obj_t dest[2] = { MP_OBJ_NULL };
386+
mp_type_module.attr(outer_module_obj, qstr_from_strn(mod_str + last, i - last), dest);
387+
if (dest[0] != MP_OBJ_NULL) {
388+
// Ensure that it's actually a module.
389+
if (mp_obj_get_type(dest[0]) == &mp_type_module) {
390+
module_obj = dest[0];
391+
store_on_parent = false;
392+
}
393+
}
394+
}
381395

382396
// Add the current part of the module name to the path.
383397
// Again, need to do this even if already loaded (see find_file call above).
@@ -455,8 +469,8 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
455469
}
456470
}
457471

458-
if (outer_module_obj != MP_OBJ_NULL) {
459-
// If it's a sub-module, then make it available on
472+
if (store_on_parent && outer_module_obj != MP_OBJ_NULL) {
473+
// If it's a sub-module (not a built-in one), then make it available on
460474
// the parent module.
461475
qstr s = qstr_from_strn(mod_str + last, i - last);
462476
mp_store_attr(outer_module_obj, s, 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