summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/builtinimport.c8
-rw-r--r--unix/main.c83
2 files changed, 73 insertions, 18 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 80c4c77f68..af93aace91 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -286,6 +286,14 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
module_obj = mp_obj_new_module(mod_name);
+ // if args[3] (fromtuple) has magic value False, set up
+ // this module for command-line "-m" option (set module's
+ // name to __main__ instead of real name).
+ if (i == mod_len && fromtuple == mp_const_false) {
+ mp_obj_module_t *o = module_obj;
+ mp_obj_dict_store(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
+ }
+
if (stat == MP_IMPORT_STAT_DIR) {
DEBUG_printf("%s is dir\n", vstr_str(&path));
// https://docs.python.org/3/reference/import.html
diff --git a/unix/main.c b/unix/main.c
index ca5dea99ac..7bfa96b273 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -47,6 +47,7 @@
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
+#include "builtin.h"
#include "repl.h"
#include "gc.h"
#include "genhdr/py-version.h"
@@ -83,8 +84,28 @@ STATIC void sighandler(int signum) {
#endif
#define FORCED_EXIT (0x100)
-// returns standard error codes: 0 for success, 1 for all other errors
-// if FORCED_EXIT bit is set then script raised SystemExit and the
+// If exc is SystemExit, return value where FORCED_EXIT bit set,
+// and lower 8 bits are SystemExit value. For all other exceptions,
+// return 1.
+STATIC int handle_uncaught_exception(mp_obj_t exc) {
+ // check for SystemExit
+ if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
+ // None is an exit value of 0; an int is its value; anything else is 1
+ mp_obj_t exit_val = mp_obj_exception_get_value(exc);
+ mp_int_t val = 0;
+ if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
+ val = 1;
+ }
+ return FORCED_EXIT | (val & 255);
+ }
+
+ // Report all other exceptions
+ mp_obj_print_exception(exc);
+ return 1;
+}
+
+// Returns standard error codes: 0 for success, 1 for all other errors,
+// except if FORCED_EXIT bit is set then script raised SystemExit and the
// value of the exit is in the lower 8 bits of the return value
STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
if (lex == NULL) {
@@ -160,19 +181,7 @@ STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind,
#ifndef _WIN32
sigaction(SIGINT, &sa, NULL);
#endif
- // check for SystemExit
- mp_obj_t exc = (mp_obj_t)nlr.ret_val;
- if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
- // None is an exit value of 0; an int is its value; anything else is 1
- mp_obj_t exit_val = mp_obj_exception_get_value(exc);
- mp_int_t val = 0;
- if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
- val = 1;
- }
- return FORCED_EXIT | (val & 255);
- }
- mp_obj_print_exception((mp_obj_t)nlr.ret_val);
- return 1;
+ return handle_uncaught_exception((mp_obj_t)nlr.ret_val);
}
}
@@ -320,6 +329,12 @@ void pre_process_options(int argc, char **argv) {
}
}
+void set_sys_argv(char *argv[], int argc, int start_arg) {
+ for (int i = start_arg; i < argc; i++) {
+ mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i])));
+ }
+}
+
#ifdef _WIN32
#define PATHLIST_SEP_CHAR ';'
#else
@@ -417,6 +432,40 @@ int main(int argc, char **argv) {
break;
}
a += 1;
+ } else if (strcmp(argv[a], "-m") == 0) {
+ if (a + 1 >= argc) {
+ return usage(argv);
+ }
+ mp_obj_t import_args[4];
+ import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]), false);
+ import_args[1] = import_args[2] = mp_const_none;
+ // Ask __import__ to handle imported module specially - set its __name__
+ // to __main__, and also return this leaf module, not top-level package
+ // containing it.
+ import_args[3] = mp_const_false;
+ // TODO: https://docs.python.org/3/using/cmdline.html#cmdoption-m :
+ // "the first element of sys.argv will be the full path to
+ // the module file (while the module file is being located,
+ // the first element will be set to "-m")."
+ set_sys_argv(argv, argc, a + 1);
+
+ mp_obj_t mod;
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ mod = mp_builtin___import__(MP_ARRAY_SIZE(import_args), import_args);
+ nlr_pop();
+ } else {
+ // uncaught exception
+ return handle_uncaught_exception((mp_obj_t)nlr.ret_val);
+ }
+
+ if (mp_obj_is_package(mod)) {
+ // TODO
+ fprintf(stderr, "%s: -m for packages not yet implemented\n", argv[0]);
+ exit(1);
+ }
+ ret = 0;
+ break;
} else if (strcmp(argv[a], "-X") == 0) {
a += 1;
} else if (strcmp(argv[a], "-v") == 0) {
@@ -447,9 +496,7 @@ int main(int argc, char **argv) {
path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir));
free(pathbuf);
- for (int i = a; i < argc; i++) {
- mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i])));
- }
+ set_sys_argv(argv, argc, a);
ret = do_file(argv[a]);
break;
}