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.

Author r.david.murray
Recipients Camion, r.david.murray
Date 2017-12-18.18:45:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1513622730.35.0.213398074469.issue32361@psf.upfronthosting.co.za>
In-reply-to
Content
What is happening here is that what nonlocal does is give the function containing the nonlocal statement access to the "cell" in the parent function that holds the local variable of that function.  When you use a global statement, the name instead refers to a global variable, and  there is no local cell created for that variable name.  Thus you get "no binding [cell] for nonlocal 'a' found".  That is literally correct from the compiler's point of view.

I agree that this message is mysterious unless you understand how python scoping works at a fairly detailed level, and thus it would be nice if the error message could be improved.  The code generating the message may not know that there's a global statement for that name in effect, though, so it might not be trivial to improve it.

Would it be possible for nonlocal to effectively "chain", and turn the references in the inner function into global references?  In theory the answer would be yes, but in practice it might be distinctly non-trivial, and would probably be a PEP level change to the language.  It is currently documented that nonlocal does not look in to the global namespace (https://docs.python.org/3/reference/simple_stmts.html#nonlocal): "The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.)
History
Date User Action Args
2017-12-18 18:45:30r.david.murraysetrecipients: + r.david.murray, Camion
2017-12-18 18:45:30r.david.murraysetmessageid: <1513622730.35.0.213398074469.issue32361@psf.upfronthosting.co.za>
2017-12-18 18:45:30r.david.murraylinkissue32361 messages
2017-12-18 18:45:30r.david.murraycreate