Cannot anotate type of generic functions.
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 32/100
Research direction
Start with the generic-function examples and the linked Pyright issue, then compare them with the current type-variable scoping rules. Done means the typing specification has an agreed resolution for annotating generic function variables and class instance variables; the issue names no repository files or tests.
Written by the indexing model from the issue text.
Description
The current scoping rules for type variables seems to deny type annotations over generic functions.
The issue
define two functions as follows:
def fx_1(f: Callable[[bool], int]) -> int:
return f(True)
def fx_2[T](f: Callable[[bool], T]) -> T:
return f(True)
If a function alias is required, these functions can be assigned to variables. However, if type annotations are used, fx_2 cannot be annotated using compliant type checkers (i.e. pyright).
T = TypeVar("T")
fx_1_alias: Callable[[Callable[[bool], int]], int] = fx_1 # OK!
fx_2_alias: Callable[[Callable[[bool], T]], T] = fx_2 # complains that T has no meaning
Justification
- All variables should be able to be type annotated, even when those variables are functions or the annotation is not required.
defis a syntactic sugar equivalent to a variable assignation over a lambda function. As a result, it should be possible to define generic functions withoutdefstatements e.g.
fx_2_alternative: Callable[[Callable[[bool], T]], T] = lambda f: f(True)
- Generics are the first ladder of what is called a "dependent type". In the case of functions, this corresponds to a Π type where the input itself is the concrete type that will be replaced on the type var of a generic type. Here type-vars scope is over the function type itself rather than some outer entity (class, function, method).
- By these definitions of Π type, it cannot exist an unbound type variable when function/callable types are involved, since in python, the type argument is implicit and supplied when referring a TypeVar.
e.g.
T = TypeVar("T")
fx_2_alias: Callable[[Callable[[bool], T]], T] = fx_2
fx_2_alias_2: Callable[[Callable[[bool], T]], T] = fx_2
Even when using the same type var fx_2_alias and fx_2_alias_2 each var is an independent one.
A more clear syntax (like the introduced on def statements on python312) could be
fx_2_alias: Callable[X][[Callable[[bool], X]], X] = fx_2
fx_2_alias_2: Callable[X][[Callable[[bool], X]], X] = fx_2
This marks explicitly that the scope of the var is over the type itself. However, this issue does not aim to propose a new syntax, but rather aims to adjust the scoping rules of type vars.
Motivation
This issue was derived from a pyright issue where generic functions as class instance variables are denied by the checker because of the same scope issues described before.
- Dominant language
- Python
- Stars
- 1.8k
- Forks
- 302
- Avg merge
- 23h
- Merged PRs (30d)
- 8
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python/typing
-
topic: typing spec
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
topic: typing spec
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
topic: documentation
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
topic: documentation
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
topic: conformance tests topic: typing spec
Difficulty 3/5 1-2 days Newbie friendliness 72/100
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
learningequality/ricecooker#747 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
BSData/horus-heresy-3rd-edition#3171 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
run-llama/llama_index#23199 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
KhronosGroup/glTF-Blender-IO#2769 ·