3 ms·
I always wondered why does this variable leak outside the `with` scope, because this is really the one place where it should not. IIRC python3 fixed scope leak
by chombier 4y ago
I always wondered why does this variable leak outside the `with` scope, because this is really the one place where it should not.
IIRC python3 fixed scope leaks in list comprehensions, does anyone know why they didn't fix this one as well? Or does it have actual uses in practice?
- shakna 4y agoI don't know the _motivation_ for why it leaks, but it leaks because the method calls of a context manager are __enter__ and __exit__, but not __del__. [0] The motivation is especially opaque, because though CPython does run __exit__ immediately, it isn't guaranteed to do so by the standard. So __exit__ will happen at some point, like __del__ with the GC, but it won't actually call __del__, which makes GC'ing the value more complicated as __del__ can't safely run until __exit__ does. I _think_ the motivation is something to do with __exit__ being allowed to throw an exception that can be caught, whereas __del__ isn't allowed to do that, but I don't find it that convincing. And I've never seen an example where the introduced variable is ever referenced afterwards in Python's documentation (including in the PEP itself). [0] https://peps.python.org/pep-0343/ https://peps.python.org/pep-0343/
- chombier 4y agoThinking about it, my guess is that properly scoping the variable does not really prevent the user from leaking the value anyway: with context() as foo: leak = foo This is unlike list comprehensions, where it is syntactically impossible to bind the comprehension variable to a new name accessible outside the comprehension. So maybe the reason is that it is not really worth the trouble.