Python 3.6 AST模块无法识别异步方法

Jac*_*oge 6 python async-await transcrypt

Transcrypt Python to JavaScript编译器中实现协同程序时,我遇到了以下奇怪的问题.

Transcrypt使用CPython 3.6的本机解析器生成AST.对于异步全局函数defs,它会生成AsyncFunctionDef节点.但对于异步方法,它没有!然而,CPython本身似乎正确地编译异步方法.

所以下面的一段代码用CPython运行,但是Transcrypt无法运行它,因为CPython的AST模块生成的AST似乎缺少方法的AsyncFunctionDef节点(而不是全局函数).

所以下面的代码不会生成AsyncFunctionDef节点:

class C:
    def __init__ (self):
        self.aTime = 2

    async def g (self, waw, asio):
        print ('g0')
        await waw (self.aTime, asio)
        print ('g1')
Run Code Online (Sandbox Code Playgroud)

我错过了什么?异步方法是官方支持的,不是吗?在PEP 492中找不到任何具体内容.

该示例的完整代码是:

from org.transcrypt.stubs.browser import __pragma__, __envir__

# Note that CPython will ignore all pragma's



# Provide waitAWhile for Transcrypt

__pragma__ ('js', '{}', '''
    function waitAWhile (aTime, asio) {
      return new Promise (resolve => {
        setTimeout (() => {
          resolve (aTime);
        }, 1000 * aTime);
      });
    }
''')



# Provide waitAWhile for CPython

__pragma__ ('skip') # Compile time, needed because import is done compile time

import asyncio

def waitAWhile (aTime, asio):
    return asio.sleep (aTime)

__pragma__ ('noskip')



# Actual code to be tested    

async def f (waw, asio):
    print ('f0')
    await waw (2, asio)
    print ('f1')

class C:
    def __init__ (self):
        self.aTime = 2

    async def g (self, waw, asio):
        print ('g0')
        await waw (self.aTime, asio)
        print ('g1')

c = C ()


# Just call async functions for Transcrypt, since in the browser JavaScript is event driven by default

if __envir__.executor_name == __envir__.transpiler_name:
    f (waitAWhile, None)
    c.g (waitAWhile, None)
    c.g (waitAWhile, None)
    f (waitAWhile, None)



# Create event loop and tasks for CPython, since it isn't event driven by default

else:
    eventLoop = asyncio.get_event_loop ()
    tasks = [
        eventLoop.create_task (f (waitAWhile, asyncio)),
        eventLoop.create_task (c.g (waitAWhile, asyncio)),
        eventLoop.create_task (c.g (waitAWhile, asyncio)),
        eventLoop.create_task (f (waitAWhile, asyncio)),
    ]

    waitingTasks = asyncio.wait (tasks)
    eventLoop.run_until_complete (waitingTasks)
    eventLoop.close ()
Run Code Online (Sandbox Code Playgroud)

Jac*_*oge 1

最终我让解析器正常工作。我最初一定是在其他地方阻止了解析。visit可能我忘记从树上的更高节点调用。不幸的是我无法再重现这个问题了。

对于那些感兴趣的人,解析器代码位于:

https://github.com/QQuick/Transcrypt/blob/master/transcrypt/modules/org/transcrypt/compiler.py

2045 行。

最重要的是:Python 的 ast 模块工作正常,尽管它需要更多的文档。

有一个(非常紧凑但可用)第三方文档:

https://greentreesnakes.readthedocs.io/en/latest/