py/compile: Disallow 'import *' outside module level.
This check follows CPython's behaviour, because 'import *' always populates the globals with the imported names, not locals. Since it's safe to do this (doesn't lead to a crash or undefined behaviour) the check is only enabled for MICROPY_CPYTHON_COMPAT. Fixes issue #5121.
This commit is contained in:
parent
26e90a0514
commit
25a9bccdee
|
@ -1196,6 +1196,13 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||
} while (0);
|
||||
|
||||
if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (comp->scope_cur->kind != SCOPE_MODULE) {
|
||||
compile_syntax_error(comp, (mp_parse_node_t)pns, "import * not at module level");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
EMIT_ARG(load_const_small_int, import_level);
|
||||
|
||||
// build the "fromlist" tuple
|
||||
|
|
|
@ -115,7 +115,7 @@ def f():
|
|||
# import
|
||||
import a
|
||||
from a import b
|
||||
from a import *
|
||||
#from sys import * # tested at module scope
|
||||
|
||||
# raise
|
||||
raise
|
||||
|
@ -154,3 +154,6 @@ del Class
|
|||
# load super method
|
||||
def f(self):
|
||||
super().f()
|
||||
|
||||
# import * (needs to be in module scope)
|
||||
from sys import *
|
||||
|
|
|
@ -7,7 +7,7 @@ arg names:
|
|||
(N_EXC_STACK 0)
|
||||
bc=0 line=1
|
||||
########
|
||||
bc=\\d\+ line=155
|
||||
bc=\\d\+ line=159
|
||||
00 MAKE_FUNCTION \.\+
|
||||
\\d\+ STORE_NAME f
|
||||
\\d\+ MAKE_FUNCTION \.\+
|
||||
|
@ -27,6 +27,11 @@ arg names:
|
|||
\\d\+ DELETE_NAME Class
|
||||
\\d\+ MAKE_FUNCTION \.\+
|
||||
\\d\+ STORE_NAME f
|
||||
\\d\+ LOAD_CONST_SMALL_INT 0
|
||||
\\d\+ LOAD_CONST_STRING '*'
|
||||
\\d\+ BUILD_TUPLE 1
|
||||
\\d\+ IMPORT_NAME 'sys'
|
||||
\\d\+ IMPORT_STAR
|
||||
\\d\+ LOAD_CONST_NONE
|
||||
\\d\+ RETURN_VALUE
|
||||
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
|
||||
|
@ -300,11 +305,6 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
|
|||
\\d\+ IMPORT_FROM 'b'
|
||||
\\d\+ STORE_DEREF 14
|
||||
\\d\+ POP_TOP
|
||||
\\d\+ LOAD_CONST_SMALL_INT 0
|
||||
\\d\+ LOAD_CONST_STRING '*'
|
||||
\\d\+ BUILD_TUPLE 1
|
||||
\\d\+ IMPORT_NAME 'a'
|
||||
\\d\+ IMPORT_STAR
|
||||
\\d\+ RAISE_LAST
|
||||
\\d\+ LOAD_CONST_SMALL_INT 1
|
||||
\\d\+ RAISE_OBJ
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# test errors with import *
|
||||
|
||||
# 'import *' is not allowed in function scope
|
||||
try:
|
||||
exec('def foo(): from x import *')
|
||||
except SyntaxError as er:
|
||||
print('function', 'SyntaxError')
|
||||
|
||||
# 'import *' is not allowed in class scope
|
||||
try:
|
||||
exec('class C: from x import *')
|
||||
except SyntaxError as er:
|
||||
print('class', 'SyntaxError')
|
Loading…
Reference in New Issue