python / python/mypy

Type[T] -> T has a strange behaviour

Open
#9,003 16 comments 7 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug priority-1-normal topic-type-form topic-usability
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

This bug report is coming from https://github.com/python/mypy/issues/8946 and https://github.com/ltworf/typedload/issues/132

Basically the pattern

def f(t: Type[T]) -> T: ...

Works for some types but not others, and I can't see a pattern. For example it will work for a NamedTuple but not for a Tuple.

See this example:

from typing import *
from dataclasses import dataclass
T = TypeVar('T')

@dataclass
class P:
    a: int

class Q(NamedTuple):
    a: int

def create(t: Type[T]) -> T:    ...

# These ones work
reveal_type(create(int))
reveal_type(create(str))
reveal_type(create(List[int]))
reveal_type(create(Dict[int, int]))
reveal_type(create(Q))
reveal_type(create(P))

# These do not
reveal_type(create(Tuple[int]))
reveal_type(create(Union[int,str]))
reveal_type(create(Optional[int]))

Now in the older mypy, the ones that do not work would just be understood as Any, which is absolutely not the intended behaviour. In the latest release instead they fail with error: Argument 1 to "create" has incompatible type "object"; expected "Type[<nothing>]" (and I have no idea of what this means).

Anyway in my view, all of the examples provided should work.

In case I'm wrong, then none of them should work, and probably a way to achieve this is needed.

Background: I am working on a library to load json-like things into more typed classes, and it promises to either return an object of the wanted type, or fail with an exception.

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.

Research direction

Begin with the supplied Python reproducer and run mypy against each reveal_type call, comparing the working cases with Tuple[int], Union[int, str], and Optional[int]. Trace how Type[T] and TypeVar[T] are inferred for those calls; done means the examples have consistent, intended inferred types or the supported behavior is clearly documented and covered by regression tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.