Skip to content

Commit 86fd93b

Browse files
committed
Support importing native modules in native packages.
This only fixes the `import` portion. It doesn't actually change reference behavior because modules within a package could already be referenced through the parent package even though an error should have been thrown.
1 parent 7037ebe commit 86fd93b

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

py/builtinimport.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,21 +400,31 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
400400
DEBUG_printf("Current path: %.*s\n", vstr_len(&path), vstr_str(&path));
401401

402402
if (stat == MP_IMPORT_STAT_NO_EXIST) {
403-
#if MICROPY_MODULE_WEAK_LINKS
404-
// check if there is a weak link to this module
405-
if (i == mod_len) {
406-
mp_map_elem_t *el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map, MP_OBJ_NEW_QSTR(mod_name), MP_MAP_LOOKUP);
403+
// This is just the module name after the previous .
404+
qstr current_module_name = qstr_from_strn(mod_str + last, i - last);
405+
mp_map_elem_t *el = NULL;
406+
if (outer_module_obj == MP_OBJ_NULL) {
407+
el = mp_map_lookup((mp_map_t*)&mp_builtin_module_map,
408+
MP_OBJ_NEW_QSTR(current_module_name),
409+
MP_MAP_LOOKUP);
410+
#if MICROPY_MODULE_WEAK_LINKS
411+
// check if there is a weak link to this module
407412
if (el == NULL) {
408-
goto no_exist;
413+
el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map,
414+
MP_OBJ_NEW_QSTR(current_module_name),
415+
MP_MAP_LOOKUP);
409416
}
410-
// found weak linked module
417+
#endif
418+
} else {
419+
el = mp_map_lookup(&((mp_obj_module_t*) outer_module_obj)->globals->map,
420+
MP_OBJ_NEW_QSTR(current_module_name),
421+
MP_MAP_LOOKUP);
422+
}
423+
424+
if (el != NULL) {
411425
module_obj = el->value;
412426
mp_module_call_init(mod_name, module_obj);
413427
} else {
414-
no_exist:
415-
#else
416-
{
417-
#endif
418428
// couldn't find the file, so fail
419429
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
420430
mp_raise_ImportError(translate("module not found"));

py/gc_long_lived.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max
8585
return gc_make_long_lived(prop);
8686
}
8787

88+
extern const mp_obj_dict_t mcu_module_globals;
89+
8890
mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) {
8991
#ifndef MICROPY_ENABLE_GC
9092
return dict;
9193
#endif
92-
if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main)) {
94+
if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main) || dict->map.is_fixed) {
9395
return dict;
9496
}
9597
// Don't recurse unnecessarily. Return immediately if we've already seen this dict.

py/objmodule.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
6969
// delete/store attribute
7070
mp_obj_dict_t *dict = self->globals;
7171
if (dict->map.is_fixed) {
72+
mp_map_elem_t *elem = mp_map_lookup(&dict->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
73+
// Return success if the given value is already in the dictionary. This is the case for
74+
// native packages with native submodules.
75+
if (elem != NULL && elem->value == dest[1]) {
76+
dest[0] = MP_OBJ_NULL; // indicate success
77+
return;
78+
} else
7279
#if MICROPY_CAN_OVERRIDE_BUILTINS
7380
if (dict == &mp_module_builtins_globals) {
7481
if (MP_STATE_VM(mp_module_builtins_override_dict) == NULL) {

0 commit comments

Comments
 (0)