Skip to content

Commit

Permalink
ports: Move '.frozen' to second entry in sys.path.
Browse files Browse the repository at this point in the history
In commit 86ce442 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 <damien@micropython.org>
  • Loading branch information
dpgeorge committed Dec 29, 2021
1 parent 028776d commit aac5a97
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 11 deletions.
11 changes: 5 additions & 6 deletions ports/unix/main.c
Expand Up @@ -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++;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion ports/unix/mpconfigport.h
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ports/unix/variants/minimal/mpconfigvariant.h
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ports/windows/mpconfigport.h
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion py/runtime.c
Expand Up @@ -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

Expand Down
16 changes: 16 additions & 0 deletions 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())
2 changes: 1 addition & 1 deletion tests/run-tests.py
Expand Up @@ -852,7 +852,7 @@ def main():

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)
Expand Down

0 comments on commit aac5a97

Please sign in to comment.