Skip to content

Commit c14a816

Browse files
committed
py: Add module weak link support.
With this patch a port can enable module weak link support and provide a dict of qstr->module mapping. This mapping is looked up only if an import fails to find the requested module in the filesystem. This allows to have the builtin module named, eg, usocket, and provide a weak link of "socket" to the same module, but this weak link can be overridden if a file by the name "socket.py" is found in the import path.
1 parent 3c34d41 commit c14a816

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

py/builtinimport.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "runtime0.h"
4545
#include "runtime.h"
4646
#include "builtin.h"
47+
#include "builtintables.h"
4748

4849
#if 0 // print debugging info
4950
#define DEBUG_PRINT (1)
@@ -251,12 +252,29 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, mp_obj_t *args) {
251252
}
252253
DEBUG_printf("Current path: %s\n", vstr_str(&path));
253254

254-
// fail if we couldn't find the file
255255
if (stat == MP_IMPORT_STAT_NO_EXIST) {
256-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", qstr_str(mod_name)));
256+
#if MICROPY_MODULE_WEAK_LINKS
257+
// check if there is a weak link to this module
258+
if (i == mod_len) {
259+
mp_map_elem_t *el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_dict_obj.map, MP_OBJ_NEW_QSTR(mod_name), MP_MAP_LOOKUP);
260+
if (el == NULL) {
261+
goto no_exist;
262+
}
263+
// found weak linked module
264+
module_obj = el->value;
265+
} else {
266+
no_exist:
267+
#else
268+
{
269+
#endif
270+
// couldn't find the file, so fail
271+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", qstr_str(mod_name)));
272+
}
273+
} else {
274+
// found the file, so get the module
275+
module_obj = mp_module_get(mod_name);
257276
}
258277

259-
module_obj = mp_module_get(mod_name);
260278
if (module_obj == MP_OBJ_NULL) {
261279
// module not already loaded, so load it!
262280

py/builtintables.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,20 @@ const mp_obj_dict_t mp_builtin_module_dict_obj = {
227227
.table = (mp_map_elem_t*)mp_builtin_module_table,
228228
},
229229
};
230+
231+
#if MICROPY_MODULE_WEAK_LINKS
232+
STATIC const mp_map_elem_t mp_builtin_module_weak_links_table[] = {
233+
MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS
234+
};
235+
236+
const mp_obj_dict_t mp_builtin_module_weak_links_dict_obj = {
237+
.base = {&mp_type_dict},
238+
.map = {
239+
.all_keys_are_qstrs = 1,
240+
.table_is_fixed_array = 1,
241+
.used = MP_ARRAY_SIZE(mp_builtin_module_weak_links_table),
242+
.alloc = MP_ARRAY_SIZE(mp_builtin_module_weak_links_table),
243+
.table = (mp_map_elem_t*)mp_builtin_module_weak_links_table,
244+
},
245+
};
246+
#endif

py/builtintables.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@
2626

2727
extern const mp_obj_dict_t mp_builtin_object_dict_obj;
2828
extern const mp_obj_dict_t mp_builtin_module_dict_obj;
29+
30+
#if MICROPY_MODULE_WEAK_LINKS
31+
extern const mp_obj_dict_t mp_builtin_module_weak_links_dict_obj;
32+
#endif

py/mpconfig.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ typedef double mp_float_t;
269269
#define MICROPY_STREAMS_NON_BLOCK (0)
270270
#endif
271271

272+
// Whether module weak links are supported
273+
#ifndef MICROPY_MODULE_WEAK_LINKS
274+
#define MICROPY_MODULE_WEAK_LINKS (0)
275+
#endif
276+
272277
/*****************************************************************************/
273278
/* Fine control over Python builtins, classes, modules, etc */
274279

@@ -411,6 +416,11 @@ typedef double mp_float_t;
411416
#define MICROPY_PORT_BUILTIN_MODULES
412417
#endif
413418

419+
// Any module weak links - see builtintables.c:mp_builtin_module_weak_links_table.
420+
#ifndef MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS
421+
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS
422+
#endif
423+
414424
// Additional constant definitions for the compiler - see compile.c:mp_constants_table.
415425
#ifndef MICROPY_PORT_CONSTANTS
416426
#define MICROPY_PORT_CONSTANTS

0 commit comments

Comments
 (0)