[Python-ideas] Deterministic iterator cleanup

Nick Coghlan ncoghlan at gmail.com
Tue Oct 25 04:33:35 EDT 2016


On 25 October 2016 at 11:59, Stephen J. Turnbull
<turnbull.stephen.fw at u.tsukuba.ac.jp> wrote:
> On the semantic side,
> constructs like closures and generators (which they may be cargo-
> culting!) mean that it's harder to link resource management to
> (syntactic) function calls than a new developer might think.  (Isn't
> that Nathaniel's motivation for the OP?)

This is my read of Nathaniel's motivation as well, and hence my
proposal: rather than trying to auto-magically guess when a developer
intended for their resource management to be linked to the current
executing frame (which requires fundamentally changing how iteration
works in a way that breaks the world, and still doesn't solve the
problem in general), I'm starting to think that we instead need a way
to let them easily say "This resource, the one I just created or have
otherwise gained access to? Link its management to the lifecycle of
the currently running function or frame, so it gets cleaned up when it
finishes running".

Precisely *how* a particular implementation did that resource
management would be up to the particular Python implementation, but
one relatively straightforward way would be to use
contextlib.ExitStack under the covers, and then when the frame
finishes execution have a check that goes:

  - did the lazily instantiated ExitStack instance get created during
frame execution?
  - if yes, close it immediately, thus reclaiming all the registered resources

The spelling of the *surface* API though is something I'd need help
from educators in designing - my problem is that I already know all
the moving parts and how they fit together (hence my confidence that
something like this would be relatively easy to implement, at least in
CPython, if we decided we wanted to do it), but I *don't* know what
kinds for terms could be used in the API if we wanted to make it
approachable to relative beginners. My initial thought would be to
offer:

    from local_resources import function_resource

and:

    from local_resources import frame_resource

Where the only difference between the two is that the first one would
complain if you tried to use it outside a normal function body, while
the second would be usable anywhere (function, class, module,
generator, coroutine).

Both would accept and automatically enter context managers as input,
as if you'd wrapped the rest of the frame body in a with statement.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list