py: Automatically provide weak links from "foo" to "ufoo" module name.
This commit implements automatic module weak links for all built-in
modules, by searching for "ufoo" in the built-in module list if "foo"
cannot be found. This means that all modules named "ufoo" are always
available as "foo". Also, a port can no longer add any other weak links,
which makes strict the definition of a weak link.
It saves some code size (about 100-200 bytes) on ports that previously had
lots of weak links.
Some changes from the previous behaviour:
- It doesn't intern the non-u module names (eg "foo" is not interned),
which saves code size, but will mean that "import foo" creates a new qstr
(namely "foo") in RAM (unless the importing module is frozen).
- help('modules') no longer lists non-u module names, only the u-variants;
this reduces duplication in the help listing.
Weak links are effectively the same as having a set of symbolic links on
the filesystem that is searched last. So an "import foo" will search
built-in modules first, then all paths in sys.path, then weak links last,
importing "ufoo" if it exists. Thus a file called "foo.py" somewhere in
sys.path will still have precedence over the weak link of "foo" to "ufoo".
See issues: #1740, #4449, #5229, #5241.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2013-2019 Damien P. George
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -381,21 +381,18 @@ 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) {
|
||||
module_obj = MP_OBJ_NULL;
|
||||
#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);
|
||||
if (el == NULL) {
|
||||
goto no_exist;
|
||||
module_obj = mp_module_search_umodule(mod_str);
|
||||
if (module_obj != MP_OBJ_NULL) {
|
||||
// found weak linked module
|
||||
mp_module_call_init(mod_name, module_obj);
|
||||
}
|
||||
// found weak linked module
|
||||
module_obj = el->value;
|
||||
mp_module_call_init(mod_name, module_obj);
|
||||
} else {
|
||||
no_exist:
|
||||
#else
|
||||
{
|
||||
}
|
||||
#endif
|
||||
if (module_obj == MP_OBJ_NULL) {
|
||||
// couldn't find the file, so fail
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_msg(&mp_type_ImportError, "module not found");
|
||||
@@ -492,11 +489,11 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
|
||||
|
||||
#if MICROPY_MODULE_WEAK_LINKS
|
||||
// Check if there is a weak link to this module
|
||||
mp_map_elem_t *el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map, MP_OBJ_NEW_QSTR(module_name_qstr), MP_MAP_LOOKUP);
|
||||
if (el != NULL) {
|
||||
module_obj = mp_module_search_umodule(qstr_str(module_name_qstr));
|
||||
if (module_obj != MP_OBJ_NULL) {
|
||||
// Found weak-linked module
|
||||
mp_module_call_init(module_name_qstr, el->value);
|
||||
return el->value;
|
||||
mp_module_call_init(module_name_qstr, module_obj);
|
||||
return module_obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user