This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Possibly spurious SyntaxError: annotated name can't be global
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gvanrossum, levkivskyi, pablogsal, rohanpadhye, serhiy.storchaka, xtreak
Priority: normal Keywords: patch

Created on 2018-10-09 01:58 by rohanpadhye, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 9844 merged pablogsal, 2018-10-13 16:39
Messages (8)
msg327378 - (view) Author: Rohan Padhye (rohanpadhye) Date: 2018-10-09 01:58
The following code when run as a script file gives syntax error:

```
def set_x():
    global x
    x = 1

x:int = 0   # SyntaxError: annotated name 'x' can't be global
```

PEP 526 does not seem to forbid this. The error message "annotated name [...] can't be global" is usually seen when using the `global x` declaration *in the same scope* as an annotated assignment. In the above case, the annotated assignment is outside the function scope, yet Python 3.7 gives a syntax error.


Is this a bug in CPython? Or should the PEP 526 document say something about forward references?

Interestingly, if the above program is run in interactive mode, there is no syntax error. 

In interactive mode:
```
>>> def set_x():
...     global x
...     x = 1
... 
>>> x:int = 0
>>> set_x()
>>> print(x)
1
```

Further, forward references work fine with `nonlocal`. For example, the following works fine both as a script file and in interactive mode:
```
def outer():
    def inner():
        nonlocal y
        y = 1
    y:int = 0
```

I don't see why a forward reference in `global` is a problem.
msg327384 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-10-09 08:26
The error message was added with 6cff8744a0ae58c88728df8bbca4580ffa6c6a86 and issue27999. The docs were also changed as below with the commit : 

https://docs.python.org/3.8/reference/simple_stmts.html#the-global-statement

> Names listed in a global statement must not be defined as formal parameters or in a for loop control target, class definition, function definition, import statement, or variable annotation.


Thanks
msg327386 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-10-09 09:38
Hm, I think this should be allowed. The formulation in the docs is not very clear, but the wording in the PEP clarifies the intention. Indeed, only annotations at the same scope with global declarations should be prohibited.

So I think this is a bug.
msg327420 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2018-10-09 15:52
I agree with Ivan.
msg327421 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-10-09 15:58
This looks similar to say

    x = 1
    global x

It is an error in a file, but is not an error in interactive mode.
msg327424 - (view) Author: Rohan Padhye (rohanpadhye) Date: 2018-10-09 16:07
Another point I'd like to make is that there is no error in either file or interactive if the annotated assignment appears before the `global` declaration like so:

```
x:int = 0

def set_x():
    global x
    x = 1

# Works fine!
```

The syntax error specifically occurs when the annotated assignment occurs after a `global` declaration in the program, even if the assignment is in a different scope.

Neither the docs nor the PEP say anything about such an ordering constraint.
msg327554 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-10-11 20:37
I think we can just go ahead and allow this. If there is a volunteer, please go ahead, otherwise I will try to find time for this myself.
msg327716 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2018-10-14 17:01
New changeset de2aea0ff02fa9486365ce9d215bef150fae3a0b by Pablo Galindo in branch 'master':
bpo-34939: Allow annotated global names in module namespace (GH-9844)
https://github.com/python/cpython/commit/de2aea0ff02fa9486365ce9d215bef150fae3a0b
History
Date User Action Args
2022-04-11 14:59:06adminsetgithub: 79120
2018-10-14 17:07:08pablogsalsetstatus: open -> closed
stage: patch review -> resolved
2018-10-14 17:01:07pablogsalsetnosy: + pablogsal
messages: + msg327716
2018-10-13 16:39:01pablogsalsetkeywords: + patch
stage: patch review
pull_requests: + pull_request9217
2018-10-11 20:37:08levkivskyisetmessages: + msg327554
2018-10-09 16:07:14rohanpadhyesetmessages: + msg327424
2018-10-09 15:58:13serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg327421
2018-10-09 15:52:38gvanrossumsetmessages: + msg327420
2018-10-09 09:38:05levkivskyisetmessages: + msg327386
2018-10-09 08:26:31xtreaksetnosy: + xtreak
messages: + msg327384
2018-10-09 05:22:39serhiy.storchakasetnosy: + gvanrossum, levkivskyi
2018-10-09 01:58:38rohanpadhyecreate