On Sun, Mar 21, 2021 at 3:35 PM Chris Angelico <ros...@gmail.com> wrote:

> On Mon, Mar 22, 2021 at 7:49 AM Ben Rudiak-Gould <benrud...@gmail.com>
> wrote:
> >
> > In the "Object Lifetime" section you say "registers should be cleared
> upon last reference". That isn't safe, since there can be hidden
> dependencies on side effects of __del__, e.g.:
> >
> >     process_objects = create_pipeline()
> >     output_process = process_objects[-1]
> >     return output_process.wait()
> >
> > If the process class terminates the process in __del__ (PyQt5's QProcess
> does), then implicitly deleting process_objects after the second line will
> break the code.
> >
>
> Hang on hang on hang on. After the second line, there are two
> references to the last object, and one to everything else. (If
> create_pipeline returns two objects, one for each end of the pipe,
> then there are two references to the second one, and one to the
> first.) Even if you dispose of process_objects itself on the basis
> that it's not used any more (which I would disagree with, since it's
> very difficult to manage that well), it shouldn't terminate the
> process, because one of the objects is definitely still alive.
>

In the hypothetical scenario, presumably create_pipeline() returns a list
of process objects, where the process class somehow kills the process when
it is finalized. In that case dropping the last reference to
process_objects[0] would kill the first process in the pipeline. I don't
know if that's good API design, but Ben states that PyQt5 does this, and it
could stand in for any number of other APIs that legitimately destroy an
external resource when the last reference is dropped. (E.g., stdlib
temporary files.)

Curiously, this is about the opposite problem that we would have if we were
to replace the current reference counting scheme with some kind of
traditional garbage collection system.


> This is nothing to do with a register-based VM and everything to do
> with standard Python semantics, so this can't change.
>

Exactly. The link with a register-based VM is that if we replaced the value
stack with temporary local variables (as the "register-based" VM scheme
does), we'd have to decide on the lifetimes of those temporary variables.
Finalizing them when the function returns might extend the lifetimes of
some objects compared to the stack-based scheme. But finalizing all local
variables (temporary or not) as soon as they are no longer needed by
subsequent code could *shorten* the lifetimes, as in the above example.

A reasonable solution would be to leave the lifetimes of explicitly named
locals alone, but use the proposed ("as soon as possible") scheme for
temporary variables. This would appear to match how values on the value
stack are treated. Honestly that's how I read the quoted section of Skip's
proto-PEP (since it explicitly mentions registers). A version of the
example that exhibits the same questionable behavior would be this:

    return create_pipeline()[-1].wait()

Presumably this would not work correctly with the PyQt5 process class.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/VRHX3JRVL6ZDXHBLWVNNYTMPGW5ERYBH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to