在Transcrypt Python到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')
我错过了什么?官方支持异步方法,不是吗? 在 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 ()
最终我让解析器正常工作。 我最初一定在其他地方阻止了解析。 可能我忘了从树上更高的节点调用visit
。 不幸的是,我无法再重现该问题。
对于那些感兴趣的人,解析器代码位于:
https://github.com/QQuick/Transcrypt/blob/master/transcrypt/modules/org/transcrypt/compiler.py
第 2045 行。
最重要的是:Python的ast模块工作正常,尽管它可以做更多的文档。
有一个(非常紧凑但可用(的第三方文档:
https://greentreesnakes.readthedocs.io/en/latest/