Skip to content

Type variables of generic returned callables not resolved/leaking #1703

Closed
@alexd2580

Description

@alexd2580

While trying to implement a typesafe @curry decorator which would enable partial application without writing any additional function-specific wrapper-code or other syntactic noise, I came across the problem of representing function-transformers using the python type system.

E.g.
Given two typed functions:

id(x) -> x
transform(f) -> f

I expect transform(id) to be typed and typesafe as well.

The problem arises with Generics and can be reproduced by typechecking the following snippet:

from typing import Callable, TypeVar

X = TypeVar("X")


def id_int(x: int) -> int:
    return x


def id_generic(x: X) -> X:
    return x


def id_f(x: Callable[[X], X]) -> Callable[[X], X]:
    return x


a: Callable[[int], int] = id_int
b: int = id_int(1)

# c: Callable[[X], X] = id_generic
d: int = id_generic(2)

# e: Callable[[Callable[[X], X]], Callable[[X], X]] = id_f

bound_id_int = id_f(id_int)
f: Callable[[int], int] = bound_id_int
g: int = bound_id_int(3)

bound_id_generic = id_f(id_generic)
# h: Callable[[X], X] = bound_id_generic
i: int = bound_id_generic(4) # ERROR HERE

Same as mypy, pyright cannot infer the type of X@id_generic to be int or Literal[4].

>>> pyright --version
pyright 1.1.126
>>> pyright callable_return_type.py
No configuration file found.
stubPath /[REDACTED] is not a valid directory.
Assuming Python platform Linux
Searching for source files
Found 1 source file
/[REDACTED]/callable_return_type.py
  /[REDACTED]/callable_return_type.py:32:27 - error: Argument of type "Literal[4]" cannot be assigned to parameter of type "X@id_generic"
    Type "Literal[4]" cannot be assigned to type "X@id_generic" (reportGeneralTypeIssues)
  /[REDACTED]/callable_return_type.py:32:10 - error: Expression of type "X@id_generic" cannot be assigned to declared type "int"
    "object" is incompatible with "int" (reportGeneralTypeIssues)
2 errors, 0 warnings, 0 infos 
Completed in 0.523sec
>>> mypy --version
mypy 0.812
>>> mypy callable_return_type.py
callable_return_type.py:32: error: Incompatible types in assignment (expression has type "X", variable has type "int")
callable_return_type.py:32: error: Argument 1 has incompatible type "int"; expected "X"
Found 2 errors in 1 file (checked 1 source file)

This issue might be related to #1639, with the exception that here we have a transformer that produces a generic function, like python/mypy#1317.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions