This lets us turn maps over Iter[Any] into Any, which I think we
really might want to do.
Activity
8Question: why exactly is this better? Does Map() allow for better runtime evalution?
Related, I think it would be nice if we could write ... for ... in T when T is a variadic type parameter instead of ... for ... in Iter[tuple[*T]]
As an example, I had the following decorator:
def computed[*T, V](
*reactives: *[signal[t] for t in Iter[tuple[*T]]],
name: str | None = None,
) -> Callable[[Callable[[*T], V]], signal[V]]: ...Question: why exactly is this better? Does
Map()allow for better runtime evalution?
Yes, the idea here is that we would like to be able to turn something like tuple[*[T | None for T in Iter[Any]]] into Any. This isn't doable with our current evaluation system because the list comprehension gets evaluated eagerly and the Iter needs to resolve to something.
By using Map and a generator comprehension, the computation is delayed and we can defer its execution to a place where we can catch an exception raised by it, allowing us to detect that case.
That said, I don't think we are going to go with this approach.
I think the real plan is going to be to require being able to extract the AST/string of annotations and support an AST based evaluation.
My plan there is to write another PEP for 3.16 for that. Backporting/prototyping gets annoying though; using from __future__ import annotations will be able to work, and I also have a zany scheme for doing "abstract interpretation" of the bytecode of __annotate__ functions to extract ASTs. (A mega-slop draft of that idea here: https://github.com/vercel/python-typemap/tree/bytecode-nonsense)
Related, I think it would be nice if we could write
... for ... in Twhen T is a variadic type parameter instead of... for ... in Iter[tuple[*T]]As an example, I had the following decorator:
def computed[*T, V]( *reactives: *[signal[t] for t in Iter[tuple[*T]]], name: str | None = None, ) -> Callable[[Callable[[*T], V]], signal[V]]: ...
I will ponder this; it might be doable. Did that *reactives type work?
Thank you!
AST evaluation sounds nice.
The *reactives does not work. Mypy is crashing. You can try the following code if you'd like to reproduce:
from collections.abc import Callable
from dataclasses import dataclass
from typemap_extensions import Iter
@dataclass
class signal[T]:
value: T | None
def computed[*T, V](
*reactives: *[signal[t] for t in Iter[tuple[*T]]],
) -> Callable[[Callable[[*T], V]], signal[V]]:
result = signal[V](None)
def decorator(func: Callable[[*T], V]) -> signal[V]:
# Not relevant right now. In here, we'd automatically update the result
# signal, based on the input signals.
return result
return decorator
r1 = signal[int](1)
r2 = signal[int](2)
@computed(r1, r2)
def f1(value1: int, value2: int) -> int:
# produce a new signal that's the sum of the given signals.
return value1 + value2
@computed(r1, r2)
def f2(value1: str, value2: str) -> str:
# Mypy should fail here! Signals are of type int, not str.
return value1 + value2This pull request is a draft
Merging is unavailable until it is marked ready for review.
The latest updates on your projects. Learn more about Vercel for GitHub.