summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2020-02-25 12:13:08 -0800
committerScott Shawcroft <scott@tannewt.org>2020-02-25 15:32:55 -0800
commit86fd93bd03d937713d4d23fa38ab359034c503c2 (patch)
treee0e2c873e39ae788bec6afae62aa5ea6f1548c29 /py
parent7037ebe0ecdbaedd108d284fb44492d56f2d0c50 (diff)
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.
Diffstat (limited to 'py')
-rw-r--r--py/builtinimport.c30
-rwxr-xr-xpy/gc_long_lived.c4
-rw-r--r--py/objmodule.c7
3 files changed, 30 insertions, 11 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 6ed0a7594..9edda18b3 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -400,21 +400,31 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
DEBUG_printf("Current path: %.*s\n", vstr_len(&path), vstr_str(&path));
if (stat == MP_IMPORT_STAT_NO_EXIST) {
- #if MICROPY_MODULE_WEAK_LINKS
- // check if there is a weak link to this module
- if (i == mod_len) {
- 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);
+ // This is just the module name after the previous .
+ qstr current_module_name = qstr_from_strn(mod_str + last, i - last);
+ mp_map_elem_t *el = NULL;
+ if (outer_module_obj == MP_OBJ_NULL) {
+ el = mp_map_lookup((mp_map_t*)&mp_builtin_module_map,
+ MP_OBJ_NEW_QSTR(current_module_name),
+ MP_MAP_LOOKUP);
+ #if MICROPY_MODULE_WEAK_LINKS
+ // check if there is a weak link to this module
if (el == NULL) {
- goto no_exist;
+ el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map,
+ MP_OBJ_NEW_QSTR(current_module_name),
+ MP_MAP_LOOKUP);
}
- // found weak linked module
+ #endif
+ } else {
+ el = mp_map_lookup(&((mp_obj_module_t*) outer_module_obj)->globals->map,
+ MP_OBJ_NEW_QSTR(current_module_name),
+ MP_MAP_LOOKUP);
+ }
+
+ if (el != NULL) {
module_obj = el->value;
mp_module_call_init(mod_name, module_obj);
} else {
- no_exist:
- #else
- {
- #endif
// couldn't find the file, so fail
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_ImportError(translate("module not found"));
diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c
index 01c22a7af..a2b5d88e0 100755
--- a/py/gc_long_lived.c
+++ b/py/gc_long_lived.c
@@ -85,11 +85,13 @@ mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max
return gc_make_long_lived(prop);
}
+extern const mp_obj_dict_t mcu_module_globals;
+
mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) {
#ifndef MICROPY_ENABLE_GC
return dict;
#endif
- if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main)) {
+ if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main) || dict->map.is_fixed) {
return dict;
}
// Don't recurse unnecessarily. Return immediately if we've already seen this dict.
diff --git a/py/objmodule.c b/py/objmodule.c
index 627ba79e8..c8b3a67a2 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -69,6 +69,13 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// delete/store attribute
mp_obj_dict_t *dict = self->globals;
if (dict->map.is_fixed) {
+ mp_map_elem_t *elem = mp_map_lookup(&dict->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
+ // Return success if the given value is already in the dictionary. This is the case for
+ // native packages with native submodules.
+ if (elem != NULL && elem->value == dest[1]) {
+ dest[0] = MP_OBJ_NULL; // indicate success
+ return;
+ } else
#if MICROPY_CAN_OVERRIDE_BUILTINS
if (dict == &mp_module_builtins_globals) {
if (MP_STATE_VM(mp_module_builtins_override_dict) == NULL) {