Home > front end >  MyPy - Incompatible types in assignment (expression has type None, variable has type X)
MyPy - Incompatible types in assignment (expression has type None, variable has type X)

Time:11-03

Does anyone have any idea why MyPy is complaining about this? It is extremely frustrating because it works if it's a ternary but not if in a standard if/else:

from typing import List, Optional, Union

def get_relevant_params() -> List[str]:
    return sorted(list(set(['1', '2', '3'])))

# also doesn't work with: ... -> Union[List[str], None]
def get_config(config_path: Optional[str] = None) -> Optional[List[str]]:
    
    # this doesn't work
    if config_path:
        read_cols = get_relevant_params()
    else:
        read_cols = None
        
    # # this works
    # read_cols = get_relevant_params() if config_path else None

    return read_cols

Here is an interactive MyPy playground with the example: https://mypy-play.net/?mypy=latest&python=3.8&gist=2c846e569ecbd5f8884367393a754adc

CodePudding user response:

Change line 11 to read:

 read_cols: Optional[List[str]] = get_relevant_params()

Your problem is that mypy identified the type of the variable read_cols automatically as a List[str] because that's the return type of get_relevant_params. Then when you try to assign None to it, it says "incompatible type". If you specify on variable creation that you want it to be optional, everything works.


Maybe a cleaner solution is to avoid using a return variable.

    if config_path:
        return get_relevant_params()
    else:
        return None

This way, there's never any confusion about the type of config_path.

CodePudding user response:

You didn't annotate read_cols, so mypy has to infer a type for it based on the first assignment to read_cols. The first assignment assigns a value of type List[str], so mypy decides that's read_cols's type, and None is not a valid value of that type.

If you want a different type, annotate your variables:

read_cols: Optional[List[str]]
  • Related