Export types from a plugin as `pyi`
Opened this issue · 0 comments
Feature
Add a way to export generated types from a plugin (like mypy_django_plugin
) as pyi
. So they can be used by other type checkers.
Pitch
Few days ago i started an effort to migrate types from mongo-types
into core mongoengine
, and i need to solve a problem:
Each field can accept and return either T
or T | None
, depending on the required
property.
In the mongo-types
it was solved by adding __new__
overloads for each field, and it works well, but clutters the codebase.
Similar problem exists for Django, and django-stubs
are solving this by writing a mypy plugin, that changes __set__
and __get__
descriptors for a field, depending on the init argumens.
Can this type information be exported? For example, for a django app/models.py
plugin would generate typings/mypy/app/models.pyi
with all the added types. I would run it like mypy export-plugin-types
or something similar, when my code changes.
Other options
If there's another way to solve this problem, please help me.
My last attempt looks like this (but it returns BaseField, and not the child class like StringField. And when init arguments are changing, i need to redefine those overloads for a field specifically):
from typing import Literal, Optional, TypeVar, Union, overload
from typing import Any, Callable, Generic
_ST = TypeVar("_ST")
_GT = TypeVar("_GT")
class BaseField(Generic[_ST, _GT]):
@overload
def __new__(
cls,
*args: Any,
required: Literal[False] = ...,
default: None = ...,
**kwargs: Any,
) -> BaseField[Optional[_ST], Optional[_GT]]: ...
# BaseField()
@overload
def __new__(
cls,
*args: Any,
required: Literal[False] = ...,
default: Union[str, Callable[[], str]],
**kwargs: Any,
) -> BaseField[Optional[_ST], _GT]: ...
# BaseField(required=False, default="foo")
@overload
def __new__(
cls,
*args: Any,
**kwargs: Any,
) -> BaseField[_ST, _GT]: ...
# BaseField(required=True)
def __set__(self, instance: Any, value: _ST) -> None: ...
def __get__(self, instance: Any, owner: Any) -> _GT: ...