如何将运行时对象类型用作通用类型提示参数?

问题描述 投票:13回答:1

简介

有了Python / MyPy类型提示,可以使用.pyi存根将批注保存在单独的文件中以实现。我正在使用此功能来提供SQLAlchemy的ORM的基本提示(更具体地说,是flask_sqlalchemy插件)。

模型定义如下:

class MyModel(db.Model):
    id = db.Column()
    ...
...

其中db.Model直接来自SQLAlchemy。例如,可以通过以下方式查询它们:

MyModel.query.filter({options: options}).one_or_none()

[其中filter()返回另一个Query,并且one_or_none()返回MyModel的实例(显然是None)。]]

以下.pyi文件成功提示了上述构造,尽管它不完整-无法提示one_or_none()的返回类型。

class _SQLAlchemy(sqlalchemy.orm.session.Session):
    class Model:
       query = ... # type: _Query

class _Query(sqlalchemy.orm.query.Query):
    def filter(self, *args) -> query.Query: ...
    def one_or_none(self) -> Any: ...

db = ... # type: _SQLAlchemy

问题

[如何全面而通用地暗示以上内容,并暗示one_or_none()的返回类型?我的第一个尝试是使用泛型,但看起来我无法访问有问题的子类型(在给定的示例中为MyModel)。为了说明一种无效的方法:

from typing import Generic, TypeVar

_T = TypeVar('_T')

class _SQLAlchemy(sqlalchemy.orm.session.Session):
    class Model:
       def __init__(self, *args, **kwargs):
           self.query = ... # type: _Query[self.__class__]

class _Query(Generic[_T], sqlalchemy.orm.query.Query):
    def filter(self, *args) -> _Query[_T]: ...
    def one_or_none(self) -> _T: ...

db = ... # type: _SQLAlchemy

有什么方法可以使它正常工作?

为具体示例和示例道歉,但我尝试了一段时间,用一个通用示例简洁地编写了此示例,它从未像现在这样清晰(可能还不多!)

编辑

另一种无效的方法(我知道这将不得不调用myModelInstance.query ...而不是静态的MyModel.query,但即使这样也不起作用):

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 = ... # type: _SQLAlchemy

简介使用Python / MyPy类型提示,可以使用.pyi存根将批注保存在单独的文件中以实现。我正在使用此功能来给出SQLAlchemy的ORM的基本提示(...

python python-3.5 type-hinting
1个回答
0
投票

幸运的是,现在可以为该特定问题https://github.com/dropbox/sqlalchemy-stubs使用类型注释存根

© www.soinside.com 2019 - 2024. All rights reserved.