我的代码中有如下代码行。
from inspect import isclass
if isclass(route.handler) and issubclass(route.handler, web.View):
很不幸,这一行代码在我的生产环境中会引发以下异常。
TypeError: issubclass() arg 1 must be a class
据我所知,Python(3.7.7)编译器将首先检查if语句的第一个条件,如果评估为false,则不会检查第二个条件。因此,我必须得出结论,route.handler必须是一个类,因此我所遇到的TypeError不应该发生。这里是否有什么漏洞呢?是否有人知道可能导致这种情况的原因吗?
(不幸的是,我无法重现这个错误)
编辑:
错误源于swagger-aiohttp包。以下是完整的traceback:
Traceback (most recent call last):
File "/var/www/app/main.py", line 249, in <module>
run_app(cfg)
File "/var/www/app/main.py", line 225, in run_app
setup_swagger(app, ui_version=SWAGGER_VERSION, swagger_url=SWAGGER_URL)
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/__init__.py", line 72, in setup_swagger
security_definitions=security_definitions
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/helpers/builders.py", line 163, in generate_doc_from_each_end_point
end_point_doc = _build_doc_from_func_doc(route)
File "/home/webapp/.venv/lib/python3.7/site-packages/aiohttp_swagger/helpers/builders.py", line 44, in _build_doc_from_func_doc
if isclass(route.handler) and issubclass(route.handler, web.View):
File "/home/webapp/.venv/lib/python3.7/abc.py", line 143, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class
编辑2:
route.handler
应该是一个 aiohttp
基于类的视图。例如,这是如何创建并在其上构建一个 swagger UI 的示例。
class PingHandler(web.View):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
async def get(request):
"""
---
description: This end-point allow to test that service is up.
tags:
- Health check
produces:
- text/plain
responses:
"200":
description: successful operation. Return "pong" text
"405":
description: invalid HTTP Method
"""
return web.Response(text="pong")
app = web.Application()
app.router.add_route('GET', "/ping", PingHandler)
setup_swagger(app, swagger_url="/api/v1/doc", ui_version=3)
在我目前的实现中,我还向Handler类添加了一个装饰器。
编辑3:
在本地调试时(工作正常),route.handler 似乎是 <class 'abc.ABCMeta'>
类型。
route.handler
到底是什么。它似乎是一个通过了isclass
测试的对象,但不足以通过issubclass
,因此我们需要一些关于这个神秘对象的详细信息。 - decezeisclass
检查来修复了这个问题。仍然想知道一个类如何通过isclass
检查,但在评估issubclass
检查时仍会导致 TypeError。 - Daan Klijnissubclass
替换为isinstance
。issubclass
需要一个类,而另一个需要一个对象。isclass
需要一个对象,我认为问题就出在这里。这可以解释为什么isclass
测试通过,而另一个会抛出异常。但它并不能解释为什么在你的本地机器上仍然能够正常工作。 - Carlo Zanocco