Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: issubclass() arg 1 must be a class, while I am quite sure arg 1 is a class

Tags:

python

Somewhere within my code I have the following line of code.

from inspect import isclass

if isclass(route.handler) and issubclass(route.handler, web.View):

Unfortunately this line of code gives the exception below in my production environment.

TypeError: issubclass() arg 1 must be a class

As far as I know, the Python (3.7.7) compiler will first check the first condition of the if statement and if this evaluates to false, it will not check the second condition. Therefore I must conclude that route.handler must be a class, and therefore the TypeError I am getting should not be occurring. Am I missing something here? Does someone know what might be causing this?

(Unfortunately I am not able to reproduce the error)

edit:

The error originates from the swagger-aiohttp package. Here's the entire 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

edit2:

The route.handler should be an aiohttp class-based view. For example this is how one would create one and build a swagger UI on top of that.

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)

In my current implementation I also have a decorator added to the Handler class.

edit3:

When debugging locally (where it's working fine), the route.handler seems to be a <class 'abc.ABCMeta'>.

like image 882
Daan Klijn Avatar asked Sep 07 '25 23:09

Daan Klijn


1 Answers

I finally discovered the problem. The error is raised whenever a decorator from the wrapt library is used together with a abc.ABCMeta class. This is currently an open issue for the wrapt library. An example is shown below:

import abc
from inspect import isclass
import wrapt

class Base:
    pass

class BaseWithMeta(metaclass=abc.ABCMeta):
    pass

@wrapt.decorator
def pass_through(wrapped, instance, args, kwargs):
    return wrapped(*args, **kwargs)


@pass_through
class B(BaseWithMeta):
    pass

@pass_through
class C(Base):
    pass


isclass(C)
>>>
True

issubclass(C, Base)
>>>
True

isclass(B)
>>>
True

issubclass(B, BaseWithMeta)
>>>
TypeError: issubclass() arg 1 must be a class

like image 70
Daan Klijn Avatar answered Sep 09 '25 23:09

Daan Klijn