Skip to content

Commit f6d3903

Browse files
committed
Add scope checks for global and nonlocal
1 parent ed9c087 commit f6d3903

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ public abstract class ErrorMessages {
330330
public static final String MUST_BE_STRINGS_NOT_P = "%s must be strings, not %p";
331331
public static final String MUST_SPECIFY_FILTERS = "Must specify filters for FORMAT_RAW";
332332
public static final String MUTATED_DURING_UPDATE = "%s mutated during update";
333+
public static final String NAME_IS_ASSIGNED_BEFORE_GLOBAL = "name '%s' is assigned to before global declaration";
333334
public static final String NAME_IS_ASSIGNED_BEFORE_NONLOCAL = "name '%s' is assigned to before nonlocal declaration";
334335
public static final String NAME_NOT_DEFINED = "name '%s' is not defined";
335336
public static final String NEED_BYTELIKE_OBJ = "decoding to str: need a bytes-like object, %p found";
@@ -344,6 +345,8 @@ public abstract class ErrorMessages {
344345
public static final String NO_CURRENT_FRAME = "%s: no current frame";
345346
public static final String NO_FUNCTION_FOUND = "no function %s%s found in %s";
346347
public static final String NO_SUCH_FILE_OR_DIR = "No such file or directory: '%s:/%s'";
348+
public static final String NONLOCAL_AND_GLOBAL = "name '%s' is nonlocal and global";
349+
public static final String NONLOCAL_AT_MODULE_LEVEL = "nonlocal declaration not allowed at module level";
347350
public static final String NON_HEX_DIGIT_FOUND = "Non-hexadecimal digit found";
348351
public static final String NON_STRING_IN_CODE_SLOT = "non-string found in code slot";
349352
public static final String NOT_A_ZIP_FILE = "not a Zip file: '%s'";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/PythonSSTNodeFactory.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ public SSTNode registerGlobal(String[] names, int startOffset, int endOffset) {
129129
ScopeInfo scopeInfo = scopeEnvironment.getCurrentScope();
130130
ScopeInfo globalScope = scopeEnvironment.getGlobalScope();
131131
for (String name : names) {
132+
if (scopeInfo.isExplicitNonlocalVariable(name)) {
133+
throw errors.raiseInvalidSyntax(source, createSourceSection(startOffset, endOffset), ErrorMessages.NONLOCAL_AND_GLOBAL, name);
134+
}
135+
if (scopeInfo.findFrameSlot(name) != null) {
136+
// The expectation is that in the local context the variable can not have slot yet.
137+
// The slot is created by assignment or declaration
138+
throw errors.raiseInvalidSyntax(source, createSourceSection(startOffset, endOffset), ErrorMessages.NAME_IS_ASSIGNED_BEFORE_GLOBAL, name);
139+
}
132140
scopeInfo.addExplicitGlobalVariable(name);
133141
globalScope.createSlotIfNotPresent(name);
134142
}
@@ -137,7 +145,13 @@ public SSTNode registerGlobal(String[] names, int startOffset, int endOffset) {
137145

138146
public SSTNode registerNonLocal(String[] names, int startOffset, int endOffset) {
139147
ScopeInfo scopeInfo = scopeEnvironment.getCurrentScope();
148+
if (scopeInfo.getScopeKind() == ScopeKind.Module) {
149+
throw errors.raiseInvalidSyntax(source, createSourceSection(startOffset, endOffset), ErrorMessages.NONLOCAL_AT_MODULE_LEVEL);
150+
}
140151
for (String name : names) {
152+
if (scopeInfo.isExplicitGlobalVariable(name)) {
153+
throw errors.raiseInvalidSyntax(source, createSourceSection(startOffset, endOffset), ErrorMessages.NONLOCAL_AND_GLOBAL, name);
154+
}
141155
if (scopeInfo.findFrameSlot(name) != null) {
142156
// the expectation is that in the local context the variable can not have slot yet.
143157
// The slot is created by assignment or declaration

0 commit comments

Comments
 (0)