from contextlib import suppress
with suppress(OSError):
os.remove(temp_file)
More generally, context managers are the right way to refactor repeated try/except/finally clauses. import os, errno
try:
os.remove(temp_file)
except OSError as e:
if e.errno != errno.ENOENT:
raiseSuppose that permissions for the directory that the file is in got screwed up. (Or you're working in a new environment and they weren't set up right.) Your version gives no indication that anything went wrong. The version you dislike gives a helpful error message that says exactly what went wrong.
That error message can save a LOT of debugging time. Please make sure it is there.
But in practice on a trusted server, this kind of race condition doesn't actually happen. And if you have someone untrusted on your server, you already have a bigger problem than what you're fixing by getting the race condition right.
By contrast the kind of permission problem that I mentioned is common, and I've spent too many hours debugging such issues in code other people wrote. (Ever tried to run old code on a new server that someone else tried to set up? You'd be amazed how many hidden dependencies will turn up...)
That is why I consider the race condition to be less important than the exception swallowing anti-pattern.
There's probably no good solution to this in this case.
try:
os.remove(temp_file)
except OSError:
pass
Has a race condition? Care to explain?Suppose then you decide to go for the try-except version. You still have the same problem. At some point between os.remove, and whatever you're going to do, this other process could leap in and create the file.
Some types of race condition can be solved by simply trying the operation required, rather than checking first and then trying only if it seems necessary, but I don't think this situation is one of them.
Otherwise we'll end up with "a = 1" being a race condition, because it may happen to map to a device memory used by many applications.
This doesn't apply if you're using exceptions as control flow, which is idiomatic and recommended Python behavior.
Let's say you want to make sure some file doesn't exist before you start doing something. Specifically, you want to wipe it out if it exists, and you don't care if it doesn't exist. You do:
This isn't idiomatic Python behavior. Instead, you want to use exceptions: Mind you, an actual bare "except:" (without specifying an exception type) is still bad, because that'll catch things you don't want being caught, like a SystemExit or KeyboardInterrupt, but it's perfectly acceptable to silently pass in this case.