Byte Commander Byte Commander - 6 months ago 3
Python Question

Does finally ensure some code gets run atomically, no matter what?

Assume I'm going to write a Python script that catches the

exception to be able to get terminated by the user using Ctrl+C safely

However, I can't put all critical actions (like file writes) into the
block because it relies on local variables and to make sure a subsequent Ctrl+C does not break it anyway.

Would it work and be good practice to use a try-catch block with empty (
part and all the code inside the
part to define this snippet as "atomic, interrupt-safe code" which may not get interrupted mid-way?


with open("file.txt", "w") as f:
for i in range(1000000):
# imagine something useful that takes very long instead
data = str(data ** (data ** data))
# ensure that this code is not interrupted to prevent file corruption:

except KeyboardInterrupt:
print("User aborted, data created so far saved in file.txt")

In this example I don't care for the currently produced data string, i.e. that creation could be interrupted and no write would be triggered. But once the write started, it must be completed, that's all I want to ensure. Also, what would happen if an exception (or KeyboardInterrupt) happened while performing the write inside the finally clause?


Code in finally can still be interrupted too. Python makes no guarantees about this; all it guarantees is that execution will switch to the finally suite after the try suite completed or if an exception in the try suite was raised. A try can only handle exceptions raised within its scope, not outside of it, and finally is outside of that scope.

As such there is no point in using try on a pass statement. The pass is a no-op, it won't ever be interrupted, but the finally suite can easily be interrupted still.

You'll need to pick a different technique. You could write to a separate file and move that into place on successful completion; the OS guarantees that a file move is atomic, for example. Or record your last successful write position, and truncate the file to that point if a next write is interrupted. Or write markers in your file that signal a successful record, so that reads know what to ignore.