12

Let's say I write the following python code:

file = open("test.txt","w+")
file.write("hi")
file.seek(0)
file.read()

The second line tells Python that I want to write "hi" to file. Of course there are two buffers involved here - the internal Python buffer and the operating system buffer - so "hi" may not actually be written to the file. I understand that if I explicitly flush the file with file.flush() or close the file with file.close() then the Python buffer will be cleared and Python will use the operating system API write method. I also understand, in both those cases (where I explicitly call flush or close), there's no guarantee that the operating system will actually write to the disk (to guarantee this I'd have to call os.fsync(file)).

Anyway, in the code above, I do not call flush nor close. So here's my question:

After the write operation, when I return the file pointer to the beginning of the file (file.seek(0)) and/or read from the file (file.read()), is it guaranteed that Python will flush its own buffer? If this is guaranteed, is the guaranteed flush a result of the seek operation, read operation, or either? In other words, do seek and/or read automatically perform a flush? And just to be clear, I'm not talking about the operating system flush to disk, which I'm pretty positive is not guaranteed - I'm only talking about Python's flush of its own buffer.

When I tested this, it seemed that both the read and seek did flush Python's buffer, but I'm not sure if this is just possible behavior, or guaranteed behavior.

If this is not guaranteed behavior, can I still rely on calling file.seek or file.read after a file.write (ie/ does Python have some other internal mechanism for dealing with this that does not involve an OS write)? Or is it best practice to always call file.flush() before a seek or read that follows a write?

VKK
  • 882
  • 7
  • 19
  • If you think the linked question doesn't answer yours, edit it with your additional observations. – Mark Ransom Jan 12 '17 at 19:26
  • @MarkRansom: you incorrectly closed this as dupe. This question is clearly OS-agnostic. But you closed it as a dupe of a Windows-only question. Please reopen, and please take more care in future. – smci Sep 14 '20 at 18:35
  • @smci are you telling me there would be a different answer on a different OS? You haven't given me any reason to change my mind. – Mark Ransom Sep 14 '20 at 18:39
  • Mark: I'm telling you that other question's title is broken, wrt being a dupe for this. If you feel confident in asserting that there are **never** any OS-specific behaviors in file flushing and closing (across all versions and runtimes of Python, pypi, etc., also, different modes: 'w+' vs 'r+b'), then please edit the other question's title to remove "in Windows", and its body to say "while this is being asked on Windows, answers should be OS-neutral". Me personally, as a 20-year user of Python who's debugged plenty of OS-specific file weirdness, I wouldn't make that claim. But it's your claim – smci Sep 14 '20 at 18:45
  • ...@MarkRansom: and of course, 2.x vs 3.x. So Python major and minor version, runtime, OS, file open mode, binary file (e.g. 'w+b') vs text, buffered vs unbuffered; there are at least six major potential sources of variation, for causing weirdness. I think your claim is extremely dubious. If people here are able to fill in that six-dimensional table, then do. – smci Sep 14 '20 at 18:52
  • I invite you to come discuss in the [Python chatroom](https://chat.stackoverflow.com/rooms/6/python) – smci Sep 14 '20 at 18:52

1 Answers1

0

For specifically CPython, for buffered IO seek calls the _io__Buffered_seek_impl which is guaranteed to flush if and only if the whence argument is set to SEEK_END (2)

read with zero arguments calls _bufferedreader_read_all through _io__Buffered_read_impl, which does flush.

avayert
  • 664
  • 5
  • 9