Search code examples
pythontypingmypy

How to use Optional correctly when assigning to None?


I have a similar problems as described here which I can reproduce with the following example (using py3.8); I have two classes like this:

from typing import Optional


class B:
    def __init__(self, name):
        self.name = name


class A:

    def __init__(
        self,
        name: str,
        clb: Optional[B] = None,
    ):
        self.name = name

        if clb is not None:
            if isinstance(clb, B):
                self.clb = clb
            else:
                raise TypeError("clb has to be of type B.")
        else:
            self.clb = None

If I now do

mypy filename.py

I will receive

error: Incompatible types in assignment (expression has type "None", variable has type "B")

I can get rid of this error if I do

self.name = name
self.clb = None

if clb is not None:
    ...

Is there another way to avoid this error?


Solution

  • Compress the check into a single test that covers all possible variants. Perform a single assignment with the result:

        if clb is None or isinstance(clb, B):
            self.clb = clb
        else:
            raise TypeError("clb has to be of type B.")