Skip to content

1.16 changed behavior of redefined variable to None #19280

Open
@eli-schwartz

Description

@eli-schwartz

https://github.com/mesonbuild/meson/blob/master/mesonbuild/cmake/fileapi.py

This file started triggering:

mesonbuild/cmake/fileapi.py:81:20: error: "None" has no attribute "__iter__" (not iterable)  [attr-defined]
mesonbuild/cmake/fileapi.py:82:20: error: Value of type "None" is not indexable  [index]
mesonbuild/cmake/fileapi.py:84:36: error: Value of type "None" is not indexable  [index]

due to reuse of for i in ......:

Reduction:

import typing as T
from pathlib import Path

for i in Path().iterdir():
    T.reveal_type(i)
    break

data = T.cast('T.Dict[str, T.Any]', {'foo': [{'kind': 1, 'b': 'two'}]})
for i in data['foo']:
    T.reveal_type(i)
    assert isinstance(i, dict)
    T.reveal_type(i)
    assert 'kind' in i

With mypy 1.16.0

$ mypy --no-strict-optional --warn-unreachable fileapi.py 
fileapi.py:5: note: Revealed type is "pathlib.Path"
fileapi.py:10: note: Revealed type is "Any"
fileapi.py:12: note: Revealed type is "None"
fileapi.py:13: error: "None" has no attribute "__iter__" (not iterable)  [attr-defined]

It starts off as Path, gets redefined as Any (which works?), but then asserting the Any is a dict results in it migrating to None. With mypy 1.15, it never redefined to Any at all, so it became unreachable:

$ pip install mypy==1.15.* 
$ mypy --no-strict-optional --warn-unreachable fileapi.py 
fileapi.py:5: note: Revealed type is "pathlib.Path"
fileapi.py:10: note: Revealed type is "pathlib.Path"
fileapi.py:11: error: Subclass of "Path" and "dict[Any, Any]" cannot exist: would have incompatible method signatures  [unreachable]
fileapi.py:12: error: Statement is unreachable  [unreachable]

I can't really say either behavior is useful. I want variables to be block-scoped and reset their expected value. But at least the 1.15 behavior was comprehensible to me. The new behavior only works if I delete the assert, which seems terribly counterproductive.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions