Today we’re going to talk about argtypes and errcheck attributes two lesser-known features that can save you a ton of headaches when working with functions in your codebase. But first, let’s start with some context.
Have you ever written a function that takes multiple arguments? Maybe it looks something like this:
# This function calculates the sum of two numbers
def calculate_sum(num1: int, num2: int) -> int: # Added type annotations for parameters and return value
"""
Calculates the sum of two numbers
:param num1: first number
:param num2: second number
:return: sum of num1 and num2
"""
return num1 + num2 # Added a docstring to explain the purpose of the function and added a return statement to actually return the sum
This is great and all, but what if we want to make sure the user passes in valid inputs for `num1` and `num2`? We could add some conditional statements inside our function to check that they’re both integers or floats. But what if there are more arguments? And what about edge cases like passing in a list instead of two numbers?
This is where argtypes come in handy! Argtypes allow you to specify the expected types for each argument, making it easier to catch errors and improve code readability. Here’s an updated version of our `calculate_sum` function with argtypes:
# Importing the necessary modules
from typing import Union
# Defining the function with argtypes
def calculate_sum(num1: Union[int, float], num2: Union[int, float]) -> Union[int, float]:
# Using Union to specify that the function can accept both integers and floats as arguments
# Using Union again to specify that the function can return either an integer or a float
return num1 + num2
# Adding the two numbers together and returning the result
In this example, we’re using type hints to specify that `num1` and `num2` can be either integers or floats. This is done by passing in a union of the two types (int or float) as the argument type.
But what if you want to make sure your function only accepts certain types for its arguments? For example, let’s say we have a function that takes a list and returns the length:
# This function takes in a list and returns its length
def get_list_length(lst: list) -> int: # Added type annotations for the argument and return value
return len(lst) # Returns the length of the list
This works fine if you pass in a list. But what happens when you accidentally pass in something else, like a string or an integer? You’ll end up with some unexpected behavior and potentially hard-to-debug errors. To avoid this, we can use argtypes to specify that our function only accepts lists:
# This function takes in a list of integers and returns the length of the list
def get_list_length(lst: List[int]) -> int:
# The "lst" parameter is annotated with the type "List[int]" to specify that only a list of integers can be passed in
# The "-> int" annotation specifies that the function will return an integer value
return len(lst)
# The "len()" function is used to get the length of the list and return it as an integer value
In this example, we’re using a type hint to specify that `lst` must be a list of integers. This ensures that our function only accepts valid input and helps us catch errors earlier in the development process.
But what if you want to make sure your function handles unexpected inputs gracefully? That’s where errcheck comes in! Errcheck allows you to specify how your function should handle invalid arguments, making it easier to debug and improve code readability. Here’s an example:
# Importing necessary libraries
from typing import Union # Importing Union from typing library to specify multiple types for a variable
import numpy as np # Importing numpy library as np for easier usage
# Defining a function to calculate the sum of two numbers
def calculate_sum(num1: Union[int, float], num2: Union[int, float]) -> Union[int, float]: # Specifying the types of input and output for the function
try:
return num1 + num2 # Returning the sum of the two numbers
except TypeError: # Handling the case where the input is not a number
raise ValueError("Invalid input. Please provide two numbers.") # Raising a ValueError to indicate invalid input
In this example, we’re using a `try-except` block to handle any unexpected errors that might occur when adding the two arguments together. If an error is raised (e.g., if one of the inputs isn’t a number), we catch it and raise our own custom error with a helpful message.
Argtypes and errcheck are powerful tools for improving code readability, catching errors earlier in development, and making your functions more robust. Give them a try next time you write a function with multiple arguments or complex input requirements I promise you won’t regret it!