Search code examples
pythonmypy

Fixing mypy error - Incompatible types in assignment (expression has type "xxx", variable has type "yyy")


I am running into the following mypy error and cannot figure out how to fix it.

test.py:30: error: Incompatible types in assignment (expression has type "list[str] | list[Path]", variable has type "list[Path]")  [assignment]

Code versions: Python 3.10.13, mypy 1.9.0 (compiled: yes)

I tried options 1 and 2 from the accepted answer here, but that didn't do anything.

Here's the code:

import re
import glob
from pathlib import Path
from typing import Sequence


def find_files(files: str | Sequence[str], sort: bool = True) -> list[str] | list[Path]:
    """Find files based on shell-style wildcards.
    
    files = '/path/to/all/*.csv'

    files = [
        '/path/to/all/*.csv',
        '/and/to/all/*.xlsx
    ]
    """

    # Convert to list if input is a str.
    files = [files] if isinstance(files, str) else files

    # Find files.
    found_files = [Path(fglob).resolve()
                   for f in files
                   for fglob in glob.glob(f, recursive=True)]

    # Make sure no duplicates exist.
    found_files = [*set(found_files)]

    if sort:
        found_files = sort_nicely(found_files) # TODO: mypy complains here

    return found_files


def sort_nicely(lst: Sequence[str] | Sequence[Path] ) -> list[str] | list[Path]:
    """Perform natural human sort.
    
    sort_nicely(['P1', 'P10', 'P2']) == ['P1', 'P2', 'P10'] 
    """

    def convert(text: str) -> str | int:
        return int(text) if text.isdigit() else text

    def alpha_key(item: str | Path) -> list[str | int]:
        return [convert(c) for c in re.split('([0-9]+)', str(item))]

    return sorted(lst, key=alpha_key)

Solution

  • You need to describe the type of your sort_nicely function better, like this:

    from typing import TypeVar
    T = TypeVar("T", bound=str|Path)
    def sort_nicely(lst: Sequence[T] ) -> list[T]:
        ...
    

    What your signature is saying is "function may take a sequence of str or Path and returns a list of str or Path". What this is saying is "function may take a sequence of str or Path and return a list of the same thing".