升级到 python3.10 后,带有数据类的代码停止使用 mod_wsgi。
如果使用 @dataclass 装饰器创建一个类(仅具有单个属性
x: str
),然后在模块级别的 apps.py
中的某个位置实例化,则会引发异常。原因是缺少生成的 __init__
方法(我确认如果我手动定义 __init__
一切正常)。不幸的是,在实际项目中,它是外部库的一部分,并且数据类在导入的模块中实例化,因此无法手动定义__init__
。代码无需更改(所有包也具有相同的版本)适用于 python3.9。
为了清楚起见,这是代码:
# models.py
from dataclasses import dataclass
@dataclass
class Test:
foo: str
# apps.py
from django.apps import AppConfig
from .models import Test
Test('bar') # Error is thrown here
class AppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app'
好像某个地方有错误。我还知道,根据 pypi 上的数据,mod_wsgi 仅支持 python 3.8,但不敢相信答案是“寻找其他 wsgi 解决方案,或者暂时不要升级”(如果是这样 - 也请告诉我,它可能是真的)。您可能会注意到 Django 的要求是 3.2 版,而 4.0 版可用:我尝试在这个演示项目上升级,没有任何改变,而且 django 3.2 声称也支持 python3.10(在实际项目上我无法升级,因为使用已弃用的函数的依赖项)。所以我的问题是:
回溯是:
Traceback (most recent call last):
File "/var/www/html/proof/proof/wsgi.py", line 16, in <module>
application = get_wsgi_application()
File "/usr/local/lib/python3.10/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
django.setup(set_prefix=False)
File "/usr/local/lib/python3.10/site-packages/django/__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "/usr/local/lib/python3.10/site-packages/django/apps/registry.py", line 91, in populate
app_config = AppConfig.create(entry)
File "/usr/local/lib/python3.10/site-packages/django/apps/config.py", line 124, in create
mod = import_module(mod_path)
File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/var/www/html/proof/app/apps.py", line 6, in <module>
Test('bar')
TypeError: Test() takes no arguments
这里的 repo 包含更多详细信息和完整的项目布局,还提供 Dockerfile,以便您可以轻松重现。