Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013-2019 Damien P. George
7 : : * Copyright (c) 2014 Paul Sokolovsky
8 : : * Copyright (c) 2021 Jim Mussared
9 : : *
10 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
11 : : * of this software and associated documentation files (the "Software"), to deal
12 : : * in the Software without restriction, including without limitation the rights
13 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 : : * copies of the Software, and to permit persons to whom the Software is
15 : : * furnished to do so, subject to the following conditions:
16 : : *
17 : : * The above copyright notice and this permission notice shall be included in
18 : : * all copies or substantial portions of the Software.
19 : : *
20 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 : : * THE SOFTWARE.
27 : : */
28 : :
29 : : #include <stdio.h>
30 : : #include <string.h>
31 : : #include <assert.h>
32 : :
33 : : #include "py/compile.h"
34 : : #include "py/objmodule.h"
35 : : #include "py/persistentcode.h"
36 : : #include "py/runtime.h"
37 : : #include "py/builtin.h"
38 : : #include "py/frozenmod.h"
39 : :
40 : : #if MICROPY_DEBUG_VERBOSE // print debugging info
41 : : #define DEBUG_PRINT (1)
42 : : #define DEBUG_printf DEBUG_printf
43 : : #else // don't print debugging info
44 : : #define DEBUG_PRINT (0)
45 : : #define DEBUG_printf(...) (void)0
46 : : #endif
47 : :
48 : : #if MICROPY_MODULE_WEAK_LINKS
49 : 244 : STATIC qstr make_weak_link_name(vstr_t *buffer, qstr name) {
50 : 244 : vstr_reset(buffer);
51 : 244 : vstr_add_char(buffer, 'u');
52 : 244 : vstr_add_str(buffer, qstr_str(name));
53 : 244 : return qstr_from_strn(buffer->buf, buffer->len);
54 : : }
55 : : #endif
56 : :
57 : : #if MICROPY_ENABLE_EXTERNAL_IMPORT
58 : :
59 : : // Must be a string of one byte.
60 : : #define PATH_SEP_CHAR "/"
61 : :
62 : : // Virtual sys.path entry that maps to the frozen modules.
63 : : #define MP_FROZEN_PATH_PREFIX ".frozen/"
64 : :
65 : 1315 : bool mp_obj_is_package(mp_obj_t module) {
66 : 1315 : mp_obj_t dest[2];
67 : 1315 : mp_load_method_maybe(module, MP_QSTR___path__, dest);
68 : 1315 : return dest[0] != MP_OBJ_NULL;
69 : : }
70 : :
71 : : // Wrapper for mp_import_stat (which is provided by the port, and typically
72 : : // uses mp_vfs_import_stat) to also search frozen modules. Given an exact
73 : : // path to a file or directory (e.g. "foo/bar", foo/bar.py" or "foo/bar.mpy"),
74 : : // will return whether the path is a file, directory, or doesn't exist.
75 : 17698 : STATIC mp_import_stat_t stat_path_or_frozen(const char *path) {
76 : : #if MICROPY_MODULE_FROZEN
77 : : // Only try and load as a frozen module if it starts with .frozen/.
78 : 17698 : const int frozen_path_prefix_len = strlen(MP_FROZEN_PATH_PREFIX);
79 [ + + ]: 17698 : if (strncmp(path, MP_FROZEN_PATH_PREFIX, frozen_path_prefix_len) == 0) {
80 : 4501 : return mp_find_frozen_module(path + frozen_path_prefix_len, NULL, NULL);
81 : : }
82 : : #endif
83 : 13197 : return mp_import_stat(path);
84 : : }
85 : :
86 : : // Given a path to a .py file, try and find this path as either a .py or .mpy
87 : : // in either the filesystem or frozen modules.
88 : 5909 : STATIC mp_import_stat_t stat_file_py_or_mpy(vstr_t *path) {
89 : 5909 : mp_import_stat_t stat = stat_path_or_frozen(vstr_null_terminated_str(path));
90 [ + + ]: 5909 : if (stat == MP_IMPORT_STAT_FILE) {
91 : : return stat;
92 : : }
93 : :
94 : : #if MICROPY_PERSISTENT_CODE_LOAD
95 : : // Didn't find .py -- try the .mpy instead by inserting an 'm' into the '.py'.
96 : 5668 : vstr_ins_byte(path, path->len - 2, 'm');
97 : 5668 : stat = stat_path_or_frozen(vstr_null_terminated_str(path));
98 [ + + ]: 5668 : if (stat == MP_IMPORT_STAT_FILE) {
99 : 1331 : return stat;
100 : : }
101 : : #endif
102 : :
103 : : return MP_IMPORT_STAT_NO_EXIST;
104 : : }
105 : :
106 : : // Given an import path (e.g. "foo/bar"), try and find "foo/bar" (a directory)
107 : : // or "foo/bar.(m)py" in either the filesystem or frozen modules.
108 : 6121 : STATIC mp_import_stat_t stat_dir_or_file(vstr_t *path) {
109 : 6121 : mp_import_stat_t stat = stat_path_or_frozen(vstr_null_terminated_str(path));
110 : 6121 : DEBUG_printf("stat %s: %d\n", vstr_str(path), stat);
111 [ + + ]: 6121 : if (stat == MP_IMPORT_STAT_DIR) {
112 : : return stat;
113 : : }
114 : :
115 : : // not a directory, add .py and try as a file
116 : 5821 : vstr_add_str(path, ".py");
117 : 5821 : return stat_file_py_or_mpy(path);
118 : : }
119 : :
120 : : // Given a top-level module, try and find it in each of the sys.path entries
121 : : // via stat_dir_or_file.
122 : 2976 : STATIC mp_import_stat_t stat_top_level_dir_or_file(qstr mod_name, vstr_t *dest) {
123 : 2976 : DEBUG_printf("stat_top_level_dir_or_file: '%s'\n", qstr_str(mod_name));
124 : : #if MICROPY_PY_SYS
125 : 2976 : size_t path_num;
126 : 2976 : mp_obj_t *path_items;
127 : 2976 : mp_obj_list_get(mp_sys_path, &path_num, &path_items);
128 : :
129 [ + - ]: 2976 : if (path_num > 0) {
130 : : // go through each path looking for a directory or file
131 [ + + ]: 7307 : for (size_t i = 0; i < path_num; i++) {
132 : 5998 : vstr_reset(dest);
133 : 5998 : size_t p_len;
134 : 5998 : const char *p = mp_obj_str_get_data(path_items[i], &p_len);
135 [ + + ]: 5998 : if (p_len > 0) {
136 : 4355 : vstr_add_strn(dest, p, p_len);
137 : 4355 : vstr_add_char(dest, PATH_SEP_CHAR[0]);
138 : : }
139 : 5998 : vstr_add_str(dest, qstr_str(mod_name));
140 : 5998 : mp_import_stat_t stat = stat_dir_or_file(dest);
141 [ + + ]: 5998 : if (stat != MP_IMPORT_STAT_NO_EXIST) {
142 : 1667 : return stat;
143 : : }
144 : : }
145 : :
146 : : // could not find a directory or file
147 : : return MP_IMPORT_STAT_NO_EXIST;
148 : : }
149 : : #endif
150 : :
151 : : // mp_sys_path is empty (or not enabled), so just stat the given path
152 : : // directly.
153 : 0 : vstr_add_str(dest, qstr_str(mod_name));
154 : 0 : return stat_dir_or_file(dest);
155 : : }
156 : :
157 : : #if MICROPY_MODULE_FROZEN_STR || MICROPY_ENABLE_COMPILER
158 : 213 : STATIC void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) {
159 : : #if MICROPY_PY___FILE__
160 : 213 : qstr source_name = lex->source_name;
161 : 213 : mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
162 : : #endif
163 : :
164 : : // parse, compile and execute the module in its context
165 : 213 : mp_obj_dict_t *mod_globals = context->module.globals;
166 : 213 : mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mod_globals, mod_globals);
167 : 213 : }
168 : : #endif
169 : :
170 : : #if (MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD) || MICROPY_MODULE_FROZEN_MPY
171 : 1329 : STATIC void do_execute_raw_code(const mp_module_context_t *context, const mp_raw_code_t *rc, const char *source_name) {
172 : 1329 : (void)source_name;
173 : :
174 : : #if MICROPY_PY___FILE__
175 : 1329 : mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(qstr_from_str(source_name)));
176 : : #endif
177 : :
178 : : // execute the module in its context
179 : 1329 : mp_obj_dict_t *mod_globals = context->module.globals;
180 : :
181 : : // save context
182 : 1329 : mp_obj_dict_t *volatile old_globals = mp_globals_get();
183 : 1329 : mp_obj_dict_t *volatile old_locals = mp_locals_get();
184 : :
185 : : // set new context
186 : 1329 : mp_globals_set(mod_globals);
187 : 1329 : mp_locals_set(mod_globals);
188 : :
189 : 1329 : nlr_buf_t nlr;
190 [ + + ]: 1329 : if (nlr_push(&nlr) == 0) {
191 : 1329 : mp_obj_t module_fun = mp_make_function_from_raw_code(rc, context, NULL);
192 : 1329 : mp_call_function_0(module_fun);
193 : :
194 : : // finish nlr block, restore context
195 : 1323 : nlr_pop();
196 : 1323 : mp_globals_set(old_globals);
197 : 1323 : mp_locals_set(old_locals);
198 : : } else {
199 : : // exception; restore context and re-raise same exception
200 : 6 : mp_globals_set(old_globals);
201 : 6 : mp_locals_set(old_locals);
202 : 6 : nlr_jump(nlr.ret_val);
203 : : }
204 : 1323 : }
205 : : #endif
206 : :
207 : 1558 : STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) {
208 : : #if MICROPY_MODULE_FROZEN || MICROPY_ENABLE_COMPILER || (MICROPY_PERSISTENT_CODE_LOAD && MICROPY_HAS_FILE_READER)
209 : 1558 : const char *file_str = vstr_null_terminated_str(file);
210 : : #endif
211 : :
212 : : // If we support frozen modules (either as str or mpy) then try to find the
213 : : // requested filename in the list of frozen module filenames.
214 : : #if MICROPY_MODULE_FROZEN
215 : 1558 : void *modref;
216 : 1558 : int frozen_type;
217 : 1558 : const int frozen_path_prefix_len = strlen(MP_FROZEN_PATH_PREFIX);
218 [ + + ]: 1558 : if (strncmp(file_str, MP_FROZEN_PATH_PREFIX, frozen_path_prefix_len) == 0) {
219 : 20 : mp_find_frozen_module(file_str + frozen_path_prefix_len, &frozen_type, &modref);
220 : :
221 : : // If we support frozen str modules and the compiler is enabled, and we
222 : : // found the filename in the list of frozen files, then load and execute it.
223 : : #if MICROPY_MODULE_FROZEN_STR
224 [ + + ]: 20 : if (frozen_type == MP_FROZEN_STR) {
225 : 6 : do_load_from_lexer(module_obj, modref);
226 : 6 : return;
227 : : }
228 : : #endif
229 : :
230 : : // If we support frozen mpy modules and we found a corresponding file (and
231 : : // its data) in the list of frozen files, execute it.
232 : : #if MICROPY_MODULE_FROZEN_MPY
233 [ + - ]: 14 : if (frozen_type == MP_FROZEN_MPY) {
234 : 14 : const mp_frozen_module_t *frozen = modref;
235 : 14 : module_obj->constants = frozen->constants;
236 : 14 : do_execute_raw_code(module_obj, frozen->rc, file_str + frozen_path_prefix_len);
237 : 14 : return;
238 : : }
239 : : #endif
240 : : }
241 : :
242 : : #endif // MICROPY_MODULE_FROZEN
243 : :
244 : : // If we support loading .mpy files then check if the file extension is of
245 : : // the correct format and, if so, load and execute the file.
246 : : #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD
247 [ + + ]: 1538 : if (file_str[file->len - 3] == 'm') {
248 : 1331 : mp_compiled_module_t cm;
249 : 1331 : cm.context = module_obj;
250 : 1331 : mp_raw_code_load_file(file_str, &cm);
251 : 1315 : do_execute_raw_code(cm.context, cm.rc, file_str);
252 : 1311 : return;
253 : : }
254 : : #endif
255 : :
256 : : // If we can compile scripts then load the file and compile and execute it.
257 : : #if MICROPY_ENABLE_COMPILER
258 : : {
259 : 207 : mp_lexer_t *lex = mp_lexer_new_from_file(file_str);
260 : 207 : do_load_from_lexer(module_obj, lex);
261 : 207 : return;
262 : : }
263 : : #else
264 : : // If we get here then the file was not frozen and we can't compile scripts.
265 : : mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("script compilation not supported"));
266 : : #endif
267 : : }
268 : :
269 : : // Convert a relative (to the current module) import, going up "level" levels,
270 : : // into an absolute import.
271 : 106 : STATIC void evaluate_relative_import(mp_int_t level, const char **module_name, size_t *module_name_len) {
272 : : // What we want to do here is to take the name of the current module,
273 : : // remove <level> trailing components, and concatenate the passed-in
274 : : // module name.
275 : : // For example, level=3, module_name="foo.bar", __name__="a.b.c.d" --> "a.foo.bar"
276 : : // "Relative imports use a module's __name__ attribute to determine that
277 : : // module's position in the package hierarchy."
278 : : // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name
279 : :
280 : 106 : mp_obj_t current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___name__));
281 [ - + ]: 106 : assert(current_module_name_obj != MP_OBJ_NULL);
282 : :
283 : : #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT && MICROPY_CPYTHON_COMPAT
284 [ + + ]: 106 : if (MP_OBJ_QSTR_VALUE(current_module_name_obj) == MP_QSTR___main__) {
285 : : // This is a module loaded by -m command-line switch (e.g. unix port),
286 : : // and so its __name__ has been set to "__main__". Get its real name
287 : : // that we stored during import in the __main__ attribute.
288 : 2 : current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
289 : : }
290 : : #endif
291 : :
292 : : // If we have a __path__ in the globals dict, then we're a package.
293 : 104 : bool is_pkg = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP);
294 : :
295 : : #if DEBUG_PRINT
296 : : DEBUG_printf("Current module/package: ");
297 : : mp_obj_print_helper(MICROPY_DEBUG_PRINTER, current_module_name_obj, PRINT_REPR);
298 : : DEBUG_printf(", is_package: %d", is_pkg);
299 : : DEBUG_printf("\n");
300 : : #endif
301 : :
302 : 104 : size_t current_module_name_len;
303 : 104 : const char *current_module_name = mp_obj_str_get_data(current_module_name_obj, ¤t_module_name_len);
304 : :
305 : 104 : const char *p = current_module_name + current_module_name_len;
306 [ + + ]: 104 : if (is_pkg) {
307 : : // If we're evaluating relative to a package, then take off one fewer
308 : : // level (i.e. the relative search starts inside the package, rather
309 : : // than as a sibling of the package).
310 : 75 : --level;
311 : : }
312 : :
313 : : // Walk back 'level' dots (or run out of path).
314 [ + + ]: 387 : while (level && p > current_module_name) {
315 [ + + ]: 283 : if (*--p == '.') {
316 : 43 : --level;
317 : : }
318 : : }
319 : :
320 : : // We must have some component left over to import from.
321 [ + + ]: 104 : if (p == current_module_name) {
322 : 2 : mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("can't perform relative import"));
323 : : }
324 : :
325 : : // New length is len("<chopped path>.<module_name>"). Note: might be one byte
326 : : // more than we need if module_name is empty (for the extra . we will
327 : : // append).
328 : 102 : uint new_module_name_len = (size_t)(p - current_module_name) + 1 + *module_name_len;
329 : 102 : char *new_mod = mp_local_alloc(new_module_name_len);
330 : 102 : memcpy(new_mod, current_module_name, p - current_module_name);
331 : :
332 : : // Only append ".<module_name>" if there was one).
333 [ + + ]: 102 : if (*module_name_len != 0) {
334 : 79 : new_mod[p - current_module_name] = '.';
335 : 79 : memcpy(new_mod + (p - current_module_name) + 1, *module_name, *module_name_len);
336 : : } else {
337 : : --new_module_name_len;
338 : : }
339 : :
340 : : // Copy into a QSTR.
341 : 102 : qstr new_mod_q = qstr_from_strn(new_mod, new_module_name_len);
342 : 102 : mp_local_free(new_mod);
343 : :
344 : 102 : DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
345 : 102 : *module_name = qstr_str(new_mod_q);
346 : 102 : *module_name_len = new_module_name_len;
347 : 102 : }
348 : :
349 : : // Load a module at the specified absolute path, possibly as a submodule of the given outer module.
350 : : // full_mod_name: The full absolute path to this module (e.g. "foo.bar.baz").
351 : : // level_mod_name: The final component of the path (e.g. "baz").
352 : : // outer_module_obj: The parent module (we need to store this module as an
353 : : // attribute on it) (or MP_OBJ_NULL for top-level).
354 : : // path: The filesystem path where we found the parent module
355 : : // (or empty for a top level module).
356 : : // override_main: Whether to set the __name__ to "__main__" (and use __main__
357 : : // for the actual path).
358 : 3099 : STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, mp_obj_t outer_module_obj, vstr_t *path, bool override_main) {
359 : 3099 : mp_import_stat_t stat = MP_IMPORT_STAT_NO_EXIST;
360 : :
361 : : // Exact-match of built-in (or already-loaded) takes priority.
362 : 3099 : mp_obj_t module_obj = mp_module_get_loaded_or_builtin(full_mod_name);
363 : :
364 : : // Even if we find the module, go through the motions of searching for it
365 : : // because we may actually be in the process of importing a sub-module.
366 : : // So we need to (re-)find the correct path to be finding the sub-module
367 : : // on the next iteration of process_import_at_level.
368 : :
369 [ + + ]: 3099 : if (outer_module_obj == MP_OBJ_NULL) {
370 : 2976 : DEBUG_printf("Searching for top-level module\n");
371 : :
372 : : // First module in the dotted-name; search for a directory or file
373 : : // relative to all the locations in sys.path.
374 : 2976 : stat = stat_top_level_dir_or_file(full_mod_name, path);
375 : :
376 : : // If the module "foo" doesn't exist on the filesystem, and it's not a
377 : : // builtin, try and find "ufoo" as a built-in. (This feature was
378 : : // formerly known as "weak links").
379 : : #if MICROPY_MODULE_WEAK_LINKS
380 [ + + ]: 2976 : if (stat == MP_IMPORT_STAT_NO_EXIST && module_obj == MP_OBJ_NULL) {
381 : 244 : qstr umodule_name = make_weak_link_name(path, level_mod_name);
382 : 244 : module_obj = mp_module_get_builtin(umodule_name);
383 : : }
384 : : #elif MICROPY_PY_SYS
385 : : if (stat == MP_IMPORT_STAT_NO_EXIST && module_obj == MP_OBJ_NULL && level_mod_name == MP_QSTR_sys) {
386 : : module_obj = MP_OBJ_FROM_PTR(&mp_module_sys);
387 : : }
388 : : #endif
389 : : } else {
390 : 123 : DEBUG_printf("Searching for sub-module\n");
391 : :
392 : : // Add the current part of the module name to the path.
393 : 123 : vstr_add_char(path, PATH_SEP_CHAR[0]);
394 : 123 : vstr_add_str(path, qstr_str(level_mod_name));
395 : :
396 : : // Because it's not top level, we already know which path the parent was found in.
397 : 123 : stat = stat_dir_or_file(path);
398 : : }
399 : 3099 : DEBUG_printf("Current path: %.*s\n", (int)vstr_len(path), vstr_str(path));
400 : :
401 [ + + ]: 3099 : if (module_obj == MP_OBJ_NULL) {
402 : : // Not a built-in and not already-loaded.
403 : :
404 [ + + ]: 1584 : if (stat == MP_IMPORT_STAT_NO_EXIST) {
405 : : // And the file wasn't found -- fail.
406 : : #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
407 : : mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found"));
408 : : #else
409 : 20 : mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), full_mod_name);
410 : : #endif
411 : : }
412 : :
413 : : // Not a built-in but found on the filesystem, try and load it.
414 : :
415 : 1564 : DEBUG_printf("Found path: %.*s\n", (int)vstr_len(path), vstr_str(path));
416 : :
417 : : // Prepare for loading from the filesystem. Create a new shell module.
418 : 1564 : module_obj = mp_obj_new_module(full_mod_name);
419 : :
420 : : #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT
421 : : // If this module is being loaded via -m on unix, then
422 : : // override __name__ to "__main__". Do this only for *modules*
423 : : // however - packages never have their names replaced, instead
424 : : // they're -m'ed using a special __main__ submodule in them. (This all
425 : : // apparently is done to not touch the package name itself, which is
426 : : // important for future imports).
427 [ + + ]: 1564 : if (override_main && stat != MP_IMPORT_STAT_DIR) {
428 : 1303 : mp_obj_module_t *o = MP_OBJ_TO_PTR(module_obj);
429 : 1303 : mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
430 : : #if MICROPY_CPYTHON_COMPAT
431 : : // Store module as "__main__" in the dictionary of loaded modules (returned by sys.modules).
432 : 1303 : mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)), MP_OBJ_NEW_QSTR(MP_QSTR___main__), module_obj);
433 : : // Store real name in "__main__" attribute. Need this for
434 : : // resolving relative imports later. "__main__ was chosen
435 : : // semi-randonly, to reuse existing qstr's.
436 : 1303 : mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(full_mod_name));
437 : : #endif
438 : : }
439 : : #endif // MICROPY_MODULE_OVERRIDE_MAIN_IMPORT
440 : :
441 [ + + ]: 1564 : if (stat == MP_IMPORT_STAT_DIR) {
442 : : // Directory -- execute "path/__init__.py".
443 : 88 : DEBUG_printf("%.*s is dir\n", (int)vstr_len(path), vstr_str(path));
444 : : // Store the __path__ attribute onto this module.
445 : : // https://docs.python.org/3/reference/import.html
446 : : // "Specifically, any module that contains a __path__ attribute is considered a package."
447 : 88 : mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(path), vstr_len(path)));
448 : 88 : size_t orig_path_len = path->len;
449 : 88 : vstr_add_str(path, PATH_SEP_CHAR "__init__.py");
450 [ + + ]: 88 : if (stat_file_py_or_mpy(path) == MP_IMPORT_STAT_FILE) {
451 : 82 : do_load(MP_OBJ_TO_PTR(module_obj), path);
452 : : } else {
453 : : // No-op. Nothing to load.
454 : : // mp_warning("%s is imported as namespace package", vstr_str(&path));
455 : 88 : }
456 : : // Remove /__init__.py suffix.
457 : 88 : path->len = orig_path_len;
458 : : } else { // MP_IMPORT_STAT_FILE
459 : : // File -- execute "path.(m)py".
460 : 1476 : do_load(MP_OBJ_TO_PTR(module_obj), path);
461 : : // Note: This should be the last component in the import path. If
462 : : // there are remaining components then it's an ImportError
463 : : // because the current path(the module that was just loaded) is
464 : : // not a package. This will be caught on the next iteration
465 : : // because the file will not exist.
466 : : }
467 : : }
468 : :
469 [ + + ]: 3057 : if (outer_module_obj != MP_OBJ_NULL) {
470 : : // If it's a sub-module (not a built-in one), then make it available on
471 : : // the parent module.
472 : 123 : mp_store_attr(outer_module_obj, level_mod_name, module_obj);
473 : : }
474 : :
475 : 3057 : return module_obj;
476 : : }
477 : :
478 : 2992 : mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) {
479 : : #if DEBUG_PRINT
480 : : DEBUG_printf("__import__:\n");
481 : : for (size_t i = 0; i < n_args; i++) {
482 : : DEBUG_printf(" ");
483 : : mp_obj_print_helper(MICROPY_DEBUG_PRINTER, args[i], PRINT_REPR);
484 : : DEBUG_printf("\n");
485 : : }
486 : : #endif
487 : :
488 : : // This is the import path, with any leading dots stripped.
489 : : // "import foo.bar" --> module_name="foo.bar"
490 : : // "from foo.bar import baz" --> module_name="foo.bar"
491 : : // "from . import foo" --> module_name=""
492 : : // "from ...foo.bar import baz" --> module_name="foo.bar"
493 : 2992 : mp_obj_t module_name_obj = args[0];
494 : :
495 : : // These are the imported names.
496 : : // i.e. "from foo.bar import baz, zap" --> fromtuple=("baz", "zap",)
497 : : // Note: There's a special case on the Unix port, where this is set to mp_const_false which means that it's __main__.
498 : 2992 : mp_obj_t fromtuple = mp_const_none;
499 : :
500 : : // Level is the number of leading dots in a relative import.
501 : : // i.e. "from . import foo" --> level=1
502 : : // i.e. "from ...foo.bar import baz" --> level=3
503 : 2992 : mp_int_t level = 0;
504 : :
505 [ + + ]: 2992 : if (n_args >= 4) {
506 : 2944 : fromtuple = args[3];
507 [ + + ]: 2944 : if (n_args >= 5) {
508 : 1637 : level = MP_OBJ_SMALL_INT_VALUE(args[4]);
509 [ + + ]: 1637 : if (level < 0) {
510 : 2 : mp_raise_ValueError(NULL);
511 : : }
512 : : }
513 : : }
514 : :
515 : 2990 : size_t module_name_len;
516 : 2990 : const char *module_name = mp_obj_str_get_data(module_name_obj, &module_name_len);
517 : :
518 [ + + ]: 2988 : if (level != 0) {
519 : : // Turn "foo.bar" into "<current module minus 3 components>.foo.bar".
520 : 106 : evaluate_relative_import(level, &module_name, &module_name_len);
521 : : }
522 : :
523 [ + + ]: 2984 : if (module_name_len == 0) {
524 : 2 : mp_raise_ValueError(NULL);
525 : : }
526 : :
527 : 2982 : DEBUG_printf("Starting module search for '%s'\n", module_name);
528 : :
529 : 2982 : VSTR_FIXED(path, MICROPY_ALLOC_PATH_MAX)
530 : 2982 : mp_obj_t top_module_obj = MP_OBJ_NULL;
531 : 2982 : mp_obj_t outer_module_obj = MP_OBJ_NULL;
532 : :
533 : : // Search for the end of each component.
534 : 2982 : size_t current_component_start = 0;
535 [ + + ]: 30665 : for (size_t i = 1; i <= module_name_len; i++) {
536 [ + + + + ]: 27731 : if (i == module_name_len || module_name[i] == '.') {
537 : : // The module name up to this depth (e.g. foo.bar.baz).
538 : 3105 : qstr full_mod_name = qstr_from_strn(module_name, i);
539 : : // The current level name (e.g. baz).
540 : 3099 : qstr level_mod_name = qstr_from_strn(module_name + current_component_start, i - current_component_start);
541 : :
542 : 3099 : DEBUG_printf("Processing module: '%s' at level '%s'\n", qstr_str(full_mod_name), qstr_str(level_mod_name));
543 : 3099 : DEBUG_printf("Previous path: =%.*s=\n", (int)vstr_len(&path), vstr_str(&path));
544 : :
545 : : #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT
546 : : // On unix, if this is being loaded via -m (magic mp_const_false),
547 : : // then handle that if it's the final component.
548 [ + + + + ]: 3099 : bool override_main = (i == module_name_len && fromtuple == mp_const_false);
549 : : #else
550 : : bool override_main = false;
551 : : #endif
552 : :
553 : : // Import this module.
554 : 3099 : mp_obj_t module_obj = process_import_at_level(full_mod_name, level_mod_name, outer_module_obj, &path, override_main);
555 : :
556 : : // Set this as the parent module, and remember the top-level module if it's the first.
557 : 3057 : outer_module_obj = module_obj;
558 [ + + ]: 3057 : if (top_module_obj == MP_OBJ_NULL) {
559 : 2934 : top_module_obj = module_obj;
560 : : }
561 : :
562 : 3057 : current_component_start = i + 1;
563 : : }
564 : : }
565 : :
566 [ + + ]: 2934 : if (fromtuple != mp_const_none) {
567 : : // If fromtuple is not empty, return leaf module
568 : : return outer_module_obj;
569 : : } else {
570 : : // Otherwise, we need to return top-level package
571 : 1175 : return top_module_obj;
572 : : }
573 : : }
574 : :
575 : : #else // MICROPY_ENABLE_EXTERNAL_IMPORT
576 : :
577 : : bool mp_obj_is_package(mp_obj_t module) {
578 : : return false;
579 : : }
580 : :
581 : : mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) {
582 : : // Check that it's not a relative import
583 : : if (n_args >= 5 && MP_OBJ_SMALL_INT_VALUE(args[4]) != 0) {
584 : : mp_raise_NotImplementedError(MP_ERROR_TEXT("relative import"));
585 : : }
586 : :
587 : : // Check if module already exists, and return it if it does
588 : : qstr module_name_qstr = mp_obj_str_get_qstr(args[0]);
589 : : mp_obj_t module_obj = mp_module_get_loaded_or_builtin(module_name_qstr);
590 : : if (module_obj != MP_OBJ_NULL) {
591 : : return module_obj;
592 : : }
593 : :
594 : : #if MICROPY_MODULE_WEAK_LINKS
595 : : // Check if there is a weak link to this module
596 : : VSTR_FIXED(umodule_path, MICROPY_ALLOC_PATH_MAX);
597 : : qstr umodule_name_qstr = make_weak_link_name(&umodule_path, module_name_qstr);
598 : : module_obj = mp_module_get_loaded_or_builtin(umodule_name_qstr);
599 : : if (module_obj != MP_OBJ_NULL) {
600 : : return module_obj;
601 : : }
602 : : #endif
603 : :
604 : : // Couldn't find the module, so fail
605 : : #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
606 : : mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found"));
607 : : #else
608 : : mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), module_name_qstr);
609 : : #endif
610 : : }
611 : :
612 : : #endif // MICROPY_ENABLE_EXTERNAL_IMPORT
613 : :
614 : : MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin___import___obj, 1, 5, mp_builtin___import__);
|