On Nov 15, 2019, at 14:52, Chris Angelico <ros...@gmail.com> wrote:
> 
> On Sat, Nov 16, 2019 at 9:44 AM Oscar Benjamin
> <oscar.j.benja...@gmail.com> wrote:
>> 
>>> On Fri, 15 Nov 2019 at 12:04, Serhiy Storchaka <storch...@gmail.com> wrote:
>>> 
>>> 15.11.19 12:40, Jonathan Fine пише:
>>>> The original poster wanted, inside 'with' context management, to open
>>>> several files. Context management is, roughly speaking, deferred
>>>> execution wrapped in a try ... except .... statement.
>>> 
>>> In case of open() there is no deferred execution. The resource is
>>> acquired in open(), not in __enter__().
>> 
>> I've often thought that this was the root of various awkwardnesses
>> with context managers. Ideally a well-behaved context manager would
>> only use __exit__ to clean up after __enter__ but open doesn't do
>> that. The nested context manager was designed for this type of
>> well-behaved context manager but was then considered harmful because
>> open (one of the most common context managers) misbehaves.
>> 
>> Maybe some of these things could be simpler if it was clarified that a
>> context manager shouldn't acquire resource before __enter__ and a new
>> version of open was provided.
>> 
> 
> Hmm. What exactly is the object that you have prior to the file being
> opened? It can't simply be a File, because you need to specify
> parameters to the open() call. Is it a "file ready to be opened"?
> What's the identity of that?

The notion of a “file ready to be opened” makes some sense. I’d expect such a 
thing to have methods like “read_contents”, “write_contents” (plus maybe atomic 
write, append, etc. variants) that you often use, and you only use it as a 
context manager if you want to get an iterable of lines out of it or something 
else you can access iteratively rather than all at once. That other thing would 
probably be a separate ABC from the ready-to-be-opened thing, but a single 
concrete type could still satisfy both ABCs for simple cases like local disk 
files and StringIO, in which case they’d still just `return self` after doing 
the open (or, for StringIO, doing nothing) in `__enter__`. The identity of the 
ready-to-open-file thing could be a value-based thing—two objects with equal 
filenames and flags, or dirfd plus filenames plus flags, or URLs, or underlying 
buffers, are equal; the fact that they give you distinct iterable things (with 
distinct file pointers) when you open them is no different from the fact that 
you get distinct iterable things from opening the same one twice.

But this doesn’t seem to be a popular design. If you look at the way Swift, C#, 
and other “modern mainstream languages” deal with files, all that 
not-opened-file stuff is done with static methods or methods of the string 
type, etc., not by having a not-opened-file type. The closest thing they have 
to a not-opened-file type is a fancy URL type (which, in Swift, can be pretty 
fancy—it can be a file: URL with an embedded access token that you got from 
opening a security scoped bookmark, for example).

Also, I think it would get in the way of some handy shortcuts that Python 
has—e.g., if you have a raw fd passed to you by a C API or over a Unix socket, 
the way to wrap it in a file object is just to call open and use it as the 
first argument; it seems like it would be weird to have a “file ready to be 
opened” that’s actually an open file but the wrapper hasn’t been built yet.


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

Reply via email to