From dff26910e542a7f193c5732b6be940e653525572 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 6 Oct 2025 09:51:13 +0200 Subject: [PATCH] Rename parameter, add test --- src/pretix/base/exporters/orderlist.py | 2 +- src/pretix/base/services/quotas.py | 8 ++++---- src/tests/base/test_models.py | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/pretix/base/exporters/orderlist.py b/src/pretix/base/exporters/orderlist.py index 3b2e6c6cac..b756c247b8 100644 --- a/src/pretix/base/exporters/orderlist.py +++ b/src/pretix/base/exporters/orderlist.py @@ -1162,7 +1162,7 @@ class QuotaListExporter(ListExporter): yield headers quotas = list(self.event.quotas.select_related('subevent')) - qa = QuotaAvailability(full_results=True, ignore_repeatable_read=True) + qa = QuotaAvailability(full_results=True, allow_repeatable_read=False) qa.queue(*quotas) qa.compute() diff --git a/src/pretix/base/services/quotas.py b/src/pretix/base/services/quotas.py index b283d6a7ea..8a2360e481 100644 --- a/src/pretix/base/services/quotas.py +++ b/src/pretix/base/services/quotas.py @@ -65,7 +65,7 @@ class QuotaAvailability: """ def __init__(self, count_waitinglist=True, ignore_closed=False, full_results=False, early_out=True, - ignore_repeatable_read=False): + allow_repeatable_read=False): """ Initialize a new quota availability calculator @@ -88,7 +88,7 @@ class QuotaAvailability: do not care about keeping the cache up to date, you can set this to ``False`` for further performance improvements. - :param ignore_repeatable_read: Allow to run this even in REPEATABLE READ mode, generally not advised. + :param allow_repeatable_read: Allow to run this even in REPEATABLE READ mode, generally not advised. """ self._queue = [] self._count_waitinglist = count_waitinglist @@ -98,7 +98,7 @@ class QuotaAvailability: self._var_to_quotas = defaultdict(set) self._early_out = early_out self._quota_objects = {} - self._ignore_repeatable_read = ignore_repeatable_read + self._allow_repeatable_read = allow_repeatable_read self.results = {} self.count_paid_orders = defaultdict(int) self.count_pending_orders = defaultdict(int) @@ -123,7 +123,7 @@ class QuotaAvailability: Compute the queued quotas. If ``allow_cache`` is set, results may also be taken from a cache that might be a few minutes outdated. In this case, you may not rely on the results in the ``count_*`` properties. """ - if not self._ignore_repeatable_read and getattr(connection, "tx_in_repeatable_read", False): + if not self._allow_repeatable_read and getattr(connection, "tx_in_repeatable_read", False): raise ValueError("You cannot compute quotas in REPEATABLE READ mode unless you explicitly opted in to " "do so.") diff --git a/src/tests/base/test_models.py b/src/tests/base/test_models.py index a4091694a1..1409a7a89c 100644 --- a/src/tests/base/test_models.py +++ b/src/tests/base/test_models.py @@ -64,6 +64,7 @@ from pretix.base.models.items import ( from pretix.base.reldate import RelativeDate, RelativeDateWrapper from pretix.base.services.orders import OrderError, cancel_order, perform_order from pretix.base.services.quotas import QuotaAvailability +from pretix.helpers import repeatable_reads_transaction from pretix.testutils.scope import classscope @@ -99,6 +100,29 @@ class BaseQuotaTestCase(TestCase): self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy') +@pytest.mark.django_db(transaction=True) +@scopes_disabled() +def test_verify_repeatable_read_check(): + if 'sqlite' in settings.DATABASES['default']['ENGINE']: + pytest.skip('Not supported on SQLite') + + o = Organizer.objects.create(name='Dummy', slug='dummy') + event = Event.objects.create( + organizer=o, name='Dummy', slug='dummy', + date_from=now(), plugins='tests.testdummy' + ) + quota = Quota.objects.create(name="Test", size=2, event=event) + + with repeatable_reads_transaction(): + with pytest.raises(ValueError): + qa = QuotaAvailability(full_results=True) + qa.queue(quota) + qa.compute() + qa = QuotaAvailability(full_results=True, allow_repeatable_read=True) + qa.queue(quota) + qa.compute() + + @pytest.mark.usefixtures("fakeredis_client") class QuotaTestCase(BaseQuotaTestCase): @classscope(attr='o')