TypeError: issubclass() arg 1 must be a class

todoism

#1

报错内容

Traceback (most recent call last):
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/cli.py", line 83, in find_best_app
    app = call_factory(script_info, app_factory)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/cli.py", line 119, in call_factory
    return app_factory()
  File "/root/flask/todoism/todoism/__init__.py", line 41, in create_app
    register_blueprints(app)
  File "/root/flask/todoism/todoism/__init__.py", line 63, in register_blueprints
    app.register_blueprint(api_v1, url_prefix='/api/v1')
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/app.py", line 98, in wrapper_func
    return f(self, *args, **kwargs)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/app.py", line 1167, in register_blueprint
    blueprint.register(self, options, first_registration)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/blueprints.py", line 256, in register
    deferred(state)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/blueprints.py", line 222, in wrapper
    func(state)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/blueprints.py", line 553, in <lambda>
    lambda s: s.app._register_error_handler(self.name, code_or_exception, f)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/app.py", line 98, in wrapper_func
    return f(self, *args, **kwargs)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/app.py", line 1420, in _register_error_handler
    exc_class, code = self._get_exc_class_and_code(code_or_exception)
  File "/root/.local/share/virtualenvs/todoism-VPre3nLT/lib/python3.5/site-packages/flask/app.py", line 1351, in _get_exc_class_and_code
    assert issubclass(exc_class, Exception)
TypeError: issubclass() arg 1 must be a class

相关部分代码(代码是从书上照着写的,自己没有改写)。
63行代码

# 注册蓝本
def register_blueprints(app):
    app.register_blueprint(auth_bp) # 认证蓝本
    app.register_blueprint(todo_bp) #  程序蓝本
    app.register_blueprint(home_bp) # 主页蓝本
    app.register_blueprint(api_v1, url_prefix='/api/v1')
    # 注册api_v1蓝本,URL前缀的形式访问Web API

41行代码

def create_app(config_name=None):
	if config_name is None:
		config_name = os.getenv('FLASK_CONFIG', 'development')

	app = Flask('todoism')
	app.config.from_object(config[config_name])

	register_extensions(app)
	register_blueprints(app)
	register_commands(app)
	register_errors(app)
	register_template_context(app)

	return app

帮忙看下,是什么问题,错误提示。
TypeError: issubclass() arg 1 must be a class
必须是个类?

浏览器打开截图


#2

注册错误处理函数的部分是怎么写的?

还是说所有代码都没改动?这样的话麻烦发下 Flask、Werkzeug 的版本。


#3

我把原导入部分代码改成这样,就没有报错了,就不知道是跳过去了,还是临时解决了。

原代码todoism/__init__.py
from todoism.apis.v1 import api_v1

改成下面代码

from todoism.apis.v1.__init__ import api_v1

下面是注册处理函数,就自己增加了错误503函数

# 注册错误函数
def register_errors(app):
    @app.errorhandler(400)
    def bad_request(e):
        return render_template('errors.html', code=400, info=_('Bad Request')), 400

    @app.errorhandler(403)
    def forbidden(e):
        return render_template('errors.html', code=403, info=_('Forbidden')), 403

    @app.errorhandler(404)
    def page_not_found(e):
        if request.accept_mimetypes.accept_json and \
        not request.accept_mimetypes.accept_html \
        or request.path.startswith('/api'):
            response = jsonify(code=404, message='The requested URL was not found on the server.')
            response.status_code = 404
            return response
        return render_template('errors.html', code=404, info=_('Page Not Found')), 404

    # 405错误响应一般只会发生在API中,我们可以直接返回JSON格式的响应。
    @app.errorhandler(405)
    def method_not_allowed(e):
        response = jsonify(code=405, message='The method is not allowed for the requested URL.')
        response.status_code = 405
        return response

    @app.errorhandler(500)
    def internal_server_error(e):
        if request.accept_mimetypes.accept_json and \
        not request.accept_mimetypes.accept_html \
        or request.host.startswith('api'):
            response = jsonify(code=500, message='An internal server error occurred.')
            response.status_code = 500
            return response
        return render_template('errors.html', code=500, info=_('Server Error')), 500
    
    # 503错误响应一般只会发生在API中,我们可以直接返回JSON格式的响应。
    @app.errorhandler(503)
    def server_not_used(e):
        response = jsonify(code=503, message='The server_not_used for the requested URL.')
        response.status_code = 503
        return response

#4

使用httpie本地测试报错,下面账号密码我可以通过网址 http://47.240.14.0登录。

(todoism) root@iZj6c1x30w0c6xqdu25e3tZ:~/flask/todoism# http --form :80/api/v1/oauth/token grant_type=password username=chile password=123
HTTP/1.0 404 NOT FOUND
Content-Length: 82
Content-Type: application/json
Date: Wed, 28 Aug 2019 03:18:51 GMT
Server: Werkzeug/0.15.5 Python/3.5.3

{
    "code": 404,
    "message": "The requested URL was not found on the server."
}

错误提示相关代码如下

def register_errors(app):
    @app.errorhandler(400)
    def bad_request(e):
        return render_template('errors.html', code=400, info=_('Bad Request')), 400

    @app.errorhandler(403)
    def forbidden(e):
        return render_template('errors.html', code=403, info=_('Forbidden')), 403

    @app.errorhandler(404)
    def page_not_found(e):
        if request.accept_mimetypes.accept_json and \
        not request.accept_mimetypes.accept_html \
        or request.path.startswith('/api'):
            response = jsonify(code=404, message='The requested URL was not found on the server.')
            response.status_code = 404
            return response
        return render_template('errors.html', code=404, info=_('Page Not Found')), 404

    # 405错误响应一般只会发生在API中,我们可以直接返回JSON格式的响应。
    @app.errorhandler(405)
    def method_not_allowed(e):
        response = jsonify(code=405, message='The method is not allowed for the requested URL.')
        response.status_code = 405
        return response

    @app.errorhandler(500)
    def internal_server_error(e):
        if request.accept_mimetypes.accept_json and \
        not request.accept_mimetypes.accept_html \
        or request.host.startswith('api'):
            response = jsonify(code=500, message='An internal server error occurred.')
            response.status_code = 500
            return response
        return render_template('errors.html', code=500, info=_('Server Error')), 500
    
    # 503错误响应一般只会发生在API中,我们可以直接返回JSON格式的响应。
    @app.errorhandler(503)
    def server_not_used(e):
        response = jsonify(code=503, message='The server_not_used for the requested URL.')
        response.status_code = 503
        return response