How to Check If a Function Raises an Exception in Python

PythonPythonBeginner
Practice Now

Introduction

In this lab, you will learn how to check if a function raises an exception in Python. The lab starts by exploring exceptions and how they can occur within functions. You'll create a simple Python function that might raise a ZeroDivisionError and observe the traceback when the exception occurs.

Next, you'll implement a try-except block to handle the exception gracefully. Finally, you'll learn how to use pytest.raises to test whether a function raises a specific exception (optional introduction).


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/ErrorandExceptionHandlingGroup -.-> python/raising_exceptions("Raising Exceptions") subgraph Lab Skills python/catching_exceptions -.-> lab-559520{{"How to Check If a Function Raises an Exception in Python"}} python/raising_exceptions -.-> lab-559520{{"How to Check If a Function Raises an Exception in Python"}} end

Explore Exceptions in Functions

In this step, you will learn about exceptions and how they can occur within functions in Python. Understanding exceptions is crucial for writing robust and reliable code. Exceptions are events that disrupt the normal flow of a program's execution. They can occur due to various reasons, such as invalid input, file not found, or network errors.

Let's start by creating a simple Python function that might raise an exception. Open the VS Code editor in the LabEx environment and create a new file named exceptions_example.py in the ~/project directory.

## ~/project/exceptions_example.py
def divide(x, y):
    return x / y

print(divide(10, 2))
print(divide(5, 0))

In this code:

  • We define a function called divide that takes two arguments, x and y, and returns the result of x divided by y.
  • We first call the divide function with the arguments 10 and 2, which will result in 5.0 being printed to the console.
  • Then, we call the divide function with the arguments 5 and 0. This will cause a ZeroDivisionError because division by zero is not allowed.

Now, let's run this script. Open the terminal in VS Code (you can find it under "View" -> "Terminal") and execute the following command:

python ~/project/exceptions_example.py

You will see output similar to this:

5.0
Traceback (most recent call last):
  File "/home/labex/project/exceptions_example.py", line 4, in <module>
    print(divide(5, 0))
  File "/home/labex/project/exceptions_example.py", line 2, in divide
    return x / y
ZeroDivisionError: division by zero

As you can see, the first print statement executed successfully, and the result 5.0 was printed. However, when the divide function was called with y = 0, a ZeroDivisionError occurred, and the program terminated. The traceback shows the sequence of function calls that led to the exception, which can be helpful for debugging.

This example demonstrates how exceptions can occur within functions and how they can disrupt the normal flow of a program. In the next step, you will learn how to handle exceptions using try and except blocks.

Implement a try-except Block

In the previous step, you saw how exceptions can cause a program to terminate abruptly. To handle exceptions gracefully and prevent program crashes, you can use try and except blocks.

A try block allows you to enclose a section of code that might raise an exception. If an exception occurs within the try block, the program will jump to the corresponding except block, where you can handle the exception.

Let's modify the exceptions_example.py file to include a try-except block to handle the ZeroDivisionError. Open the exceptions_example.py file in the VS Code editor and modify it as follows:

## ~/project/exceptions_example.py
def divide(x, y):
    try:
        result = x / y
        return result
    except ZeroDivisionError:
        return "Cannot divide by zero!"

print(divide(10, 2))
print(divide(5, 0))
print(divide(8, 4))

In this modified code:

  • We've added a try block around the x / y operation. This means that if a ZeroDivisionError occurs during the division, the program will jump to the except block.
  • The except ZeroDivisionError: line specifies that we want to handle ZeroDivisionError exceptions.
  • Inside the except block, we return the string "Cannot divide by zero!". This will be printed to the console instead of the program crashing.

Now, let's run the modified script. Open the terminal in VS Code and execute the following command:

python ~/project/exceptions_example.py

You will see output similar to this:

5.0
Cannot divide by zero!
2.0

As you can see, the program no longer crashes when dividing by zero. Instead, the except block catches the ZeroDivisionError, and the message "Cannot divide by zero!" is printed. The program then continues to execute, and the final print statement is also executed successfully.

try-except blocks can also be used to handle other types of exceptions. For example, you can use a try-except block to handle TypeError exceptions that might occur if you try to perform an operation on incompatible data types. You can also have multiple except blocks to handle different types of exceptions.

In the next step, you will learn about how to use pytest to test for exceptions.

Test with pytest.raises (Optional Intro)

In this optional step, you'll get a brief introduction to using pytest to test for exceptions. pytest is a popular testing framework for Python that simplifies the process of writing and running tests.

First, let's install pytest. Open the terminal in VS Code and run the following command:

pip install pytest

This command will download and install pytest and its dependencies.

Now, let's create a test file for our divide function. Create a new file named test_exceptions.py in the ~/project directory.

## ~/project/test_exceptions.py
import pytest
from exceptions_example import divide

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(5, 0)

def test_divide_valid():
    assert divide(10, 2) == 5

In this code:

  • We import the pytest module and the divide function from our exceptions_example.py file.
  • We define a test function called test_divide_by_zero. This function uses pytest.raises to assert that calling divide(5, 0) will raise a ZeroDivisionError. The with pytest.raises(ZeroDivisionError): block ensures that the test will only pass if a ZeroDivisionError is raised within the block.
  • We define another test function called test_divide_valid. This function asserts that calling divide(10, 2) returns the value 5.

To run the tests, open the terminal in VS Code and execute the following command:

pytest ~/project/test_exceptions.py

You should see output similar to this:

============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/labex/project
collected 2 items

test_exceptions.py ..                                                      [100%]

============================== 2 passed in 0.01s ===============================

The output shows that two tests were collected and that both tests passed. This indicates that our divide function is behaving as expected: it raises a ZeroDivisionError when dividing by zero, and it returns the correct result when dividing by a non-zero number.

This is a very basic example of using pytest to test for exceptions. pytest has many other features that can help you write more comprehensive and effective tests.

Summary

In this lab, you begin by exploring exceptions in Python functions, understanding that exceptions are events that disrupt the normal flow of a program. You create a divide function that raises a ZeroDivisionError when dividing by zero. Running the script demonstrates how the exception terminates the program and provides a traceback for debugging.

The lab highlights the importance of understanding exceptions for writing robust code, showcasing a simple example of a function that can raise an exception and how to observe the resulting error and traceback when the exception occurs.