Type alias expansion sometimes interferes with type variable binding

Open
#3,924 6 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
python

Research direction

Start by running the two Python reproductions and comparing their reveal_type output, focusing on Callable aliases and type-variable binding. Trace the type-alias expansion path to determine why test2 binds T at the outer function level; done means equivalent aliases produce equivalent inferred types.

Written by the indexing model from the issue text.

Description

bug priority-0-high topic-calls topic-type-alias topic-type-variables

Consider the following two examples, I think they should be equivalent, since logically expansion of type aliases should happen before any other steps. (At least this would be consistent and natural for those familiar with C macros):

from typing import TypeVar, Callable
T = TypeVar('T')

def test1() -> Callable[[T], T]: ...
reveal_type(test1) # Revealed type is 'def () -> def [T] (T`-1) -> T`-1'
reveal_type(test1()) # Revealed type is 'def [T] (T`-1) -> T`-1'

F = Callable[[T], T]
def test2() -> F[T]: ...
reveal_type(test2) # Revealed type is 'def [T] () -> def (T`-1) -> T`-1'
reveal_type(test2()) # Revealed type is 'def (<nothing>) -> <nothing>'

Here test1 works as expected, while if I use an alias something strange happens with test2. Namely notice a subtle difference between their types.

def () -> def [T] (T`-1) -> T`-1
and
def [T] () -> def (T`-1) -> T`-1

I have noticed few similar scenarios, they all seem to be related to Callable.

Dominant language
Python
Stars
20.6k
Forks
3.3k
Avg merge
1d 18h
Merged PRs (30d)
54

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from python/mypy

All issues in python/mypy

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.