summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/runtime.c44
-rw-r--r--tests/basics/import-pkg3.py6
2 files changed, 44 insertions, 6 deletions
diff --git a/py/runtime.c b/py/runtime.c
index 499905a0fa..4793f054a8 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -1043,13 +1043,45 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
mp_obj_t mp_import_from(mp_obj_t module, qstr name) {
DEBUG_printf("import from %p %s\n", module, qstr_str(name));
- mp_obj_t x = mp_load_attr(module, name);
- /* TODO convert AttributeError to ImportError
- if (fail) {
- (ImportError, "cannot import name %s", qstr_str(name), NULL)
+ mp_obj_t dest[2];
+
+ mp_load_method_maybe(module, name, dest);
+
+ if (dest[1] != MP_OBJ_NULL) {
+ // Hopefully we can't import bound method from an object
+import_error:
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "Cannot import name '%s'", qstr_str(name)));
+ }
+
+ if (dest[0] != MP_OBJ_NULL) {
+ return dest[0];
+ }
+
+ // See if it's a package, then can try FS import
+ mp_load_method_maybe(module, MP_QSTR___path__, dest);
+ if (dest[0] == MP_OBJ_NULL) {
+ goto import_error;
}
- */
- return x;
+
+ mp_load_method_maybe(module, MP_QSTR___name__, dest);
+ uint pkg_name_len;
+ const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
+
+ char dot_name[pkg_name_len + 1 + qstr_len(name)];
+ memcpy(dot_name, pkg_name, pkg_name_len);
+ dot_name[pkg_name_len] = '.';
+ memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
+ qstr dot_name_q = qstr_from_strn(dot_name, sizeof(dot_name));
+
+ mp_obj_t args[5];
+ args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
+ args[1] = mp_const_none; // TODO should be globals
+ args[2] = mp_const_none; // TODO should be locals
+ args[3] = mp_const_true; // Pass sentinel "non empty" value to force returning of leaf module
+ args[4] = 0;
+
+ // TODO lookup __import__ and call that instead of going straight to builtin implementation
+ return mp_builtin___import__(5, args);
}
void mp_import_all(mp_obj_t module) {
diff --git a/tests/basics/import-pkg3.py b/tests/basics/import-pkg3.py
new file mode 100644
index 0000000000..0ee885b220
--- /dev/null
+++ b/tests/basics/import-pkg3.py
@@ -0,0 +1,6 @@
+from pkg import mod
+
+print(mod.foo())
+
+import pkg.mod
+print(mod is pkg.mod)