On Mon, 18 Nov 2019 at 23:42, Oscar Benjamin <oscar.j.benja...@gmail.com> wrote:
> > The definition is clearly and precisely implied by the PEP and the
> > semantics of the with statement. A CM is anything that has __enter__
> > and __exit__. See
> > https://www.python.org/dev/peps/pep-0343/#standard-terminology.
>
> That definition is sufficient to clarify the terminology but it does
> nothing to define the expected behaviour of the context managers
> themselves - what should those methods do?

My view is that they can do whatever you like. If they give useful
behaviour when used in a with statement, then that's an acceptable
definition. Basically, the context manager protocol and the with
statement provide a mechanism, not a policy. Typically, that mechanism
is used for managing resources, but not always.

> Context managers and the
> with statement are all about assigning responsibility so there needs
> to be an understanding of what has responsibility for what at any
> given time.

Somewhere (I can't recall where) there's an example of context
managers that allow you to do something like

    with html():
        with body():
            with div(class="main-panel"):
                etc...

Whether that counts as a clever usage, or an abuse, is somewhat a
matter of opinion. I'm also not clear whether the rules you are
proposing would allow or prohibit such a use. I'm also not clear what
nested(html(), body()) might mean. It's possible to work out the
behaviours from just the definition of the mechanism. But I'm not
clear how I'd interpret a rule about "what has responsibility for
what" in this example. Conceded, that's a general statement not a
specific rule. But the rule you gave earlier:

>  If
> there was a requirement on context managers that __exit__ cleans up
> after __enter__ and any resource that needs cleaning up should only be
> acquired in __enter__ then there would never have been a problem with
> nested.

doesn't really apply here, as I don't think of the HTML example in
terms of "resources".

To look at this another way, using the example of open again, what
open() returns isn't an object that manages a resource - it's the
resource *itself* (the open file). The fact that the resource can be
self-managing at all is a result of the fact that the CM protocol and
the with statement are defined purely in terms of a mechanism. Open
file objects aren't closed using __exit__(), they are closed using
close(). But by making __enter__() do nothing and __exit__() call
close, you can make file objects work with the with statement. But you
can't make a file object's __enter__ method "acquire any resource that
needs cleaning up", because the __enter__ is a method on that resource
in the first place.

So your proposal is really saying that self-managing resources are
disallowed, and all resources need a *pair* of classes - one to
represent the resource, and one to represent a "manager" for that
resource. That's possible (that's what the opened() example in the
with statement PEP did) but it's more restrictive than the current
context manager protocol. The restrictions allow you do make more
assumptions, and hence write certain functions that you otherwise
couldn't, but do the benefits justify the costs?

On Tue, 19 Nov 2019 at 07:33, Greg Ewing <greg.ew...@canterbury.ac.nz> wrote:
>
> I think a better way to say it would be that the __enter__
> method should be atomic -- it should either acquire all the
> resources it needs or none of them. Then it's clear that the
> with statement should call __exit__ if and only if __enter__
> does not raise an exception.

I like that characterisation better, but it still makes an implicit
assumption that all context managers own the resources they manage.
Which disallows self-managing resources.

Paul
_______________________________________________
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/3KE7FE6D6FF6QV3ARN5VMDHJNJVSSOPL/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to