为ndb.tasklets键入注释

max*_*max 6 python google-app-engine mypy

GvRs App Engine的NDB库以及单片和-我的理解-现代JavaScript中使用发电机,使异步代码看起来象堵代码.

东西装饰着@ndb.tasklet.他们yield时,他们希望回馈执行到runloop而当他们有他们的结果准备好,他们raise StopIteration(value)(或别名ndb.Return):

@ndb.tasklet
def get_google_async():
    context = ndb.get_context()
    result = yield context.urlfetch("http://www.google.com/")
    if result.status_code == 200:
        raise ndb.Return(result.content)
    raise RuntimeError
Run Code Online (Sandbox Code Playgroud)

要使用这样的函数,您将获得一个ndb.Future对象并在其get_result()上调用get 函数以等待结果并获取它.例如:

def get_google():
    future = get_google_async()
    # do something else in real code here
    return future.get_result()
Run Code Online (Sandbox Code Playgroud)

一切都很好.但是如何添加类型注释?正确的类型是:

  • get_google_async() - > ndb.Future(通过yield)
  • ndb.tasklet(get_google_async) - > ndb.Future
  • ndb.tasklet(get_google_async).get_result() - > str

到目前为止,我只使用cast了异步功能.

def get_google():
    # type: () -> str
    future = get_google_async()
    # do something else in real code here
    return cast('str', future.get_result())
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不仅仅是关于urlfetch数百种方法 - 主要是ndb.Model.

tak*_*aka 1

get_google_async我认为它本身是一个生成器函数,所以类型提示可以是() -> Generator[ndb.Future, None, None]

至于get_google,如果您不想强制转换,类型检查可能会起作用。

喜欢

def get_google():
    # type: () -> Optional[str]
    future = get_google_async()
    # do something else in real code here
    res = future.get_result()
    if isinstance(res, str):
        return res
    # somehow convert res to str, or
    return None
Run Code Online (Sandbox Code Playgroud)