summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-02-16 02:53:44 +0200
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-02-16 02:55:46 +0200
commit91ba7a54c51958a584f3dd404be7d62b5ec0bbd9 (patch)
tree34718604429cf95062c24ce4b9c7c72d1c55968d
parentd3783570a4a8fb5c287ece1951215aa32c32204e (diff)
downloadmicropython-91ba7a54c51958a584f3dd404be7d62b5ec0bbd9.tar.gz
micropython-91ba7a54c51958a584f3dd404be7d62b5ec0bbd9.zip
builtinimport: Get the basic (and only basic) package imports work.
-rw-r--r--py/builtinimport.c35
-rw-r--r--tests/basics/import-pkg1.py11
-rw-r--r--tests/basics/pkg/__init__.py0
-rw-r--r--tests/basics/pkg/mod.py2
4 files changed, 41 insertions, 7 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c
index ae03f8c523..0a730b031c 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -139,18 +139,28 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
}
*/
+ uint mod_len;
+ const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len);
+
// check if module already exists
mp_obj_t module_obj = mp_obj_module_get(mp_obj_str_get_qstr(args[0]));
if (module_obj != MP_OBJ_NULL) {
- return module_obj;
+ // If it's not a package, return module right away
+ char *p = strchr(mod_str, '.');
+ if (p == NULL) {
+ return module_obj;
+ }
+ // Otherwise, we need to return top-level package
+ // TODO: subject to fromlist arg
+ qstr pkg_name = qstr_from_strn(mod_str, p - mod_str);
+ return mp_obj_module_get(pkg_name);
}
- uint mod_len;
- const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len);
-
uint last = 0;
VSTR_FIXED(path, MICROPY_PATH_MAX)
module_obj = MP_OBJ_NULL;
+ mp_obj_t top_module_obj = MP_OBJ_NULL;
+ mp_obj_t outer_module_obj = MP_OBJ_NULL;
uint i;
for (i = 1; i <= mod_len; i++) {
if (i == mod_len || mod_str[i] == '.') {
@@ -168,7 +178,6 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
vstr_add_strn(&path, mod_str + last, i - last);
stat = stat_dir_or_file(&path);
}
- last = i + 1;
// fail if we couldn't find the file
if (stat == MP_IMPORT_STAT_NO_EXIST) {
@@ -194,9 +203,21 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
vstr_cut_tail(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py
} else { // MP_IMPORT_STAT_FILE
do_load(module_obj, &path);
- break;
+ // TODO: We cannot just break here, at the very least, we must execute
+ // trailer code below. But otherwise if there're remaining components,
+ // that would be (??) object path within module, not modules path within FS.
+ // break;
}
}
+ if (outer_module_obj != MP_OBJ_NULL) {
+ qstr s = qstr_from_strn(mod_str + last, i - last);
+ rt_store_attr(outer_module_obj, s, module_obj);
+ }
+ outer_module_obj = module_obj;
+ if (top_module_obj == MP_OBJ_NULL) {
+ top_module_obj = module_obj;
+ }
+ last = i + 1;
}
}
@@ -206,7 +227,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
assert(0);
}
- return module_obj;
+ return top_module_obj;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin___import___obj, 1, 5, mp_builtin___import__);
diff --git a/tests/basics/import-pkg1.py b/tests/basics/import-pkg1.py
new file mode 100644
index 0000000000..8cd77af79d
--- /dev/null
+++ b/tests/basics/import-pkg1.py
@@ -0,0 +1,11 @@
+import pkg.mod
+
+print(pkg.__name__)
+print(pkg.mod.__name__)
+print(pkg.mod.foo())
+
+# Import 2nd time, must be same module objects
+pkg_ = __import__("pkg.mod")
+print(pkg_ is not pkg.mod)
+print(pkg_ is pkg)
+print(pkg_.mod is pkg.mod)
diff --git a/tests/basics/pkg/__init__.py b/tests/basics/pkg/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/basics/pkg/__init__.py
diff --git a/tests/basics/pkg/mod.py b/tests/basics/pkg/mod.py
new file mode 100644
index 0000000000..9e67bdd291
--- /dev/null
+++ b/tests/basics/pkg/mod.py
@@ -0,0 +1,2 @@
+def foo():
+ return 42