Apache + mod_wsgi + Django + dataclasses перестали работать после обновления до python3.10
После обновления до python3.10 код с классами данных перестал работать с mod_wsgi.
Если класс создается с помощью декоратора @dataclass (только с одним атрибутом x: str
), а затем инстанцируется где-нибудь в apps.py
на уровне модуля, то возникает исключение. Причина - отсутствие сгенерированного метода __init__
(я подтвердил, что все работает, если определить __init__
вручную). К сожалению, в реальном проекте это часть внешней библиотеки, а dataclass инстанцируется в импортируемом модуле, поэтому нет возможности определить __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'
Похоже, что где-то есть ошибка. Я также знаю, что mod_wsgi поддерживает python только до 3.8, согласно данным на pypi, но не могу поверить, что ответ "Ищите другое решение wsgi или пока не обновляйтесь" (если это так - скажите мне тоже, это может быть правдой). Вы можете заметить, что Django имеет версию 3.2 в требованиях, в то время как доступна 4.0: Я попробовал обновиться на этом демо-проекте, ничего не изменилось, плюс django 3.2 утверждает, что поддерживает и python3.10 (на реальном проекте я не могу обновиться из-за зависимостей, использующих устаревшие функции). Итак, мои вопросы таковы:
- Am I missing something that should be changed on upgrade to python 3.10 in this case?
- If it's some inner bug, where should I report it --- to python 3.10, to mod_wsgi or to Django?
Отслеживание:
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, чтобы вы могли легко воспроизвести.