geckos
geckos

Reputation: 6299

mypy `type(x) is y` does not narrow values

I have this code

class Base:
    pass


class Foo(Base):
    foo: str


def bar(x: Base):
    if type(x) is Foo:
        return x.foo
    return ""

mypy gives me this error

$ mypy cast.py
cast.py:11: error: "Base" has no attribute "foo"
Found 1 error in 1 file (checked 1 source file)

On documentation it seems that mypy supports type(x) is y for narrowing types, documentation at https://mypy.readthedocs.io/en/latest/type_narrowing.html#type-narrowing-expressions

Still I have this error. I can use isinstance(x, y) but isinstance is less efficient than type(x) is y on worst case (which I have a lot on the code). I can also fix it with a cast, which is undesirable noise to me :

def bar(x: Base):
    if type(x) is Foo:
        return cast(Foo, x).foo

so today I'm ignoring this errors with # type: ignore, which is far from ideal too

Upvotes: 1

Views: 231

Answers (1)

chepner
chepner

Reputation: 532208

You appear to be using an older version of mypy; what appears to be the pull request that added type-narrowing with the use of type was added in April 2021, between the 0.812 and 0.900 releases. Newer versions of mypy, at least, work as documented.

$ mypy --version
mypy 0.930

$ mypy tmp.py
Success: no issues found in 1 source file

Upvotes: 1

Related Questions