-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-34939: Allow annotated global names in module namespace #9844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@ilevkivskyi Is there any documentation update needed with respect to https://bugs.python.org/issue34939#msg327386 ? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! Here are some comments.
Python/symtable.c
Outdated
&& s->v.AnnAssign.simple) { | ||
if (((cur & DEF_NONLOCAL) | | ||
((cur & DEF_GLOBAL) && !(cur & DEF_GLOBAL_TOP)) | ||
) && s->v.AnnAssign.simple) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a new symbol table flag to solve this looks like an overkill (plus TBH I don't fully understand this solution). Why not just skip emitting this error at global scope? For example check that st->st_cur->ste_symbols != st->st_global
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably also add a comment here explaining that annotation forces a variable to be local for current scope, while global
forces it to be global, so these two "directives" are conflicting, unless we are currently at the global scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review @ilevkivskyi. This is the first time I touch the symtable so sorry if the original proposed solution was a bit convoluted. I have simplified it in 701bffe.
Lib/test/test_grammar.py
Outdated
global x | ||
x = 1 | ||
x:int = 3 | ||
""")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would reserve this test file only for basic things. I propose to add this test to either test_symtable.py
or test_syntax.py
.
Also there is even a simpler repro for the issue:
global x
x: int # SyntaxError
plus I would add test cases for nonlocal
as well (even though it already works).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that test_syntax
tests all raise SyntaxErrors, but in this case, we want to test that the solution is valid. On the other hand, test_symtable
seems to test the symtable properties directly, as opposed to check that something is a valid Syntax or not. I am a bit unsure on which file to put the reproducer (along with the "nonlocal" one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved the tests to test_symtable
in 0e21eba.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have openend #9872 as there are no current way to test for nonlocal declarations in the symtable python module.
@tirkarthi I don't have ideas for better wording. Maybe just note that this is an error only for non-global scope (because annotation forces a variable to be local for current scope)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have one additional suggestion. Feel free to merge after you address it.
Lib/test/test_symtable.py
Outdated
# Test that annotations for nonlocals are valid after the | ||
# variable is declared as nonlocal. | ||
st6 = symtable.symtable('def g():\n x=2\n def f():\n' | ||
' nonlocal x\n x:int', 'test', 'exec') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Complex multi-line tests are easier to read if you split them like this:
st6 = symtable.symtable('def g():\n'
' x = 2\n'
' def f():\n'
' nonlocal x\n'
' x: int',
'test', 'exec')
(Also I would stick to PEP 8 even in tests, see other test above. In this case space around =
and space after :
in annotation.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ilevkivskyi Thank you very much for the review and the helpful advice :) |
https://bugs.python.org/issue34939