Commit 558a016e authored by Damien George's avatar Damien George
Browse files

py/compile: Refine SyntaxError for repeated use of global/nonlocal.

parent 3a2171e4
...@@ -1355,9 +1355,8 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -1355,9 +1355,8 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst) { STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added); id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
if (!added) { if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
// TODO this is not compliant with CPython compile_syntax_error(comp, pn, "identifier redefined as global");
compile_syntax_error(comp, pn, "identifier already used");
return; return;
} }
id_info->kind = ID_INFO_KIND_GLOBAL_EXPLICIT; id_info->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
...@@ -1382,9 +1381,8 @@ STATIC void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -1382,9 +1381,8 @@ STATIC void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst) { STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added); id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
if (!added) { if (!added && id_info->kind != ID_INFO_KIND_FREE) {
// TODO this is not compliant with CPython compile_syntax_error(comp, pn, "identifier redefined as nonlocal");
compile_syntax_error(comp, pn, "identifier already used");
return; return;
} }
id_info_t *id_info2 = scope_find_local_in_parent(comp->scope_cur, qst); id_info_t *id_info2 = scope_find_local_in_parent(comp->scope_cur, qst);
......
# test scoping rules
# explicit global variable
a = 1
def f():
global a
global a, a # should be able to redefine as global
a = 2
f()
print(a)
# explicit nonlocal variable
def f():
a = 1
def g():
nonlocal a
nonlocal a, a # should be able to redefine as nonlocal
a = 2
g()
return a
print(f())
...@@ -77,8 +77,7 @@ test_syntax("return") ...@@ -77,8 +77,7 @@ test_syntax("return")
test_syntax("yield") test_syntax("yield")
test_syntax("nonlocal a") test_syntax("nonlocal a")
# errors on uPy but shouldn't # error on uPy, warning on CPy
#test_syntax("global a; global a")
#test_syntax("def f():\n a = 1\n global a") #test_syntax("def f():\n a = 1\n global a")
# default except must be last # default except must be last
...@@ -109,3 +108,12 @@ test_syntax("def f(a, a): pass") ...@@ -109,3 +108,12 @@ test_syntax("def f(a, a): pass")
# nonlocal must exist in outer function/class scope # nonlocal must exist in outer function/class scope
test_syntax("def f():\n def g():\n nonlocal a") test_syntax("def f():\n def g():\n nonlocal a")
# param can't be redefined as global
test_syntax('def f(x):\n global x')
# param can't be redefined as nonlocal
test_syntax('def f(x):\n nonlocal x')
# can define variable to be both nonlocal and global
test_syntax('def f():\n nonlocal x\n global x')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment