From 4379bb3f9ac0b7f6e21b1441663122a26f96be31 Mon Sep 17 00:00:00 2001 From: alandonovan Date: Tue, 4 Aug 2020 11:31:21 -0400 Subject: spec: clarify scope rules for comprehensions (#299) - first loop operand is resolved in enclosing environment - all loop vars are bound before any expression is resolved See https://github.com/bazelbuild/starlark/issues/84 --- doc/spec.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/spec.md b/doc/spec.md index 41ccc7f..743e6cd 100644 --- a/doc/spec.md +++ b/doc/spec.md @@ -1302,7 +1302,6 @@ def hello(): if x == 1: y = "hello" ``` - It is a dynamic error to evaluate a reference to a local variable before it has been bound: @@ -1319,6 +1318,32 @@ print(x) # dynamic error: global variable x referenced before ass x = "hello" ``` +and for nested loops in comprehensions. +In the (unnatural) examples below, the scope of the variables `x`, `y`, +and `z` is the entire compehension block, except the operand of the first +loop (`[]` or `[1]`), which is resolved in the enclosing environment. +The second loop may thus refer to variables defined by the third (`z`), +even though such references would fail if actually executed. + +``` +[1//0 for x in [] for y in z for z in ()] # [] (no error) +[1//0 for x in [1] for y in z for z in ()] # dynamic error: local variable z referenced before assignment +``` + + + + It is a static error to bind a global variable already explicitly bound in the file: ```python -- cgit v1.2.3