Search code examples
pythonpython-typingmypy

Incompatible types in assignment (expression has type "List[<nothing>]", variable has type (...)


Consider the following self-contained example:

from typing import List, Union

T_BENCODED_LIST = Union[List[bytes], List[List[bytes]]]
ret: T_BENCODED_LIST = []

When I test it with mypy, I get the following error:

example.py:4: error: Incompatible types in assignment (expression has type "List[<nothing>]", variable has type "Union[List[bytes], List[List[bytes]]]")

What is the problem here and how can I properly annotate this example?


Solution

  • This is related to the following mypy bugs:

    The issue relates to the use of Union with an empty list.

    There are two ways to deal with this:

    1. Get mypy to ignore the empty list assignment (not ideal, but probably the simplest approach)
    2. Use a type-hinted function to perform the empty list assignment

    Approach 1 - Get mypy to ignore the empty list assignment

    from typing import List, Union
    
    # Define the variable with type hint
    T_BENCODED_LIST: Union[List[bytes], List[List[bytes]]]
    
    # Set the value to empty list and tell mypy to look the other way.
    T_BENCODED_LIST = []  # type: ignore
    

    This feels like a reasonable approach, because it allows mypy to continue to assume that the type is correctly defined.

    Approach 2 - Use a type-hinted function for empty list assignment

    Using a type-hinted function avoids the issue with Union and empty lists. This approach means adding code that is only necessary for working around the typing issue, so isn't my preferred approach.

    from typing import List, Union
    
    # Define the variable with type hint
    T_BENCODED_LIST: Union[List[bytes], List[List[bytes]]]
    
    # Create a type-hinted function that can be used
    # for assignment.
    def get_empty_list_bytes() -> List[bytes]:
        return []
    
    # Set the value to empty list using the function.
    # Mypy will assume the type based on the functions type hint.
    T_BENCODED_LIST = get_empty_list_bytes()