From aac5a97d08f9f28b7c3f170d007be0b538349937 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 21 Dec 2021 23:07:00 +1100 Subject: [PATCH] ports: Move '.frozen' to second entry in sys.path. In commit 86ce4426079b1b368881c22f46d80045e2f720b0 the '.frozen' entry was added at the start of sys.path, to allow control over when frozen modules are searched during import, and retain existing behaviour whereby frozen was searched before the filesystem. But Python semantics of sys.path require sys.path[0] to be the directory of the currently executing script, or ''. This commit moves the '.frozen' entry to second place in sys.path, so sys.path[0] retains its correct value (described above). Signed-off-by: Damien George --- ports/unix/main.c | 11 +++++------ ports/unix/mpconfigport.h | 2 +- ports/unix/variants/minimal/mpconfigvariant.h | 2 +- ports/windows/mpconfigport.h | 2 +- py/runtime.c | 2 +- tests/basics/sys_path.py | 16 ++++++++++++++++ tests/run-tests.py | 2 +- 7 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 tests/basics/sys_path.py diff --git a/ports/unix/main.c b/ports/unix/main.c index cecb806283..b2790791af 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -497,7 +497,7 @@ MP_NOINLINE int main_(int argc, char **argv) { if (path == NULL) { path = MICROPY_PY_SYS_PATH_DEFAULT; } - size_t path_num = 2; // [0] is frozen, [1] is for current dir (or base dir of the script) + size_t path_num = 1; // [0] is for current dir (or base dir of the script) if (*path == PATHLIST_SEP_CHAR) { path_num++; } @@ -510,11 +510,10 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); - path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen); - path_items[1] = MP_OBJ_NEW_QSTR(MP_QSTR_); + path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); { char *p = path; - for (mp_uint_t i = 2; i < path_num; i++) { + for (mp_uint_t i = 1; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); @@ -655,9 +654,9 @@ MP_NOINLINE int main_(int argc, char **argv) { break; } - // Set base dir of the script as second entry in sys.path. + // Set base dir of the script as first entry in sys.path. char *p = strrchr(basedir, '/'); - path_items[1] = mp_obj_new_str_via_qstr(basedir, p - basedir); + path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir); free(pathbuf); set_sys_argv(argv, argc, a); diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index a995ac52cc..658cb680f1 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -125,7 +125,7 @@ #endif #endif #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 4766b8e895..e0db3756ca 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -89,7 +89,7 @@ #define MICROPY_PY_SYS_EXIT (0) #define MICROPY_PY_SYS_PLATFORM "linux" #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib:/usr/lib/micropython" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif #define MICROPY_PY_SYS_MAXSIZE (0) #define MICROPY_PY_SYS_STDFILES (0) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index 30d8e09e6d..f22af9b7fc 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -90,7 +90,7 @@ #define MICROPY_PY_SYS_ATEXIT (1) #define MICROPY_PY_SYS_PLATFORM "win32" #ifndef MICROPY_PY_SYS_PATH_DEFAULT -#define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib" +#define MICROPY_PY_SYS_PATH_DEFAULT ".frozen;~/.micropython/lib" #endif #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) diff --git a/py/runtime.c b/py/runtime.c index 7607ffb191..8c93f539e0 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -124,10 +124,10 @@ void mp_init(void) { #if MICROPY_PY_SYS_PATH_ARGV_DEFAULTS mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) #if MICROPY_MODULE_FROZEN mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); #endif - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #endif diff --git a/tests/basics/sys_path.py b/tests/basics/sys_path.py new file mode 100644 index 0000000000..6456e24019 --- /dev/null +++ b/tests/basics/sys_path.py @@ -0,0 +1,16 @@ +# test sys.path + +try: + import usys as sys +except ImportError: + import sys + +# check that this script was executed from a file of the same name +if "__file__" not in globals() or "sys_path.py" not in __file__: + print("SKIP") + raise SystemExit + +# test that sys.path[0] is the directory containing this script +with open(sys.path[0] + "/sys_path.py") as f: + for _ in range(4): + print(f.readline()) diff --git a/tests/run-tests.py b/tests/run-tests.py index a8a31c0ae5..6f3c09d1da 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -852,7 +852,7 @@ the last matching regex is used: if not args.keep_path: # clear search path to make sure tests use only builtin modules and those in extmod - os.environ["MICROPYPATH"] = os.pathsep + base_path("../extmod") + os.environ["MICROPYPATH"] = ".frozen" + os.pathsep + base_path("../extmod") try: os.makedirs(args.result_dir, exist_ok=True)