ports/sh: make filesystem imports relative to current file
This commit is contained in:
parent
5b52671c50
commit
61b2360b16
|
@ -22,6 +22,10 @@ extern const struct _mp_print_t mp_debug_print;
|
|||
#define MICROPY_DEBUG_PRINTER (&mp_debug_print)
|
||||
#endif
|
||||
|
||||
/* Custom option to use relative imports. For instance when working at the fs
|
||||
root, 'import b' in '/folder/a.py' will import 'folder/b.py' not '/b.py'. */
|
||||
#define MICROPY_RELATIVE_FILE_IMPORTS (1)
|
||||
|
||||
/* General feature set selection
|
||||
Other options: BASIC_FEATURES, EXTRA_FEATURES, FULL_FEATURES, EVERYTHING */
|
||||
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES)
|
||||
|
|
|
@ -444,6 +444,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
|
|||
} else {
|
||||
// No-op. Nothing to load.
|
||||
// mp_warning("%s is imported as namespace package", vstr_str(&path));
|
||||
DEBUG_printf("%s is imported as namespace package\n", vstr_str(path));
|
||||
}
|
||||
// Remove /__init__.py suffix.
|
||||
path->len = orig_path_len;
|
||||
|
@ -522,6 +523,23 @@ mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) {
|
|||
mp_obj_t top_module_obj = MP_OBJ_NULL;
|
||||
mp_obj_t outer_module_obj = MP_OBJ_NULL;
|
||||
|
||||
#if MICROPY_RELATIVE_FILE_IMPORTS
|
||||
size_t is_len;
|
||||
mp_obj_t *is_items;
|
||||
mp_obj_list_get(MP_STATE_VM(mp_import_stack), &is_len, &is_items);
|
||||
if(is_len > 0) {
|
||||
// Start next to last import
|
||||
char const *prev = qstr_str(MP_OBJ_QSTR_VALUE(is_items[is_len - 1]));
|
||||
char const *slash = strchr(prev, '/');
|
||||
int prev_len = (slash ? slash : prev) - prev;
|
||||
vstr_add_strn(&path, prev, prev_len);
|
||||
outer_module_obj = mp_obj_new_module(MP_QSTR___blankmodule);
|
||||
mp_store_attr(outer_module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path)));
|
||||
DEBUG_printf("last import was '%s'\n", prev);
|
||||
DEBUG_printf("starting in '%.*s'\n", (int)vstr_len(&path), vstr_str(&path));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Search for the end of each component.
|
||||
size_t current_component_start = 0;
|
||||
for (size_t i = 1; i <= module_name_len; i++) {
|
||||
|
|
|
@ -176,6 +176,11 @@ typedef struct _mp_state_vm_t {
|
|||
mp_obj_dict_t *mp_module_builtins_override_dict;
|
||||
#endif
|
||||
|
||||
// list (stack) of nested imports for relative import resolution
|
||||
#if MICROPY_RELATIVE_FILE_IMPORTS
|
||||
mp_obj_t mp_import_stack;
|
||||
#endif
|
||||
|
||||
// Include any root pointers registered with MP_REGISTER_ROOT_POINTER().
|
||||
#ifndef NO_QSTR
|
||||
// Only include root pointer definitions when not doing qstr extraction, because
|
||||
|
|
1
py/obj.h
1
py/obj.h
|
@ -1116,6 +1116,7 @@ mp_int_t mp_obj_tuple_hash(mp_obj_t self_in);
|
|||
// list
|
||||
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg);
|
||||
mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value);
|
||||
mp_obj_t mp_obj_list_pop(mp_obj_t self_in, mp_obj_t index);
|
||||
void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items);
|
||||
void mp_obj_list_set_len(mp_obj_t self_in, size_t len);
|
||||
void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
|
||||
|
|
|
@ -290,6 +290,12 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_list_pop(mp_obj_t self_in, mp_obj_t index)
|
||||
{
|
||||
mp_obj_t args[] = {self_in, index};
|
||||
return list_pop(2, args);
|
||||
}
|
||||
|
||||
STATIC void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, mp_obj_t binop_less_result) {
|
||||
MP_STACK_CHECK();
|
||||
while (head < tail) {
|
||||
|
|
39
py/runtime.c
39
py/runtime.c
|
@ -119,6 +119,10 @@ void mp_init(void) {
|
|||
MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
|
||||
#endif
|
||||
|
||||
#if MICROPY_RELATIVE_FILE_IMPORTS
|
||||
MP_STATE_VM(mp_import_stack) = mp_obj_new_list(0, NULL);
|
||||
#endif
|
||||
|
||||
#if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
|
||||
MP_STATE_VM(track_reloc_code_list) = MP_OBJ_NULL;
|
||||
#endif
|
||||
|
@ -1585,13 +1589,28 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i
|
|||
mp_globals_set(globals);
|
||||
mp_locals_set(locals);
|
||||
|
||||
#if MICROPY_RELATIVE_FILE_IMPORTS
|
||||
char const *volatile name = qstr_str(lex->source_name);
|
||||
(void)name;
|
||||
if (parse_input_kind == MP_PARSE_FILE_INPUT) {
|
||||
mp_obj_list_append(MP_STATE_VM(mp_import_stack), MP_OBJ_NEW_QSTR(lex->source_name));
|
||||
#if DEBUG_PRINT
|
||||
DEBUG_printf("pushing import: ", name);
|
||||
mp_obj_print_helper(MICROPY_DEBUG_PRINTER, MP_STATE_VM(mp_import_stack), PRINT_REPR);
|
||||
DEBUG_printf("\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
nlr_buf_t nlr;
|
||||
bool volatile failed = false;
|
||||
mp_obj_t volatile ret;
|
||||
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, parse_input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, parse_input_kind == MP_PARSE_SINGLE_INPUT);
|
||||
|
||||
mp_obj_t ret;
|
||||
if (MICROPY_PY_BUILTINS_COMPILE && globals == NULL) {
|
||||
// for compile only, return value is the module function
|
||||
ret = module_fun;
|
||||
|
@ -1604,13 +1623,27 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i
|
|||
nlr_pop();
|
||||
mp_globals_set(old_globals);
|
||||
mp_locals_set(old_locals);
|
||||
return ret;
|
||||
} else {
|
||||
// exception; restore context and re-raise same exception
|
||||
mp_globals_set(old_globals);
|
||||
mp_locals_set(old_locals);
|
||||
nlr_jump(nlr.ret_val);
|
||||
failed = true;
|
||||
}
|
||||
|
||||
#if MICROPY_RELATIVE_FILE_IMPORTS
|
||||
if (parse_input_kind == MP_PARSE_FILE_INPUT) {
|
||||
mp_obj_list_pop(MP_STATE_VM(mp_import_stack), MP_OBJ_NEW_SMALL_INT(-1));
|
||||
#if DEBUG_PRINT
|
||||
DEBUG_printf("popping import: ", name);
|
||||
mp_obj_print_helper(MICROPY_DEBUG_PRINTER, MP_STATE_VM(mp_import_stack), PRINT_REPR);
|
||||
DEBUG_printf("\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if(failed)
|
||||
nlr_jump(nlr.ret_val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // MICROPY_ENABLE_COMPILER
|
||||
|
|
Loading…
Reference in New Issue