pyrefly icon indicating copy to clipboard operation
pyrefly copied to clipboard

Bad specialization for werkzeug.datastructures.MultiDict

Open lost-theory opened this issue 7 months ago • 2 comments

Describe the Bug

werkzeug.datastructures.MultiDict supports typing of keys and values. Mypy is able to use these types, but pyrefly gives me an error.

Example usage of MultiDict:

from werkzeug.datastructures import MultiDict

def main() -> None:
    d: MultiDict[str, str] = MultiDict()
    d['foo'] = 'foo'
    d['bar'] = 1  # this is a type error
    print(d)

if __name__ == "__main__":
    main()

Mypy result:

$ ~/sand2-env/bin/mypy --strict dbg_multidict.py
dbg_multidict.py:6: error: Incompatible types in assignment (expression has type "int", target has type "str")  [assignment]
Found 1 error in 1 file (checked 1 source file)

Pyrefly result:

$ ~/sand2-env/bin/pyrefly --version
pyrefly 0.15.2

$ ~/sand2-env/bin/pyrefly check --python-interpreter ~/sand2-env/bin/python dbg_multidict.py
./dbg_multidict.py:4:8-27: Expected 0 type arguments for `MultiDict`, got 2 [bad-specialization]
 INFO 1 errors shown, 0 errors ignored, 1 modules, 276 transitive dependencies, 66,395 lines, took 0.20s, peak memory physical 0 B

Potentially related to #215.

Sandbox Link

No response

(Only applicable for extension issues) IDE Information

No response

lost-theory avatar May 19 '25 02:05 lost-theory

Smaller repro:

import typing

if typing.TYPE_CHECKING:
    pass

T = typing.TypeVar("T")
def foo(x: T) -> None: ...

Expected: No error Actual: Expected a type form, got instance of TypeVar

grievejia avatar May 19 '25 14:05 grievejia

I think I've figured out the root cause: we were not preserving the FlowStyle of the name typing when creating a narrowing binding for it.

grievejia avatar May 19 '25 19:05 grievejia