On Mon, 18 Nov 2019 at 11:12, Oscar Benjamin <oscar.j.benja...@gmail.com> wrote:

> I am proposing the root of the problem here is the fact that open
> acquires its resource (the opened file descriptor) before __enter__ is
> called. This is what I mean by a context manager that "misbehaves". 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.
[...]
> What I am saying is that conceived as a context manager the object
> returned by open misbehaves. I think that not just nested but a number
> of other convenient utilities and patterns could have been possible if
> opened has been used instead of open and if context managers were
> expected to meet the constraint:
> """
> There should be no need to call __exit__ if __enter__ has not been called.
> """
> Of course a lot of time has passed since then and now there are
> probably many other misbehaving context managers so it might be too
> late to do anything about that.

Hi Oscar,
Thanks for the explanation. I see what you mean now, and that *was*
something I got from the previous discussion, it's just that I guess
I'm so used to the current behaviour that I never really thought of it
as "misbehaviour". I'm not 100% convinced that there aren't edge cases
where even your strengthened requirements on a context manager might
not be enough. For example, if __enter__ is called, but raises an
exception, is calling __exit__ required then? Consider

@contextmanager
def open_2_files():
    f = open("file1")
    g = open("file2")
    try:
        yield (f,g)
    finally:
        g.close()
        f.close()

That meets your criterion, but if open("file2") fails, you're still in
a mess. Of course, that's a toy example, and could be written to fix
that, and we could even close that loophole by saying "a context
manager should only manage one resource", but we can probably carry on
down that route for quite a while (and "should only manage one
resource" is not actually correct - the whole *point* of something
like nested() would be to manage multiple resources).

So thanks for your explanation, which I appreciate. But I'm not sure
"tightening up" the requirements on context managers is really
necessary - it will always be a balance between simplicity and
catching all the edge cases, and I don't think the case has been
proved that the current design got that balance wrong (it'll always be
a matter of personal opinion, to an extent, though, so debates like
this will probably continue happening).

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/OFT7CFQL654PUQOHEIUK37AN5O55Y2IS/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to