From 50 Python features, tips & tricks that you don’t know (click)
How to use suppress() to handle Exceptions like a PRO — Python
This feature makes your code more readable and uses less lines of code.

In Python, when you use a try-except block and write pass in the except block, it is called an exception handling with a null operation. The pass keyword is a placeholder statement in Python that does nothing. At some point we all did that, because this approach is useful when you want to catch an exception and handle it later or when you want to ignore the exception entirely. By using pass in the except block, you are essentially telling the interpreter to move on to the next line of code without taking any action in response to the exception.
import os
filename = "example.txt"
try:
os.remove(filename)
except FileNotFoundError:
passThis is how we normally handle this situation, but we can make this code more readable and short using contextlib.suppress()
contextlib.suppress()
contextlib.suppress is a context manager in Python that allows you to suppress specific exceptions from being raised within a block of code. It's part of the contextlib module, which provides utilities for working with context managers and the with statement. Essentially, contextlib.suppress helps you write cleaner and more concise error handling code when you don't need to do anything if a particular exception occurs.
import os
import contextlib
filename = "example.txt"
with contextlib.suppress(FileNotFoundError):
os.remove(filename)Now, let’s compare both versions of code
import os
import contextlib
filename = "example.txt"
# Without contextlib.suppress
try:
os.remove(filename)
except FileNotFoundError:
pass
# With contextlib.suppress
with contextlib.suppress(FileNotFoundError):
os.remove(filename)Both versions of the code above achieve the same result: we try to remove a file and do nothing if the file is not found. The version using contextlib.suppress is more concise and arguably more readable.
Real world scenario
Let’s suppose that we want to delete all temporary files within a directory that has a certain extension.
import os
import contextlib
import logging
def clean_temp_files(temp_directory, extensions_to_remove):
"""Remove temporary files with specific extensions from a directory."""
for root, _, files in os.walk(temp_directory):
for file in files:
if any(file.endswith(ext) for ext in extensions_to_remove):
file_path = os.path.join(root, file)
with contextlib.suppress(FileNotFoundError, PermissionError):
os.remove(file_path)
logging.info(f"Deleted temporary file: {file_path}")
temp_directory = "/tmp"
extensions_to_remove = [".tmp", ".log"]
clean_temp_files(temp_directory, extensions_to_remove)In this code example, we define a function clean_temp_files that takes a directory path and a list of file extensions to remove. It walks through the directory, checks each file's extension, and attempts to delete the file if its extension matches one in the list. We use contextlib.suppress to ignore FileNotFoundError and PermissionError exceptions, which might occur if a file is not found or if we don't have permission to delete it.
This way, our code can continue to delete other files even if some files can’t be deleted, and we don’t need to clutter the code with multiple try-except blocks.
Performance overhead
In terms of performance, the difference between the two methods will be negligible in most cases, and the choice should be driven by code readability, maintainability, and your specific use case. But, you should avoid using this when your code is actively being executed by a program or system.
Let’s try to timeit to see how both would perform.
import contextlib
import os
import timeit
filename = "nonexistent_file.txt"
def try_except_method():
try:
os.remove(filename)
except FileNotFoundError:
pass
def suppress_method():
with contextlib.suppress(FileNotFoundError):
os.remove(filename)
# Measure the time it takes to execute each method
try_except_time = timeit.timeit(try_except_method, number=1_000)
suppress_time = timeit.timeit(suppress_method, number=1_000)
print(f"try-except time: {try_except_time:.6f} seconds")
print(f"contextlib.suppress time: {suppress_time:.6f} seconds")Result for 10 iterations:
try-except time: 0.000045 seconds
contextlib.suppress time: 0.000049 secondsResult for 1.000 iterations:
try-except time: 0.002316 seconds
contextlib.suppress time: 0.003152 secondsResult for 10.000 iterations:
try-except time: 0.025602 seconds
contextlib.suppress time: 0.029260 secondsResult for 100.000 iterations:
try-except time: 0.215278 seconds
contextlib.suppress time: 0.273794 secondsResult for 10.000.000 iterations:
try-except time: 20.464040 seconds
contextlib.suppress time: 28.150847 secondsAs you may see, for fewer iterations the difference between the two methods is negligible, but when we increase iterations, contextlib.suppress is much slower. This does not mean you should not use the suppress approach, this method should be avoided when you are dealing with lots of try-except blocks that are actively run.
As a conclusion, for most use cases it’s just fine to use contextlib.suppress, but when you are dealing with very high performant systems, it should be avoided.
Thank you for reading this article. If you want to dive deep into Python, follow me. I will write more advanced guides about Python soon including a series of article about features that i wrote about in 50 Python features, tips & tricks that you don’t know.






