python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.26k stars 2.79k forks source link

Crash when using ParamSpec #17825

Open kvdveer opened 2 days ago

kvdveer commented 2 days ago

Crash Report

I'm developing an cache decorator that uses ParamSpec to be as generic as possible. There's a slight bug in my code (I used Sequence where I should have used Paramspec.args), but I feel that shouldn't have led to a crash. There might actually be legitimate usecases for the incorrect code I wrote.

Traceback

mypy_bug_test.py:22: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.11.2
Traceback (most recent call last):
  File "mypy/checkexpr.py", line 5822, in accept
  File "mypy/checkexpr.py", line 480, in visit_call_expr
  File "mypy/checkexpr.py", line 614, in visit_call_expr_inner
  File "mypy/checkexpr.py", line 1467, in check_call_expr_with_callee_type
  File "mypy/checkexpr.py", line 1597, in check_call
  File "mypy/checkexpr.py", line 1561, in check_call
  File "mypy/checkexpr.py", line 1746, in check_callable_call
  File "mypy/checkexpr.py", line 2062, in infer_function_type_arguments
  File "mypy/checkexpr.py", line 2268, in get_arg_infer_passes
  File "mypy/subtypes.py", line 1248, in find_member
  File "mypy/subtypes.py", line 1383, in find_node_type
  File "mypy/expandtype.py", line 114, in expand_type_by_instance
  File "mypy/expandtype.py", line 69, in expand_type
  File "mypy/types.py", line 2004, in accept
  File "mypy/expandtype.py", line 408, in visit_callable_type
  File "mypy/expandtype.py", line 500, in expand_types
  File "mypy/types.py", line 769, in accept
  File "mypy/expandtype.py", line 264, in visit_param_spec
AssertionError: 
mypy_bug_test.py:22: : note: use --pdb to drop into pdb

To Reproduce

This is how far I've managed to whitle my testcase down:

from collections.abc import Callable, Sequence
import functools
from typing import Generic, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")

class DecoratorImplementation(Generic[P, R]):
    def __init__(self,
        fn: Callable[P, Sequence[R]], param):
        self.fn = fn
        self.param = param

    def __call__(self,  *args: Sequence, **kwargs: P.kwargs):
        def wrapper(*args, **kwargs):
            return self.fn(*args, **kwargs)
        return wrapper

def decorator(func, param):

    def decorator_inner(fn):
        return functools.wraps(fn)(DecoratorImplementation(fn, param))

    return decorator_inner

Your Environment

Operating system: Debian Bookworm, python 3.11, virtualenv

mypy versions tested:

pyproject.toml:

[tool.mypy]
python_version = "3.11"
ignore_missing_imports = true
show_error_codes = true
check_untyped_defs = true
exclude = "tests/.*\\.py"

[[tool.mypy.overrides]]
module = "internal.config_py.*"
# lots of dict-heavy code which isn't typed at all.
ignore_errors = true
brianschubert commented 2 days ago

Reproduces on current master (58825f7), requires --check-untyped-defs.

Bisected to a00fcba1e77ac944276b8c4ad0a31b7b05ded59f from #16942

JelleZijlstra commented 2 days ago

The culprit found by the bisect just changed the definition of functools.wraps. It might be worth inlining the current definition of functools.wraps into the example and bisecting again to isolate the change in mypy itself that introduced the crash.

brianschubert commented 2 days ago

Good point! Using an inlined definition for functools.wraps,