RFC: Proposal: Deterministic Object Destruction
Ooomzay
ooomzay at gmail.com
Sun Mar 4 06:37:38 EST 2018
On Sunday, 4 March 2018 04:23:07 UTC, Steven D'Aprano wrote:
> On Sat, 03 Mar 2018 18:19:37 -0800, Ooomzay wrote:
>
> >> def function():
> >> x = open_resource()
> >> process(x)
> >> # and we're done with x now, but too lazy to explicitly close it
> >> sleep(10000) # Simulate some more work. Lots of work.
> >> return
> >> # and finally x is closed (2.8 hours after you finished using it)
> >>
> >> The answer in C++ is "well don't do that then". The answer is Python
> >> is, "don't be so lazy, just use a with statement".
> >
> > The answer in C++ would be to say "don't be so lazy just put the x
> > manipulation in a function or sub-block".
>
> Right -- so you still have to think about resource management. The
> premise of this proposal is that RAII means you don't have to think about
> resource management, it just happens, but that's not really the case.
That is not my main premise: Which is that RAII is a more elegant (no
specialised syntax at all) and robust way to manage resources.
Please consider the case of a composite resource: You need to implement
__enter__, __exit__ and track the open/closed state at every level in
your component hierarchy - even if some levels hold no resources directly.
This is burdensome, breaks encapsulation, breaks invariance and is error prone
...very unpythonic.
> > The answer with Python + this
> > PEP would be "don't be so lazy just put the x manipulation in a function
> > or explicitly del x" ...no new syntax.
>
> Sure -- but it doesn't gain you anything we don't already have.
See above.
> It imposes enormous burdens on the maintainers of at least five
> interpreters (CPython, Stackless, Jython, IronPython, PyPy) all of which
> will need to be re-written to have RAII semantics guaranteed;
Yes. This is a substantial issue that will almost certainly see it rejected by HWCNBN on political, rather than linguistic, grounds.
My PEP is about improving the linguistic integrity and fitness for resource management purpose of the language.
> it will
> probably have significant performance costs; and at the end of the day,
> the benefit over using a with statement is minor.
>
> (Actually, I'm not convinced that there is *any* benefit. If anything, I
> think it will be a reliability regression -- see below.)
>
> >> If you want deterministic closing of resources, with statements are the
> >> way to do it.
> >>
> >> def function():
> >> with open_resource() as x:
> >> process(x)
> >> # and x is guaranteed to be closed
> >
> > What a palava!
>
> I don't know that word, and neither do any of my dictionaries. I think
> the word you might mean is "pelaver"?
I don't know that word, and neither do any of my dictionaries. I think
the word you might mean is "Palaver"?
Anyway Palava/Pelaver/Palaver/Palavra/Palabra derives from the word
for "word", but in England it is often used idiomatically to mean a
surfeit of words, or even more generally, a surfeit of effort.
I intend it in both senses: The unnecessary addition of
the words "with", "as", "__enter__" & "__exit__" to the language
and the need implement the latter two methods all
over the place.
> In any case, you might not like with statements, but I think they're
> infinitely better than:
>
> def meaningless_function_that_exists_only_to_manage_resource():
> x = open_resource()
> process(x)
> def function():
> meaningless_function_that_exists_only_to_manage_resource()
> sleep(10000) # simulate a long-running function
Why would you prefer a new construct? Functions _are_ pythons scoping context!
Giving one a pejorative name does not change that.
> In other words, your solutions are just as much manual resource
> management as the with statement. The only differences are:
>
> - instead of explicitly using a dedicated syntax designed for
> resource management, you're implicitly using scope behaviour;
Excellent: With the benefit of automatic, exception safe, destruction of
resources, including composite resources.
> - the with block is equivalent to a try...finally, and so it is
> guaranteed to close the resource even if an exception occurs;
> your solution isn't.
> If process(x) creates a non-local reference to x, and then raises an
> exception, and that exception is caught elsewhere, x will not go out of
> scope and won't be closed.
> A regression in the reliability of the code.
This PEP does not affect existing code. Peeps who are familiar with RAII
understand that creating a global reference to an RAII resource is
explicitly saying "I want this kept open at global scope" and that is the
behaviour that they will be guaranteed.
> (I'm moderately confident that this failure of RAII to deliver what it
> promises is possible in C++ too.)
(Well I bet the entire VOIP stack, AAA and accounting modules in a certain
99999 satellite network's base-stations against you)
More information about the Python-list
mailing list