On Wed, Apr 8, 2020 at 10:21 AM Guido van Rossum <guido@python.org> wrote:
On Wed, Apr 8, 2020 at 10:05 AM Alex Hall <alex.mojaki@gmail.com> wrote:
This would break uses of locals(), e.g.

Hm, okay, so suppose the code analysis was good enough to recognize most un-obfuscated uses of locals(), exec() and eval() (and presumably sys._getframe() -- IIUC there's already a Python implementation that generates less optimal code for functions where it detects usage of sys._getframe(), maybe IronPython).
Plus if the calculation raises an exception and I'm looking at the report on Sentry, I'd like to see the values of all variables. In particular I might have expected the function to return early and I want to see what `x` was.

That's a very valid objection. For simpletons like myself who just use pdb it could also be problematic. So at the very least there would have to be a way to turn it off, and probably it should have to be requested explicitly (maybe just with -O).

Even though it seems like a pedantically correct behavior to toss something after no future direct references to it are detected, it would just break so much existing code that the upgrade to an interpreter doing this would be a nightmare.  Yes, people should in theory be using a context manager or explicit reference to things that need to live, but what _is_ an explicit reference if not the local scope?  In practice code all over the place assumes "still in local scope" means the reference lives on.  Including wrapped C/C++ code where the destructor frees underlying resources that are needed by other things outside of CPython's view.

Different behavior when debugging or adding a debug print vs when running normally is bad.  Seeing surprising behavior changes due to the addition or removal of code later in a scope that inadvertently changes when something's destructor is called is action at a distance and hard to debug.  In my experience, people understand scope-based lifetime.  It is effectively the same as modern C++ STL based pointer management semantics; destruction only happens after going out of scope or when explicitly called for.

Making it optional?  It'd need to be at least at a per-file level (from __future__ style... but called something else as this isn't likely to be our future default).  A behavior change of this magnitude globally for a program with -O would just reinforce the existing practice of nobody practically using -O.  (does anyone actually run their tests under -O let alone deploy with -O?  I expect that to be a single digit % or lower minority)



--Guido van Rossum (python.org/~guido)
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/CNON3MYEASWG6WLW5C2QWRSTMQVZDDCX/
Code of Conduct: http://python.org/psf/codeofconduct/