"RecursionError: maximum recursion depth exceeded in comparison" in async function

"RecursionError: maximum recursion depth exceeded in comparison" in async function

我为 Tornado RequestHandler 写了一个辅助装饰器:

def return_response(method):
    @wraps(method)
    async def wrapper(self, *args, **kwargs):
        response = method(self, *args, **kwargs)
        if inspect.isawaitable(response):
            response = await response
        self.set_status(response.status)
        self.write(response.body)
    return wrapper

由于某种原因失败并出现以下错误:

Traceback (most recent call last):
  File ".../.venv/lib/python3.6/site-packages/tornado/web.py", line 1511, in _execute
    result = yield result
  File ".../.venv/lib/python3.6/site-packages/tornado/gen.py", line 1055, in run
    value = future.result()
  File ".../.venv/lib/python3.6/site-packages/tornado/concurrent.py", line 238, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File ".../.venv/lib/python3.6/site-packages/tornado/gen.py", line 307, in wrapper
    yielded = next(result)
  File "<string>", line 6, in _wrap_awaitable
  File ".../src/http_handlers/decorators.py", line 106, in wrapper
    response = await response
  File ".../src/http_handlers/decorators.py", line 106, in wrapper
    response = await response
  File ".../src/http_handlers/decorators.py", line 106, in wrapper
    response = await response
  [Previous line repeated 959 more times]
  File ".../src/http_handlers/decorators.py", line 104, in wrapper
    response = method(self, *args, **kwargs)
RecursionError: maximum recursion depth exceeded in comparison

此错误仅在应用程序启动一段时间后出现。是 Python、Tornado 的 bug 还是我的代码有误?有人遇到过同样的问题吗?

更新

我已经设法解决了这个问题。它在完全不同的地方。我曾经在 __new__ 方法中在运行时应用这个装饰器。我错误地将它应用于 cls 的方法,而不是实际实例。因此,每次创建 class 的新实例时,都会再次包装方法。

也许看看这个What is the maximum recursion depth in Python, and how to increase it?但是答案不会是增加它。

当您不断从自身内部调用函数时,它会不断添加到堆栈中,从而不断填满内存。 Python 对此设置了限制,因此您不会 运行 进入堆栈溢出。一段时间后,您似乎达到了该限制。

decorators.py 的第 106 行发生的任何事情都会导致同一方法在自身内部被一遍又一遍地调用。我不确定我们是否能够在没有看到完整用法的情况下确切地知道发生了什么,但希望这能给你一些想法。

我建议尝试找出您的代码在哪里被递归调用,并想出一种方法来重构您的程序,以免它发生。