Closed CNSeniorious000 closed 2 months ago
Sounds generally reasonable to me. But mypy requires you provide a T
to JsProxy[T]
and not everything does something reasonable when you call to_py()
so I'm not sure what to do about it. Can we make a type parameter optional?
Can we make a type parameter optional?
I think this is possible in python 3.13. In python 3.13 PEP 696 is implemented. So we can provide a default
argument to TypeVar
. I think mypy will support this then.
I think we can explicitly specify the type in every usage of JsProxy
. And use JsProxy[Any]
for cases when we can't infer the type. For downstream developers, they may need to static type every JsProxy
too or at least use JsProxy[Any]
if they want to support mypy. (Or they can migrate to pyright because pyright treats them as JsProxy[unknown]
in "standard" mode. Its "strict" mode is the same as mypy)
Another way is to use a type-only TypedJsProxy
. The implementation may belike:
class TypedJsProxy[T](JsProxy):
def to_py(self) -> T: ...
@overload
def to_js(value: T) -> TypedJsProxy[T]: ...
# ... other to_js overloads ...
def to_js(value: Any) -> TypedJsProxy[Any]: ...
After trying a bit, I think this is impossible and worthless. If we want to pursue absolute type correctness, we may need to make too many changes.
Firstly, we need to add a TypedJsProxy
here, which is a fake class for type hinting only. Then, we need to change every option type in webtypy where TypedDict is used as a parameter to TypedJsProxy... like this:
- def fetch(input: str, init: RequestInit | None = {}) -> Awaitable[Response]:
+ def fetch(input: str, init: TypedJsProxy[RequestInit] | None = to_js({})) -> Awaitable[Response]:
I think this is not a good solution.
On the other hand, when we use webtypy
to type check javascript function usages, we can simply make a fake to_js
to have the right type checking:
if TYPE_CHECKING:
def to_js[T](obj: T) -> T: ...
else:
from pyodide.ffi import to_js
Then use to_js
in calls to JavaScript functions:
from js import fetch
await fetch("/", to_js({"headers": {}, "method": "POST", "body": "123"))
will have the right behavior both during runtime and type-checking.
So I am closing this issue.
🚀 Feature
I think
JsProxy
can also be a generic type. Like:And
to_js(...).to_py()
should returns the same type as the input (if it is a simple type).Motivation
In webtypy, all kinds of options are
TypedDict
s, but they should be converted to aJsProxy
before sending it to the JavaScript function. I think we can change the type there toJsProxy[<the original TypedDict>]
instead, which needs theJsProxy
to be a generic type.Supporting this may make webtypy even more useful.
Pitch
Add more
@overload
inffi.py
Alternatives
Additional context
I think in the JavaScript side, we can consider make
PyProxy
a generic type too. Like: