@@ -2852,6 +2852,18 @@ codegen_import_as(compiler *c, location loc,
28522852 return codegen_nameop (c , loc , asname , Store );
28532853}
28542854
2855+ static int
2856+ codegen_validate_lazy_import (compiler * c , location loc )
2857+ {
2858+ if (_PyCompile_ScopeType (c ) != COMPILE_SCOPE_MODULE ) {
2859+ return _PyCompile_Error (c , loc , "lazy imports only allowed in module scope" );
2860+ } else if (_PyCompile_TopFBlock (c )) {
2861+ return _PyCompile_Error (c , loc , "cannot lazy import in a nested scope" );
2862+ }
2863+
2864+ return SUCCESS ;
2865+ }
2866+
28552867static int
28562868codegen_import (compiler * c , stmt_ty s )
28572869{
@@ -2873,11 +2885,15 @@ codegen_import(compiler *c, stmt_ty s)
28732885 ADDOP_LOAD_CONST (c , loc , zero );
28742886 ADDOP_LOAD_CONST (c , loc , Py_None );
28752887 if (s -> v .Import .is_lazy ) {
2876- // TODO: SyntaxError when not in module scope
2888+ RETURN_IF_ERROR ( codegen_validate_lazy_import ( c , loc ));
28772889 ADDOP_NAME_CUSTOM (c , loc , IMPORT_NAME , alias -> name , names , 2 , 1 );
28782890 } else {
2879- // TODO: If in try/except, set 2nd bit
2880- ADDOP_NAME_CUSTOM (c , loc , IMPORT_NAME , alias -> name , names , 2 , 0 );
2891+ if (_PyCompile_TopFBlock (c ) || _PyCompile_ScopeType (c ) != COMPILE_SCOPE_MODULE ) {
2892+ // force eager import in try/except block
2893+ ADDOP_NAME_CUSTOM (c , loc , IMPORT_NAME , alias -> name , names , 2 , 2 );
2894+ } else {
2895+ ADDOP_NAME_CUSTOM (c , loc , IMPORT_NAME , alias -> name , names , 2 , 0 );
2896+ }
28812897 }
28822898
28832899 if (alias -> asname ) {
@@ -2929,11 +2945,23 @@ codegen_from_import(compiler *c, stmt_ty s)
29292945 from = s -> v .ImportFrom .module ;
29302946 }
29312947 if (s -> v .ImportFrom .is_lazy ) {
2932- // TODO: SyntaxError when not in module scope
2948+ alias_ty alias = (alias_ty )asdl_seq_GET (s -> v .ImportFrom .names , 0 );
2949+ if (PyUnicode_READ_CHAR (alias -> name , 0 ) == '*' ) {
2950+ return _PyCompile_Error (c , LOC (s ), "cannot lazy import *" );
2951+ }
2952+ RETURN_IF_ERROR (codegen_validate_lazy_import (c , LOC (s )));
29332953 ADDOP_NAME_CUSTOM (c , LOC (s ), IMPORT_NAME , from , names , 2 , 1 );
29342954 } else {
2935- ADDOP_NAME_CUSTOM (c , LOC (s ), IMPORT_NAME , from , names , 2 , 0 );
2955+ alias_ty alias = (alias_ty )asdl_seq_GET (s -> v .ImportFrom .names , 0 );
2956+ if (_PyCompile_TopFBlock (c ) || _PyCompile_ScopeType (c ) != COMPILE_SCOPE_MODULE ||
2957+ PyUnicode_READ_CHAR (alias -> name , 0 ) == '*' ) {
2958+ // forced non-lazy import due to try/except or import *
2959+ ADDOP_NAME_CUSTOM (c , LOC (s ), IMPORT_NAME , from , names , 2 , 2 );
2960+ } else {
2961+ ADDOP_NAME_CUSTOM (c , LOC (s ), IMPORT_NAME , from , names , 2 , 0 );
2962+ }
29362963 }
2964+
29372965 for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
29382966 alias_ty alias = (alias_ty )asdl_seq_GET (s -> v .ImportFrom .names , i );
29392967 identifier store_name ;
0 commit comments