Compare commits

...

1 Commits

Author SHA1 Message Date
Phin Wolkwitz
efd5ca5e25 Update django to 5.2, initial fixes 2025-12-04 14:45:28 +01:00
4 changed files with 56 additions and 19 deletions

View File

@@ -3,7 +3,7 @@ name = "pretix"
dynamic = ["version"]
description = "Reinventing presales, one ticket at a time"
readme = "README.rst"
requires-python = ">=3.9"
requires-python = ">=3.10"
license = {file = "LICENSE"}
keywords = ["tickets", "web", "shop", "ecommerce"]
authors = [
@@ -22,7 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.2",
]
dependencies = [
@@ -36,7 +36,7 @@ dependencies = [
"css-inline==0.18.*",
"defusedcsv>=1.1.0",
"dnspython==2.*",
"Django[argon2]==4.2.*,>=4.2.26",
"Django[argon2]==5.2.*",
"django-bootstrap3==25.2",
"django-compressor==4.5.1",
"django-countries==7.6.*",

View File

@@ -60,23 +60,25 @@ def _populate_app_cache():
def get_defining_app(o):
# If sentry packed this in a wrapper, unpack that
if "sentry" in o.__module__:
module = getattr(o, "__module__", None)
if module and "sentry" in module:
o = o.__wrapped__
if hasattr(o, "__mocked_app"):
return o.__mocked_app
# Find the Django application this belongs to
searchpath = o.__module__
searchpath = module or getattr(o.__class__, "__module__", None) or ""
# Core modules are always active
if any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
if searchpath and any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
return 'CORE'
if not app_cache:
_populate_app_cache()
while True:
app = None
while searchpath:
app = app_cache.get(searchpath)
if "." not in searchpath or app:
break
@@ -157,7 +159,11 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
if not app_cache:
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
for receiver in self._sorted_receivers(sender)[0]:
if self._is_receiver_active(sender, receiver):
response = receiver(signal=self, sender=sender, **named)
responses.append((receiver, response))
for receiver in self._sorted_receivers(sender)[1]:
if self._is_receiver_active(sender, receiver):
response = receiver(signal=self, sender=sender, **named)
responses.append((receiver, response))
@@ -179,7 +185,11 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
if not app_cache:
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
for receiver in self._sorted_receivers(sender)[0]:
if self._is_receiver_active(sender, receiver):
named[chain_kwarg_name] = response
response = receiver(signal=self, sender=sender, **named)
for receiver in self._sorted_receivers(sender)[1]:
if self._is_receiver_active(sender, receiver):
named[chain_kwarg_name] = response
response = receiver(signal=self, sender=sender, **named)
@@ -204,7 +214,15 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
if not app_cache:
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
for receiver in self._sorted_receivers(sender)[0]:
if self._is_receiver_active(sender, receiver):
try:
response = receiver(signal=self, sender=sender, **named)
except Exception as err:
responses.append((receiver, err))
else:
responses.append((receiver, response))
for receiver in self._sorted_receivers(sender)[1]:
if self._is_receiver_active(sender, receiver):
try:
response = receiver(signal=self, sender=sender, **named)
@@ -215,16 +233,33 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
return responses
def _sorted_receivers(self, sender):
orig_list = self._live_receivers(sender)
sorted_list = sorted(
orig_list,
orig_list_sync = self._live_receivers(sender)[0]
# todo: _live_receivers changed return value from [] to [], []
orig_list_async = self._live_receivers(sender)[1]
def _receiver_module(receiver):
return getattr(receiver, "__module__", receiver.__class__.__module__)
def _receiver_name(receiver):
return getattr(receiver, "__name__", receiver.__class__.__name__)
sorted_list_sync = sorted(
orig_list_sync,
key=lambda receiver: (
0 if any(receiver.__module__.startswith(m) for m in settings.CORE_MODULES) else 1,
receiver.__module__,
receiver.__name__,
0 if any(_receiver_module(receiver).startswith(m) for m in settings.CORE_MODULES) else 1,
_receiver_module(receiver),
_receiver_name(receiver),
)
)
return sorted_list
sorted_list_async = sorted(
orig_list_async,
key=lambda receiver: (
0 if any(_receiver_module(receiver).startswith(m) for m in settings.CORE_MODULES) else 1,
_receiver_module(receiver),
_receiver_name(receiver),
)
)
return sorted_list_sync, sorted_list_async
class EventPluginSignal(PluginSignal[Event]):

View File

@@ -49,7 +49,7 @@ from django.views.decorators.cache import cache_page
from django.views.decorators.gzip import gzip_page
from django.views.decorators.http import condition
from django.views.i18n import (
JavaScriptCatalog, get_formats, js_catalog_template,
JavaScriptCatalog, get_formats, builtin_template_path,
)
from lxml import html
@@ -168,7 +168,8 @@ def generate_widget_js(version, lang):
'September', 'October', 'November', 'December'
)
catalog = dict((k, v) for k, v in catalog.items() if k.startswith('widget\u0004') or k in str_wl)
template = Engine().from_string(js_catalog_template)
with builtin_template_path("i18n_catalog.js").open(encoding="utf-8") as fh:
template = Engine().from_string(fh.read())
context = Context({
'catalog_str': indent(json.dumps(
catalog, sort_keys=True, indent=2)) if catalog else None,

View File

@@ -530,6 +530,7 @@ X_FRAME_OPTIONS = 'DENY'
# URL settings
ROOT_URLCONF = 'pretix.multidomain.maindomain_urlconf'
FORMS_URLFIELD_ASSUME_HTTPS = True # transitional for django 6.0
WSGI_APPLICATION = 'pretix.wsgi.application'