Introduction
With hints such as Python / MyPy, you can use .pyi stubs to save annotations in separate implementation files. I use this functionality to give basic guidance to SQLAlchemy ORM (more precisely, the flask_sqlalchemy plugin).
Models are defined as follows:
class MyModel(db.Model): id = db.Column() ... ...
where db.Model is included directly from SQLAlchemy. They can be requested, for example:
MyModel.query.filter({options: options}).one_or_none()
where filter () returns another request, and one_or_none () returns an instance of MyModel (or None, obviously).
The following .pyi file successfully hints at the construction described above, although it is incomplete - there is no way to specify the return type one_or_none ().
class _SQLAlchemy(sqlalchemy.orm.session.Session): class Model: query = ...
Question
How can we hint completely and broadly above and hint at the return type one_or_none ()? My first attempt was to use generics, but it looks like I don't have access to the subtype in question (in this example, MyModel). To illustrate a non-working approach:
from typing import Generic, TypeVar _T = TypeVar('_T') class _SQLAlchemy(sqlalchemy.orm.session.Session): class Model: def __init__(self, *args, **kwargs): self.query = ...
Is there any way to make this work?
Apologies for the concrete and example, but for some time I tried to describe it briefly with the help of a general example, and it was never as clear as at present (which, perhaps, there is still not so much!)
Edit
Another inoperative approach (I know that this would limit the need to call myModelInstance.query ... instead of the static MyModel.query, but even this does not work):
from typing import Generic, TypeVar _T = TypeVar('_T') class _SQLAlchemy(sqlalchemy.orm.session.Session): class Model: @property def query(self: _T) -> _Query[_T]: ... class _Query(Generic[_T], sqlalchemy.orm.query.Query): def filter(self, *args) -> _Query[_T]: ... def one_or_none(self) -> _T: ... db = ...