Introducing strictpy: A Strict Typing Library for Python

Posted on Apr 16, 2023

As Python projects grow in complexity, maintaining type safety becomes increasingly important to ensure code stability and reduce potential bugs. While Python’s dynamic typing system provides a lot of flexibility, it can sometimes lead to type-related issues that can be difficult to debug. That’s where strictpy comes in - a Python library that provides strict typing capabilities to Python 3.x. Developed by Senior Software Engineer Ishmam Hossain, strictpy makes it easy to define and enforce strict types for your Python code.

Here are some of the key features of strictpy:

1. Easy to Use

Strictpy provides a simple syntax for defining types using Python’s built-in typing module.

Here’s an example:

from strictpy import strict

@strict 
def add_numbers(x: int, y: int) -> int: 
    return x + y

In this example, we’ve defined a function add_numbers that takes two arguments, both of which must be of type int. If you try to pass anything other than an integer value for x or y, Strictpy will raise a Custom Error.

2. Custom Error/Exception classes

By default, strictpy will raise a custom exception if a type violation occurs. Here are the custom exceptions that will be raised when some violation happens.

  1. TypeHintMissingError

    • In the above code snippet, type hint for y is missing which will result in the following exception-
    from strictpy import strict
    
    @strict 
    def some_function(x: int, y) -> int: 
        return x * y
    

    Here is tracback message for the above mentioned code-

    strictpy.exceptions.TypeHintMissingError: parameter type hint cannot be empty for 'y'
    
    • In this example, the return type annotation is missing, so the program will raise TypeHintMissingError.
    from strictpy import strict
    
    @strict 
    def add_numbers(x: int, y: int): 
        return x + y
    

    Traceback-

    strictpy.exceptions.TypeHintMissingError: return type hint cannot be empty.
    
    • To ignore checking return type annotation, you can do this-
    @strict(force_return_type_check=False)
    def some_function(x: int, y: int):
        return x * y
    
  2. TypeMismatchError

    • Here, return type is str but the return value in clearly int, so you’ll get the following exception traceback:
    from strictpy import strict
    
    @strict(force_return_type_check=False)
    def some_function(x: int, y: int) -> str:
        return x * y
    
    some_function(5, y=6) # x is positional
    

    Traceback-

    strictpy.exceptions.TypeMismatchError: Expected type of 'return' is <class 'str'>, got <class 'int'> instead.```
    
    
  3. PositionalArgumentsNotAllowedException

    • You MUST call the decorated function with Keyword Only Arguments! Failing to do so will raise exception. Let’s look at an example-
    from strictpy import strict
    
    @strict(force_return_type_check=False)
    def some_function(x: int, y: int):
        return x * y
    
    some_function(5, y=6) # x is positional
    

    Error traceback:

    strictpy.exceptions.PositionalArgumentsNotAllowedException: Only keyword arguments are expected, 1 were passed as positional arguments.
    

3. Lightweight and Performant

Strictpy is designed to be lightweight and fast, with minimal overhead. It uses Python’s built-in typing module to define and enforce types, so there’s no need for external dependencies.

Strictpy is compatible with popular Python tools such as pytest and mypy. It also works seamlessly with other strictpy-enabled code, so you can use it to enforce type safety across your entire codebase.

5. Getting Started with Strictpy

Getting started with Strictpy is easy. Simply install the package using pip:

pip install strictpy

Then, you can start using it in your Python code by importing the strict decorator:

Overall, Strictpy is a flexible tool for enforcing strict typing in your Python code. If you’re looking for an easy way to ensure code stability and reduce potential bugs, give Strictpy a try today!

This is, by any means, not a replacement for static type checkers like mypy.