On Tuesday, November 19, 2019 at 3:06:26 PM UTC-5, Paul Moore wrote:
On Tue, 19 Nov 2019 at 19:03, Random832 <rand...@fastmail.com> wrote:
>
> On Tue, Nov 19, 2019, at 11:26, Paul Moore wrote:
> > Because you don't have to create the context manager directly in the
> > with statement
>
> ...what? that's *my* argument. that's *precisely* why I consider open to be 'misbehaving'. Because you *should* be able to create a context manager outside the with statement without causing these problems. Because calling open outside the with statement [absent other arrangements like an explicit try/finally] causes problems that wouldn't be there for a proper context manager that has __exit__ as the inverse of __enter__ rather than as the inverse of some other operation that happens before __enter__.

We're just going round in circles here. You *can* call open outside
the with statement. It's *perfectly* fine to do so. But if you do, it
is *your* responsibility to manage the closing of the file object

So you're proposing that everyone who doesn't use open in a context manager should always write
f = open(...)
# Absolutely nothing between the above line and the line below.
try:
   ...
finally:
   f.close()

How is that any nicer than using a context manager?  Because if you don't always write the above code, I think your code is way too fragile.  If any line of code where the comment is raises, you have a resource leak. 

(which is done using close(), not __exit__()). That's been valid and
acceptable for more years than I can recall (at least back to Python
1.4).

It is valid, and I guess this is a matter of preference, but personally I don't think it's "acceptable" code.  I think most code reviews would request changes to code that opens files without using a context manager.
 
As a convenience, you can pass the file object to a with
statement, to say "i want the file to be closed when control leaves
this suite, regardless of how that happens - please handle the admin
for me. That convenience ability is provided by file objects making
__enter__ do nothing (because there's nothing you need to do on
entering the with block to prepare for the tidying up) and making
__exit__ act like close (because all you need to do on leaving the
scope is close the file).

According to the PEP, and established usage since Python 2.5, an
object that does this is called a context manager. It's a perfectly
acceptable one. Even if it doesn't implement other behaviours that you
would like it to have, doesn't mean it's not a context manager. I'm
fine with you coining a new term ("enhanced context manager", I don't
know, I've already said naming is hard) for context managers with the
additional properties you are interested in, but existing context
managers are *not* somehow "misbehaving" or "broken", or "problematic"
- it's your assumption that context managers have behaviour that isn't
required of them by the definition of that term that's wrong.

I guess I'm in the camp of people that considers acquiring resources in the constructor as "misbehaving".  Reason below…

> Because you *should* be able to create a context manager outside the with statement without causing these problems.

Says who? The PEP doesn't say any such thing. If you are saying it, I
disagree with you. If you are saying "it's obvious and everyone must
surely agree", then sorry, I still disagree with you. Simply asserting
the same thing repeatedly is not a particularly effective argument.

Demonstrate some benefits. I'll give you "we'd be able to create

There's nothing preventing anyone from creating a context manager whenever they please.  For example, an object could create a list of context managers and then acquire those later when the resources are needed.  Are you proposing a system whereby objects that inherit from ContextManager can only come into existence in a with block?

Right now, context managers can be created anwhere.  Your best defense against leaking resources is acquiring them in the __enter__ method.  Therefore, my personal opinion is that any object that acquires resources outside of an __enter__ method should probably be rewritten as a context manager. 
 
functions like nested() without worrying about users misusing them"
for free. It's not worth a lot (IMO) but hey, you got it for free,
what did you expect? ;-)
Examine the costs, and explain why they are worth accepting  Backward
compatibility is a big one here, and you're going to need some serious
benefits to offset it, or at least some really good ways to mitigate
it - there's masses of code that passes file objects to with
statements, as well as plenty of code that uses them independently.

I really don't see any new arguments being made here, to be honest.

Paul
_______________________________________________
Python-ideas mailing list -- python...@python.org
To unsubscribe send an email to python-id...@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/2E3ULZ3Z75FZWNABSIVQAGN3V6J5QTGS/
Code of Conduct: http://python.org/psf/codeofconduct/