Skip to content

Bad type inference with a partial None type and a for loop. #8637

@barisione

Description

@barisione

I believe there's a bug in mypy (from master) which makes it not detect that a variabe used in a loop may be uninitialised (or use the value assigned before the loop) unless you are iterating over a literal []/().

This code:

def test() -> str:
    c = None
    for c in "":
        pass

    if c is None:
        return None

    return "foo"


print(test())

Prints:

$ python3 opt.py
None

But mypy says:

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

This is with mypy just updated from git and Python 3.7.4 but also happens with mypy 0.720 and Python 2.7:

$ mypy --version
mypy 0.770+dev.d54fc8e78a8dd5be3c97c1aa0da357e313113dec

If you replace "" with a [] or () I get:

$ mypy opt.py
opt.py:10: error: Incompatible return value type (got "None", expected "str")
Found 1 error in 1 file (checked 1 source file)

It's also interesting that, if the loop iterates over a variable, then nothing potentially wrong is detected:

import typing


def test(l : typing.Sequence[str]) -> str:
    c = None
    for c in l:
        pass

    if c is None:
        return None

    return "foo"


print(test([]))
print(test(""))
print(test(["hello", "world"]))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions