I recently ran into a data corruption bug for my music player when a user (me) encounters a BSOD. The best practice solution is to use a temporary file. However to do this properly, you need to ensure that the contents are written to the disk before calling os.replace. os.fsync does this and works for Unix and Windows, however macOS support is missing. Of course, macOS doesn’t support fsync, but has it’s own mechanism to achieve the same goal. When sharing my bug to a coworker I pointed out that in our company’s application, our temporary file solution is missing a sync_data cal to the disk. My coworker found that Rust takes care of macOS’s lack of fsync:
I highly suggest Python does the same otherwise the barrier of software engineering vigilance needed for Python programmers is much higher. I now have to write a conditional for macOS to call the relevant system call before calling os.replace. This make porting bug-free applications much harder.
For people confused: macos does support fsync, but makes different (weaker) guarantees on what this operation means. To get behavior matching posix standard, fcntl(fd, F_FULLFSYNC) needs to also/instead be called. (at least I think the behavior matches then)
So what you’re saying is that, to achieve the same effect, you do one thing on Linux and a different thing on Mac? That sounds like a perfect thing to paper over in the interpreter, so that calling os.fsync does the right thing regardless of platform.