diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index 6a824e064..51dacfec0 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -23,9 +23,9 @@ import datetime import mimetypes import os from decimal import Decimal +from zoneinfo import ZoneInfo import django_filters -import pytz from django.db import transaction from django.db.models import ( Exists, F, OuterRef, Prefetch, Q, Subquery, prefetch_related_objects, @@ -602,7 +602,7 @@ class OrderViewSet(viewsets.ModelViewSet): status=status.HTTP_400_BAD_REQUEST ) - tz = pytz.timezone(self.request.event.settings.timezone) + tz = ZoneInfo(self.request.event.settings.timezone) new_date = make_aware(datetime.datetime.combine( new_date, datetime.time(hour=23, minute=59, second=59) diff --git a/src/pretix/base/exporter.py b/src/pretix/base/exporter.py index e10385779..2b911f05b 100644 --- a/src/pretix/base/exporter.py +++ b/src/pretix/base/exporter.py @@ -37,8 +37,8 @@ import tempfile from collections import OrderedDict, namedtuple from decimal import Decimal from typing import Optional, Tuple +from zoneinfo import ZoneInfo -import pytz from defusedcsv import csv from django import forms from django.conf import settings @@ -68,7 +68,7 @@ class BaseExporter: self.events = event self.event = None e = self.events.first() - self.timezone = e.timezone if e else pytz.timezone(settings.TIME_ZONE) + self.timezone = e.timezone if e else ZoneInfo(settings.TIME_ZONE) else: self.events = Event.objects.filter(pk=event.pk) self.timezone = event.timezone diff --git a/src/pretix/base/exporters/orderlist.py b/src/pretix/base/exporters/orderlist.py index 52a8218b8..a617b508d 100644 --- a/src/pretix/base/exporters/orderlist.py +++ b/src/pretix/base/exporters/orderlist.py @@ -34,8 +34,8 @@ from collections import OrderedDict from decimal import Decimal +from zoneinfo import ZoneInfo -import pytz from django import forms from django.db.models import ( Case, CharField, Count, DateTimeField, F, IntegerField, Max, Min, OuterRef, @@ -319,7 +319,7 @@ class OrderListExporter(MultiSheetListExporter): yield self.ProgressSetTotal(total=qs.count()) for order in qs.order_by('datetime').iterator(): - tz = pytz.timezone(self.event_object_cache[order.event_id].settings.timezone) + tz = ZoneInfo(self.event_object_cache[order.event_id].settings.timezone) row = [ self.event_object_cache[order.event_id].slug, @@ -452,7 +452,7 @@ class OrderListExporter(MultiSheetListExporter): yield self.ProgressSetTotal(total=qs.count()) for op in qs.order_by('order__datetime').iterator(): order = op.order - tz = pytz.timezone(order.event.settings.timezone) + tz = ZoneInfo(order.event.settings.timezone) row = [ self.event_object_cache[order.event_id].slug, order.code, @@ -621,7 +621,7 @@ class OrderListExporter(MultiSheetListExporter): for op in ops: order = op.order - tz = pytz.timezone(self.event_object_cache[order.event_id].settings.timezone) + tz = ZoneInfo(self.event_object_cache[order.event_id].settings.timezone) row = [ self.event_object_cache[order.event_id].slug, order.code, @@ -803,7 +803,7 @@ class PaymentListExporter(ListExporter): yield self.ProgressSetTotal(total=len(objs)) for obj in objs: - tz = pytz.timezone(obj.order.event.settings.timezone) + tz = ZoneInfo(obj.order.event.settings.timezone) if isinstance(obj, OrderPayment) and obj.payment_date: d2 = obj.payment_date.astimezone(tz).date().strftime('%Y-%m-%d') elif isinstance(obj, OrderRefund) and obj.execution_date: @@ -968,7 +968,7 @@ class GiftcardRedemptionListExporter(ListExporter): yield headers for obj in objs: - tz = pytz.timezone(obj.order.event.settings.timezone) + tz = ZoneInfo(obj.order.event.settings.timezone) gc = GiftCard.objects.get(pk=obj.info_data.get('gift_card')) row = [ obj.order.event.slug, diff --git a/src/pretix/base/exporters/waitinglist.py b/src/pretix/base/exporters/waitinglist.py index bd71da88a..19d015e16 100644 --- a/src/pretix/base/exporters/waitinglist.py +++ b/src/pretix/base/exporters/waitinglist.py @@ -20,8 +20,8 @@ # . # from collections import OrderedDict +from zoneinfo import ZoneInfo -import pytz from django import forms from django.db.models import F, Q from django.dispatch import receiver @@ -137,7 +137,7 @@ class WaitingListExporter(ListExporter): # which event should be used to output dates in columns "Start date" and "End date" event_for_date_columns = entry.subevent if entry.subevent else entry.event - tz = pytz.timezone(entry.event.settings.timezone) + tz = ZoneInfo(entry.event.settings.timezone) datetime_format = '%Y-%m-%d %H:%M:%S' row = [ diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py index e6419fe75..4d5632143 100644 --- a/src/pretix/base/forms/questions.py +++ b/src/pretix/base/forms/questions.py @@ -37,10 +37,10 @@ import json import logging from decimal import Decimal from io import BytesIO +from zoneinfo import ZoneInfo import dateutil.parser import pycountry -import pytz from django import forms from django.conf import settings from django.contrib import messages @@ -685,7 +685,7 @@ class BaseQuestionsForm(forms.Form): initial = answers[0] else: initial = None - tz = pytz.timezone(event.settings.timezone) + tz = ZoneInfo(event.settings.timezone) help_text = rich_text(q.help_text) label = escape(q.question) # django-bootstrap3 calls mark_safe required = q.required and not self.all_optional diff --git a/src/pretix/base/management/commands/export.py b/src/pretix/base/management/commands/export.py index a27887a02..26e837628 100644 --- a/src/pretix/base/management/commands/export.py +++ b/src/pretix/base/management/commands/export.py @@ -22,7 +22,7 @@ import json import sys -import pytz +import pytz_deprecation_shim from django.core.management.base import BaseCommand from django.utils.timezone import override from django_scopes import scope @@ -60,7 +60,7 @@ class Command(BaseCommand): sys.exit(1) locale = options.get("locale", None) - timezone = pytz.timezone(options['timezone']) if options.get('timezone') else None + timezone = pytz_deprecation_shim.timezone(options['timezone']) if options.get('timezone') else None with scope(organizer=o): if options['event_slug']: diff --git a/src/pretix/base/middleware.py b/src/pretix/base/middleware.py index 8ad3ef16a..61af59c22 100644 --- a/src/pretix/base/middleware.py +++ b/src/pretix/base/middleware.py @@ -21,8 +21,8 @@ # from collections import OrderedDict from urllib.parse import urlsplit +from zoneinfo import ZoneInfo, ZoneInfoNotFoundError -import pytz from django.conf import settings from django.http import Http404, HttpRequest, HttpResponse from django.middleware.common import CommonMiddleware @@ -98,9 +98,9 @@ class LocaleMiddleware(MiddlewareMixin): tzname = request.user.timezone if tzname: try: - timezone.activate(pytz.timezone(tzname)) + timezone.activate(ZoneInfo(tzname)) request.timezone = tzname - except pytz.UnknownTimeZoneError: + except ZoneInfoNotFoundError: pass else: timezone.deactivate() diff --git a/src/pretix/base/migrations/0031_auto_20160816_0648_squashed_0048_auto_20161129_1330.py b/src/pretix/base/migrations/0031_auto_20160816_0648_squashed_0048_auto_20161129_1330.py index 18b311835..1a305bb90 100644 --- a/src/pretix/base/migrations/0031_auto_20160816_0648_squashed_0048_auto_20161129_1330.py +++ b/src/pretix/base/migrations/0031_auto_20160816_0648_squashed_0048_auto_20161129_1330.py @@ -2,6 +2,8 @@ # Generated by Django 1.10.4 on 2017-02-03 14:21 from __future__ import unicode_literals +from zoneinfo import ZoneInfo + import django.core.validators import django.db.migrations.operations.special import django.db.models.deletion @@ -26,7 +28,7 @@ def forwards42(apps, schema_editor): for s in EventSetting.objects.filter(key='timezone').values('object_id', 'value') } for order in Order.objects.all(): - tz = pytz.timezone(etz.get(order.event_id, 'UTC')) + tz = ZoneInfo(etz.get(order.event_id, 'UTC')) order.expires = order.expires.astimezone(tz).replace(hour=23, minute=59, second=59) order.save() diff --git a/src/pretix/base/migrations/0042_order_expires.py b/src/pretix/base/migrations/0042_order_expires.py index 5d1ea51dc..233be5b60 100644 --- a/src/pretix/base/migrations/0042_order_expires.py +++ b/src/pretix/base/migrations/0042_order_expires.py @@ -2,9 +2,9 @@ # Generated by Django 1.10.2 on 2016-10-19 17:57 from __future__ import unicode_literals -import pytz +from zoneinfo import ZoneInfo + from django.db import migrations -from django.utils import timezone def forwards(apps, schema_editor): @@ -15,7 +15,7 @@ def forwards(apps, schema_editor): for s in EventSetting.objects.filter(key='timezone').values('object_id', 'value') } for order in Order.objects.all(): - tz = pytz.timezone(etz.get(order.event_id, 'UTC')) + tz = ZoneInfo(etz.get(order.event_id, 'UTC')) order.expires = order.expires.astimezone(tz).replace(hour=23, minute=59, second=59) order.save() diff --git a/src/pretix/base/migrations/0198_invoice_sent_to_customer.py b/src/pretix/base/migrations/0198_invoice_sent_to_customer.py index a82a362f5..0b6593de7 100644 --- a/src/pretix/base/migrations/0198_invoice_sent_to_customer.py +++ b/src/pretix/base/migrations/0198_invoice_sent_to_customer.py @@ -1,8 +1,7 @@ # Generated by Django 3.2.4 on 2021-09-30 10:25 -from datetime import datetime +from datetime import datetime, timezone from django.db import migrations, models -from pytz import UTC class Migration(migrations.Migration): @@ -15,7 +14,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='invoice', name='sent_to_customer', - field=models.DateTimeField(blank=True, null=True, default=UTC.localize(datetime(1970, 1, 1, 0, 0, 0, 0))), + field=models.DateTimeField(blank=True, null=True, default=datetime(1970, 1, 1, 0, 0, 0, 0, tzinfo=timezone.utc)), preserve_default=False, ), ] diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 46bf9b744..9c322be9c 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -40,8 +40,9 @@ from collections import OrderedDict from datetime import datetime, time, timedelta from operator import attrgetter from urllib.parse import urljoin +from zoneinfo import ZoneInfo -import pytz +import pytz_deprecation_shim from django.conf import settings from django.core.exceptions import ValidationError from django.core.files.storage import default_storage @@ -214,7 +215,7 @@ class EventMixin: @property def timezone(self): - return pytz.timezone(self.settings.timezone) + return pytz_deprecation_shim.timezone(self.settings.timezone) @property def effective_presale_end(self): @@ -718,7 +719,7 @@ class Event(EventMixin, LoggedModel): """ The last datetime of payments for this event. """ - tz = pytz.timezone(self.settings.timezone) + tz = ZoneInfo(self.settings.timezone) return make_aware(datetime.combine( self.settings.get('payment_term_last', as_type=RelativeDateWrapper).datetime(self).date(), time(hour=23, minute=59, second=59) diff --git a/src/pretix/base/models/items.py b/src/pretix/base/models/items.py index f90b9eec0..e7aae9a3e 100644 --- a/src/pretix/base/models/items.py +++ b/src/pretix/base/models/items.py @@ -39,9 +39,9 @@ from collections import Counter, OrderedDict from datetime import date, datetime, time from decimal import Decimal, DecimalException from typing import Tuple +from zoneinfo import ZoneInfo import dateutil.parser -import pytz from django.conf import settings from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator, RegexValidator @@ -1474,7 +1474,7 @@ class Question(LoggedModel): try: dt = dateutil.parser.parse(answer) if is_naive(dt): - dt = make_aware(dt, pytz.timezone(self.event.settings.timezone)) + dt = make_aware(dt, ZoneInfo(self.event.settings.timezone)) except: raise ValidationError(_('Invalid datetime input.')) else: diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index a7d08cf5b..691fba8cb 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -42,10 +42,10 @@ from collections import Counter from datetime import datetime, time, timedelta from decimal import Decimal from typing import Any, Dict, List, Union +from zoneinfo import ZoneInfo import dateutil import pycountry -import pytz from django.conf import settings from django.core.exceptions import ValidationError from django.db import models, transaction @@ -485,7 +485,7 @@ class Order(LockModel, LoggedModel): def set_expires(self, now_dt=None, subevents=None): now_dt = now_dt or now() - tz = pytz.timezone(self.event.settings.timezone) + tz = ZoneInfo(self.event.settings.timezone) mode = self.event.settings.get('payment_term_mode') if mode == 'days': exp_by_date = now_dt.astimezone(tz) + timedelta(days=self.event.settings.get('payment_term_days', as_type=int)) @@ -856,7 +856,7 @@ class Order(LockModel, LoggedModel): @property def payment_term_last(self): - tz = pytz.timezone(self.event.settings.timezone) + tz = ZoneInfo(self.event.settings.timezone) term_last = self.event.settings.get('payment_term_last', as_type=RelativeDateWrapper) if term_last: if self.event.has_subevents: @@ -1216,7 +1216,7 @@ class QuestionAnswer(models.Model): try: d = dateutil.parser.parse(self.answer) if self.orderposition: - tz = pytz.timezone(self.orderposition.order.event.settings.timezone) + tz = ZoneInfo(self.orderposition.order.event.settings.timezone) d = d.astimezone(tz) return date_format(d, "SHORT_DATETIME_FORMAT") except ValueError: diff --git a/src/pretix/base/models/organizer.py b/src/pretix/base/models/organizer.py index 9568ec5bd..554e99471 100644 --- a/src/pretix/base/models/organizer.py +++ b/src/pretix/base/models/organizer.py @@ -35,7 +35,7 @@ import string from datetime import date, datetime, time -import pytz +import pytz_deprecation_shim from django.conf import settings from django.core.mail import get_connection from django.core.validators import MinLengthValidator, RegexValidator @@ -140,7 +140,7 @@ class Organizer(LoggedModel): @property def timezone(self): - return pytz.timezone(self.settings.timezone) + return pytz_deprecation_shim.timezone(self.settings.timezone) @cached_property def all_logentries_link(self): diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index 4901a7b07..454d1758b 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -39,8 +39,8 @@ import logging from collections import OrderedDict from decimal import ROUND_HALF_UP, Decimal from typing import Any, Dict, Union +from zoneinfo import ZoneInfo -import pytz from django import forms from django.conf import settings from django.contrib import messages @@ -508,7 +508,7 @@ class BasePaymentProvider: def _is_still_available(self, now_dt=None, cart_id=None, order=None): now_dt = now_dt or now() - tz = pytz.timezone(self.event.settings.timezone) + tz = ZoneInfo(self.event.settings.timezone) availability_date = self.settings.get('_availability_date', as_type=RelativeDateWrapper) if availability_date: diff --git a/src/pretix/base/pdf.py b/src/pretix/base/pdf.py index cb7fdb352..1d699c263 100644 --- a/src/pretix/base/pdf.py +++ b/src/pretix/base/pdf.py @@ -46,6 +46,7 @@ import uuid from collections import OrderedDict from functools import partial from io import BytesIO +from zoneinfo import ZoneInfo import jsonschema from arabic_reshaper import ArabicReshaper @@ -63,7 +64,6 @@ from django.utils.timezone import now from django.utils.translation import gettext_lazy as _, pgettext from i18nfield.strings import LazyI18nString from PyPDF2 import PdfReader -from pytz import timezone from reportlab.graphics import renderPDF from reportlab.graphics.barcode.qr import QrCodeWidget from reportlab.graphics.shapes import Drawing @@ -239,7 +239,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event begin date and time"), "editor_sample": _("2017-05-31 20:00"), "evaluate": lambda op, order, ev: date_format( - ev.date_from.astimezone(timezone(ev.settings.timezone)), + ev.date_from.astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATETIME_FORMAT" ) if ev.date_from else "" }), @@ -247,7 +247,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event begin date"), "editor_sample": _("2017-05-31"), "evaluate": lambda op, order, ev: date_format( - ev.date_from.astimezone(timezone(ev.settings.timezone)), + ev.date_from.astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATE_FORMAT" ) if ev.date_from else "" }), @@ -265,7 +265,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event end date and time"), "editor_sample": _("2017-05-31 22:00"), "evaluate": lambda op, order, ev: date_format( - ev.date_to.astimezone(timezone(ev.settings.timezone)), + ev.date_to.astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATETIME_FORMAT" ) if ev.date_to else "" }), @@ -273,7 +273,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event end date"), "editor_sample": _("2017-05-31"), "evaluate": lambda op, order, ev: date_format( - ev.date_to.astimezone(timezone(ev.settings.timezone)), + ev.date_to.astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATE_FORMAT" ) if ev.date_to else "" }), @@ -281,7 +281,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event end time"), "editor_sample": _("22:00"), "evaluate": lambda op, order, ev: date_format( - ev.date_to.astimezone(timezone(ev.settings.timezone)), + ev.date_to.astimezone(ZoneInfo(ev.settings.timezone)), "TIME_FORMAT" ) if ev.date_to else "" }), @@ -294,7 +294,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event admission date and time"), "editor_sample": _("2017-05-31 19:00"), "evaluate": lambda op, order, ev: date_format( - ev.date_admission.astimezone(timezone(ev.settings.timezone)), + ev.date_admission.astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATETIME_FORMAT" ) if ev.date_admission else "" }), @@ -302,7 +302,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Event admission time"), "editor_sample": _("19:00"), "evaluate": lambda op, order, ev: date_format( - ev.date_admission.astimezone(timezone(ev.settings.timezone)), + ev.date_admission.astimezone(ZoneInfo(ev.settings.timezone)), "TIME_FORMAT" ) if ev.date_admission else "" }), @@ -387,7 +387,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Printing date"), "editor_sample": _("2017-05-31"), "evaluate": lambda op, order, ev: date_format( - now().astimezone(timezone(ev.settings.timezone)), + now().astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATE_FORMAT" ) }), @@ -395,7 +395,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Printing date and time"), "editor_sample": _("2017-05-31 19:00"), "evaluate": lambda op, order, ev: date_format( - now().astimezone(timezone(ev.settings.timezone)), + now().astimezone(ZoneInfo(ev.settings.timezone)), "SHORT_DATETIME_FORMAT" ) }), @@ -403,7 +403,7 @@ DEFAULT_VARIABLES = OrderedDict(( "label": _("Printing time"), "editor_sample": _("19:00"), "evaluate": lambda op, order, ev: date_format( - now().astimezone(timezone(ev.settings.timezone)), + now().astimezone(ZoneInfo(ev.settings.timezone)), "TIME_FORMAT" ) if ev.date_admission else "" }), diff --git a/src/pretix/base/reldate.py b/src/pretix/base/reldate.py index 2122e2508..7459a64c3 100644 --- a/src/pretix/base/reldate.py +++ b/src/pretix/base/reldate.py @@ -22,8 +22,8 @@ import datetime from collections import namedtuple from typing import Union +from zoneinfo import ZoneInfo -import pytz from dateutil import parser from django import forms from django.core.exceptions import ValidationError @@ -67,7 +67,7 @@ class RelativeDateWrapper: if self.data.minutes_before is not None: raise ValueError('A minute-based relative datetime can not be used as a date') - tz = pytz.timezone(event.settings.timezone) + tz = ZoneInfo(event.settings.timezone) if isinstance(event, SubEvent): base_date = ( getattr(event, self.data.base_date_name) @@ -86,7 +86,7 @@ class RelativeDateWrapper: if isinstance(self.data, (datetime.datetime, datetime.date)): return self.data else: - tz = pytz.timezone(event.settings.timezone) + tz = ZoneInfo(event.settings.timezone) if isinstance(event, SubEvent): base_date = ( getattr(event, self.data.base_date_name) diff --git a/src/pretix/base/services/checkin.py b/src/pretix/base/services/checkin.py index 6706fd1ff..b1f86d8ab 100644 --- a/src/pretix/base/services/checkin.py +++ b/src/pretix/base/services/checkin.py @@ -32,7 +32,7 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under the License. import os -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from functools import partial, reduce import dateutil @@ -439,7 +439,7 @@ class SQLLogic: if operator == 'buildTime': if values[0] == "custom": - return Value(dateutil.parser.parse(values[1]).astimezone(pytz.UTC)) + return Value(dateutil.parser.parse(values[1]).astimezone(timezone.utc)) elif values[0] == "customtime": parsed = dateutil.parser.parse(values[1]) return Value(now().astimezone(self.list.event.timezone).replace( @@ -447,7 +447,7 @@ class SQLLogic: minute=parsed.minute, second=parsed.second, microsecond=parsed.microsecond, - ).astimezone(pytz.UTC)) + ).astimezone(timezone.utc)) elif values[0] == 'date_from': return Coalesce( F('subevent__date_from'), @@ -475,7 +475,7 @@ class SQLLogic: return int(values[1]) elif operator == 'var': if values[0] == 'now': - return Value(now().astimezone(pytz.UTC)) + return Value(now().astimezone(timezone.utc)) elif values[0] == 'now_isoweekday': return Value(now().astimezone(self.list.event.timezone).isoweekday()) elif values[0] == 'product': diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index b78df3802..8fe9c9ea8 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -45,8 +45,8 @@ from email.mime.image import MIMEImage from email.utils import formataddr from typing import Any, Dict, List, Sequence, Union from urllib.parse import urljoin, urlparse +from zoneinfo import ZoneInfo -import pytz import requests from bs4 import BeautifulSoup from celery import chain @@ -218,11 +218,11 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La if event: timezone = event.timezone elif user: - timezone = pytz.timezone(user.timezone) + timezone = ZoneInfo(user.timezone) elif organizer: timezone = organizer.timezone else: - timezone = pytz.timezone(settings.TIME_ZONE) + timezone = ZoneInfo(settings.TIME_ZONE) if settings_holder: if settings_holder.settings.mail_bcc: diff --git a/src/pretix/base/timeframes.py b/src/pretix/base/timeframes.py index 72b4d1fa3..617edc845 100644 --- a/src/pretix/base/timeframes.py +++ b/src/pretix/base/timeframes.py @@ -20,11 +20,10 @@ # . # import calendar -from datetime import date, datetime, time, timedelta +from datetime import date, datetime, time, timedelta, timezone from itertools import groupby from typing import Optional, Tuple -import pytz from django import forms from django.core.exceptions import ValidationError from django.utils.formats import date_format @@ -390,7 +389,7 @@ class SerializerDateFrameField(serializers.CharField): if data is None: return None try: - resolve_timeframe_to_dates_inclusive(now(), data, pytz.UTC) + resolve_timeframe_to_dates_inclusive(now(), data, timezone.utc) except: raise ValidationError("Invalid date frame") diff --git a/src/pretix/base/views/tasks.py b/src/pretix/base/views/tasks.py index 6302b3374..e7f3fe20c 100644 --- a/src/pretix/base/views/tasks.py +++ b/src/pretix/base/views/tasks.py @@ -21,9 +21,9 @@ # import logging from importlib import import_module +from zoneinfo import ZoneInfo import celery.exceptions -import pytz from celery import states from celery.result import AsyncResult from django.conf import settings @@ -252,7 +252,7 @@ class AsyncFormView(AsyncMixin, FormView): task_self = self view_instance._task_self = task_self - with translation.override(locale), timezone.override(pytz.timezone(tz)): + with translation.override(locale), timezone.override(ZoneInfo(tz)): form_class = view_instance.get_form_class() if form_kwargs.get('instance'): form_kwargs['instance'] = cls.model.objects.get(pk=form_kwargs['instance']) @@ -377,7 +377,7 @@ class AsyncPostView(AsyncMixin, View): task_self = self view_instance._task_self = task_self - with translation.override(locale), timezone.override(pytz.timezone(tz)): + with translation.override(locale), timezone.override(ZoneInfo(tz)): return view_instance.async_post(view_instance.request, *url_args, **url_kwargs) cls.async_execute = app.task( diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index d53e5e989..947026dd8 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -36,6 +36,7 @@ from decimal import Decimal from urllib.parse import urlencode, urlparse +from zoneinfo import ZoneInfo from django import forms from django.conf import settings @@ -55,7 +56,7 @@ from django_countries.fields import LazyTypedChoiceField from i18nfield.forms import ( I18nForm, I18nFormField, I18nFormSetMixin, I18nTextarea, I18nTextInput, ) -from pytz import common_timezones, timezone +from pytz import common_timezones from pretix.base.channels import get_all_sales_channels from pretix.base.email import get_available_placeholders @@ -221,7 +222,7 @@ class EventWizardBasicsForm(I18nModelForm): }) # change timezone - zone = timezone(data.get('timezone')) + zone = ZoneInfo(data.get('timezone')) data['date_from'] = self.reset_timezone(zone, data.get('date_from')) data['date_to'] = self.reset_timezone(zone, data.get('date_to')) data['presale_start'] = self.reset_timezone(zone, data.get('presale_start')) @@ -230,7 +231,7 @@ class EventWizardBasicsForm(I18nModelForm): @staticmethod def reset_timezone(tz, dt): - return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None + return dt.replace(tzinfo=tz) if dt is not None else None def clean_slug(self): slug = self.cleaned_data['slug'] diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py index 2dd0ca3d4..7043f11af 100644 --- a/src/pretix/control/logdisplay.py +++ b/src/pretix/control/logdisplay.py @@ -39,7 +39,6 @@ from decimal import Decimal import bleach import dateutil.parser -import pytz from django.dispatch import receiver from django.urls import reverse from django.utils.formats import date_format @@ -190,7 +189,7 @@ def _display_checkin(event, logentry): if 'datetime' in data: dt = dateutil.parser.parse(data.get('datetime')) show_dt = abs((logentry.datetime - dt).total_seconds()) > 5 or 'forced' in data - tz = pytz.timezone(event.settings.timezone) + tz = event.timezone dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT") if 'list' in data: @@ -582,7 +581,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs): if logentry.action_type == 'pretix.control.views.checkin': # deprecated dt = dateutil.parser.parse(data.get('datetime')) - tz = pytz.timezone(sender.settings.timezone) + tz = sender.timezone dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT") if 'list' in data: try: diff --git a/src/pretix/control/views/checkin.py b/src/pretix/control/views/checkin.py index 465a127c0..06f1cd373 100644 --- a/src/pretix/control/views/checkin.py +++ b/src/pretix/control/views/checkin.py @@ -19,18 +19,7 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # - -# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of -# the Apache License 2.0 can be obtained at . -# -# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A -# full history of changes and contributors is available at . -# -# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu -# -# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under the License. +from datetime import timezone import dateutil.parser from django.contrib import messages @@ -44,7 +33,6 @@ from django.utils.functional import cached_property from django.utils.timezone import is_aware, make_aware, now from django.utils.translation import gettext_lazy as _ from django.views.generic import ListView -from pytz import UTC from pretix.base.channels import get_all_sales_channels from pretix.base.models import Checkin, Order, OrderPosition @@ -60,6 +48,18 @@ from pretix.control.views import CreateView, PaginationMixin, UpdateView from pretix.helpers.compat import CompatDeleteView from pretix.helpers.models import modelcopy +# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of +# the Apache License 2.0 can be obtained at . +# +# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A +# full history of changes and contributors is available at . +# +# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu +# +# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under the License. + class CheckInListQueryMixin: @@ -156,20 +156,20 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList if e.last_entry: if isinstance(e.last_entry, str): # Apparently only happens on SQLite - e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), UTC) + e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), timezone.utc) elif not is_aware(e.last_entry): # Apparently only happens on MySQL - e.last_entry_aware = make_aware(e.last_entry, UTC) + e.last_entry_aware = make_aware(e.last_entry, timezone.utc) else: # This would be correct, so guess on which database it works… Yes, it's PostgreSQL. e.last_entry_aware = e.last_entry if e.last_exit: if isinstance(e.last_exit, str): # Apparently only happens on SQLite - e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), UTC) + e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), timezone.utc) elif not is_aware(e.last_exit): # Apparently only happens on MySQL - e.last_exit_aware = make_aware(e.last_exit, UTC) + e.last_exit_aware = make_aware(e.last_exit, timezone.utc) else: # This would be correct, so guess on which database it works… Yes, it's PostgreSQL. e.last_exit_aware = e.last_exit diff --git a/src/pretix/control/views/dashboards.py b/src/pretix/control/views/dashboards.py index 50746d131..31cdb8b6d 100644 --- a/src/pretix/control/views/dashboards.py +++ b/src/pretix/control/views/dashboards.py @@ -34,8 +34,8 @@ from datetime import timedelta from decimal import Decimal +from zoneinfo import ZoneInfo -import pytz from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.db.models import ( @@ -510,7 +510,7 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False): for event in events: if not lazy: tzname = event.cache.get_or_set('timezone', lambda: event.settings.timezone) - tz = pytz.timezone(tzname) + tz = ZoneInfo(tzname) if event.has_subevents: if event.min_from is None: dr = pgettext("subevent", "No dates") diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 4cc35964f..ae76a09fe 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -40,6 +40,7 @@ from collections import OrderedDict from decimal import Decimal from itertools import groupby from urllib.parse import urlsplit +from zoneinfo import ZoneInfo import bleach from django.apps import apps @@ -64,7 +65,6 @@ from django.views.generic.base import TemplateView, View from django.views.generic.detail import SingleObjectMixin from i18nfield.strings import LazyI18nString from i18nfield.utils import I18nJSONEncoder -from pytz import timezone from pretix.base.channels import get_all_sales_channels from pretix.base.email import get_available_placeholders @@ -250,7 +250,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired self.item_meta_property_formset.is_valid() and self.confirm_texts_formset.is_valid() and \ self.footer_links_formset.is_valid(): # reset timezone - zone = timezone(self.sform.cleaned_data['timezone']) + zone = ZoneInfo(self.sform.cleaned_data['timezone']) event = form.instance event.date_from = self.reset_timezone(zone, event.date_from) event.date_to = self.reset_timezone(zone, event.date_to) @@ -263,7 +263,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired @staticmethod def reset_timezone(tz, dt): - return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None + return dt.replace(tzinfo=tz) if dt is not None else None @cached_property def item_meta_property_formset(self): diff --git a/src/pretix/control/views/typeahead.py b/src/pretix/control/views/typeahead.py index 815df116f..13d76b6f1 100644 --- a/src/pretix/control/views/typeahead.py +++ b/src/pretix/control/views/typeahead.py @@ -33,8 +33,8 @@ # License for the specific language governing permissions and limitations under the License. from datetime import datetime, time +from zoneinfo import ZoneInfo -import pytz from dateutil.parser import parse from django.core.exceptions import PermissionDenied from django.db.models import F, Max, Min, Q @@ -87,7 +87,7 @@ def serialize_event(e): if e.min_from is None: dr = pgettext('subevent', 'No dates') else: - tz = pytz.timezone(e.settings.timezone) + tz = ZoneInfo(e.settings.timezone) dr = _('Series:') + ' ' + daterange( e.min_from.astimezone(tz), (e.max_fromto or e.max_to or e.max_from).astimezone(tz) diff --git a/src/pretix/plugins/checkinlists/exporters.py b/src/pretix/plugins/checkinlists/exporters.py index b0878372e..ec842f588 100644 --- a/src/pretix/plugins/checkinlists/exporters.py +++ b/src/pretix/plugins/checkinlists/exporters.py @@ -33,6 +33,7 @@ # License for the specific language governing permissions and limitations under the License. from collections import OrderedDict +from datetime import timezone import bleach import dateutil.parser @@ -47,7 +48,6 @@ from django.utils.timezone import is_aware, make_aware, now from django.utils.translation import ( gettext as _, gettext_lazy, pgettext, pgettext_lazy, ) -from pytz import UTC from reportlab.lib.units import mm from reportlab.platypus import Flowable, Paragraph, Spacer, Table, TableStyle @@ -493,7 +493,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter): elif op.last_checked_in: last_checked_in = op.last_checked_in if last_checked_in and not is_aware(last_checked_in): - last_checked_in = make_aware(last_checked_in, UTC) + last_checked_in = make_aware(last_checked_in, timezone.utc) last_checked_out = None if isinstance(op.last_checked_out, str): # SQLite @@ -501,7 +501,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter): elif op.last_checked_out: last_checked_out = op.last_checked_out if last_checked_out and not is_aware(last_checked_out): - last_checked_out = make_aware(last_checked_out, UTC) + last_checked_out = make_aware(last_checked_out, timezone.utc) row = [ op.order.code, diff --git a/src/pretix/plugins/reports/exporters.py b/src/pretix/plugins/reports/exporters.py index 88467ba41..0b67ade59 100644 --- a/src/pretix/plugins/reports/exporters.py +++ b/src/pretix/plugins/reports/exporters.py @@ -37,7 +37,6 @@ import tempfile from collections import OrderedDict, defaultdict from decimal import Decimal -import pytz from dateutil.parser import parse from django import forms from django.conf import settings @@ -83,7 +82,7 @@ class ReportlabExportMixin: return 'report-%s.pdf' % self.event.slug, 'application/pdf', self.create(form_data) def get_filename(self): - tz = pytz.timezone(self.event.settings.timezone) + tz = self.event.timezone return "%s-%s.pdf" % (self.name, now().astimezone(tz).strftime("%Y-%m-%d-%H-%M-%S")) @staticmethod @@ -444,7 +443,7 @@ class OrderTaxListReportPDF(Report): headlinestyle = self.get_style() headlinestyle.fontSize = 15 headlinestyle.fontName = 'OpenSansBd' - tz = pytz.timezone(self.event.settings.timezone) + tz = self.event.timezone tax_rates = set( a for a diff --git a/src/pretix/presale/ical.py b/src/pretix/presale/ical.py index 464827a65..bda9ee3b7 100644 --- a/src/pretix/presale/ical.py +++ b/src/pretix/presale/ical.py @@ -22,7 +22,6 @@ import datetime from urllib.parse import urlparse -import pytz import vobject from django.conf import settings from django.utils.formats import date_format @@ -41,11 +40,11 @@ def get_public_ical(events): """ cal = vobject.iCalendar() cal.add('prodid').value = '-//pretix//{}//'.format(settings.PRETIX_INSTANCE_NAME.replace(" ", "_")) - creation_time = datetime.datetime.now(pytz.utc) + creation_time = datetime.datetime.now(datetime.timezone.utc) for ev in events: event = ev if isinstance(ev, Event) else ev.event - tz = pytz.timezone(event.settings.timezone) + tz = event.timezone if isinstance(ev, Event): url = build_absolute_uri(event, 'presale:event.index') else: @@ -113,9 +112,9 @@ def get_private_icals(event, positions): - It would be pretty hard to implement it in a way that doesn't require us to use distinct settings fields for emails to customers and to attendees, which feels like an overcomplication. """ - tz = pytz.timezone(event.settings.timezone) + tz = event.timezone - creation_time = datetime.datetime.now(pytz.utc) + creation_time = datetime.datetime.now(datetime.timezone.utc) calobjects = [] evs = set(p.subevent or event for p in positions) diff --git a/src/pretix/presale/views/organizer.py b/src/pretix/presale/views/organizer.py index 2e46e1e11..5cda15341 100644 --- a/src/pretix/presale/views/organizer.py +++ b/src/pretix/presale/views/organizer.py @@ -38,10 +38,10 @@ from collections import defaultdict from datetime import date, datetime, time, timedelta from functools import reduce from urllib.parse import quote, urlencode +from zoneinfo import ZoneInfo import dateutil import isoweek -import pytz from django.conf import settings from django.core.cache import caches from django.db.models import Exists, Max, Min, OuterRef, Prefetch, Q @@ -392,7 +392,7 @@ class OrganizerIndex(OrganizerViewMixin, EventListMixin, ListView): def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) for event in ctx['events']: - event.tzname = pytz.timezone(event.cache.get_or_set('timezone', lambda: event.settings.timezone)) + event.tzname = ZoneInfo(event.cache.get_or_set('timezone', lambda: event.settings.timezone)) if event.has_subevents: event.daterange = daterange( event.min_from.astimezone(event.tzname), @@ -508,7 +508,7 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n continue timezones.add(s.timezone) - tz = pytz.timezone(s.timezone) + tz = ZoneInfo(s.timezone) datetime_from = se.date_from.astimezone(tz) date_from = datetime_from.date() if s.show_date_to and se.date_to: diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index 1e51abd05..b83884978 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -26,9 +26,9 @@ import logging from collections import defaultdict from datetime import date, datetime, timedelta from urllib.parse import urljoin +from zoneinfo import ZoneInfo import isoweek -import pytz from compressor.filters.jsmin import rJSMinFilter from django.conf import settings from django.contrib.staticfiles import finders @@ -427,7 +427,7 @@ class WidgetAPIProductList(EventListMixin, View): event = ev.event else: event = ev - tz = pytz.timezone(e['timezone']) + tz = ZoneInfo(e['timezone']) time = date_format(ev.date_from.astimezone(tz), 'TIME_FORMAT') if e.get('time') and event.settings.show_times else None if time and ev.date_to and ev.date_from.astimezone(tz).date() == ev.date_to.astimezone(tz).date() and event.settings.show_date_to: time += ' – ' + date_format(ev.date_to.astimezone(tz), 'TIME_FORMAT') @@ -607,7 +607,7 @@ class WidgetAPIProductList(EventListMixin, View): data['events'] = [] qs = self._get_event_queryset() for event in qs: - tz = pytz.timezone(event.cache.get_or_set('timezone', lambda: event.settings.timezone)) + tz = ZoneInfo(event.cache.get_or_set('timezone', lambda: event.settings.timezone)) if event.has_subevents: dr = daterange( event.min_from.astimezone(tz), diff --git a/src/setup.py b/src/setup.py index ce3dfc876..d8f985fb0 100644 --- a/src/setup.py +++ b/src/setup.py @@ -217,6 +217,7 @@ setup( 'python-dateutil==2.8.*', 'python-u2flib-server==4.*', 'pytz', + 'pytz-deprecation-shim==0.1.*', 'pyuca', 'redis==4.4.*', 'reportlab==3.6.*', diff --git a/src/tests/api/conftest.py b/src/tests/api/conftest.py index 860d77c3d..5e9a3b8ca 100644 --- a/src/tests/api/conftest.py +++ b/src/tests/api/conftest.py @@ -32,13 +32,12 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under the License. -from datetime import datetime +from datetime import datetime, timezone import pytest from django.test import utils from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from rest_framework.test import APIClient from pretix.base.models import Device, Event, Organizer, Team, User @@ -67,7 +66,7 @@ def meta_prop(organizer): def event(organizer, meta_prop): e = Event.objects.create( organizer=organizer, name='Dummy', slug='dummy', - date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC), + date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf', is_public=True ) @@ -82,7 +81,7 @@ def event(organizer, meta_prop): def event2(organizer, meta_prop): e = Event.objects.create( organizer=organizer, name='Dummy2', slug='dummy2', - date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC), + date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf' ) e.meta_values.create(property=meta_prop, value="Conference") @@ -94,7 +93,7 @@ def event2(organizer, meta_prop): def event3(organizer, meta_prop): e = Event.objects.create( organizer=organizer, name='Dummy3', slug='dummy3', - date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC), + date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf' ) e.meta_values.create(property=meta_prop, value="Conference") @@ -172,7 +171,7 @@ def device_client(client, device): def subevent(event, meta_prop): event.has_subevents = True event.save() - se = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) se.meta_values.create(property=meta_prop, value="Workshop") return se @@ -183,7 +182,7 @@ def subevent(event, meta_prop): def subevent2(event2, meta_prop): event2.has_subevents = True event2.save() - se = event2.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se = event2.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) se.meta_values.create(property=meta_prop, value="Workshop") return se diff --git a/src/tests/api/test_cart.py b/src/tests/api/test_cart.py index 8849d6448..4767411c2 100644 --- a/src/tests/api/test_cart.py +++ b/src/tests/api/test_cart.py @@ -28,7 +28,6 @@ import pytest from django.core.files.base import ContentFile from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.base.models import Question, SeatingPlan @@ -95,15 +94,15 @@ TEST_CARTPOSITION_RES = { @pytest.mark.django_db def test_cp_list(token_client, organizer, event, item, taxrule, question): - testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime cr = CartPosition.objects.create( event=event, cart_id="aaa", item=item, price=23, attendee_name_parts={'full_name': 'Peter'}, - datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) ) res = dict(TEST_CARTPOSITION_RES) res["id"] = cr.pk @@ -116,15 +115,15 @@ def test_cp_list(token_client, organizer, event, item, taxrule, question): @pytest.mark.django_db def test_cp_list_api(token_client, organizer, event, item, taxrule, question): - testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime cr = CartPosition.objects.create( event=event, cart_id="aaa@api", item=item, price=23, attendee_name_parts={'full_name': 'Peter'}, - datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) ) res = dict(TEST_CARTPOSITION_RES) res["id"] = cr.pk @@ -137,15 +136,15 @@ def test_cp_list_api(token_client, organizer, event, item, taxrule, question): @pytest.mark.django_db def test_cp_detail(token_client, organizer, event, item, taxrule, question): - testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime cr = CartPosition.objects.create( event=event, cart_id="aaa@api", item=item, price=23, attendee_name_parts={'full_name': 'Peter'}, - datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) ) res = dict(TEST_CARTPOSITION_RES) res["id"] = cr.pk @@ -158,21 +157,21 @@ def test_cp_detail(token_client, organizer, event, item, taxrule, question): @pytest.mark.django_db def test_cp_delete(token_client, organizer, event, item, taxrule, question): - testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime cr = CartPosition.objects.create( event=event, cart_id="aaa@api", item=item, price=23, attendee_name_parts={'full_name': 'Peter'}, - datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) ) CartPosition.objects.create( event=event, cart_id="aaa@api", item=item, addon_to=cr, price=23, attendee_name_parts={'full_name': 'Peter'}, - datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC) + datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc) ) res = dict(TEST_CARTPOSITION_RES) res["id"] = cr.pk diff --git a/src/tests/api/test_checkin.py b/src/tests/api/test_checkin.py index 6d76e13a8..f2133b8a6 100644 --- a/src/tests/api/test_checkin.py +++ b/src/tests/api/test_checkin.py @@ -31,7 +31,6 @@ from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled from i18nfield.strings import LazyI18nString -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.api.serializers.item import QuestionSerializer @@ -57,15 +56,15 @@ def other_item(event): @pytest.fixture def order(event, item, other_item, taxrule): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PAID, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=46, locale='en' ) InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ')) @@ -249,7 +248,7 @@ def test_list_list(token_client, organizer, event, clist, item, subevent, django '/api/v1/organizers/{}/events/{}/checkinlists/?subevent_match={}'.format(organizer.slug, event.slug, subevent.pk)) assert [res] == resp.data['results'] with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) resp = token_client.get( '/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) assert [] == resp.data['results'] @@ -568,7 +567,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a @pytest.mark.django_db def test_list_all_items_positions_by_subevent(token_client, organizer, event, clist, clist_all, item, other_item, order, subevent): with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) pfirst = order.positions.get(positionid=1) pfirst.subevent = se2 pfirst.save() diff --git a/src/tests/api/test_checkinrpc.py b/src/tests/api/test_checkinrpc.py index 8a9e93efe..22c08984a 100644 --- a/src/tests/api/test_checkinrpc.py +++ b/src/tests/api/test_checkinrpc.py @@ -29,7 +29,6 @@ from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled from i18nfield.strings import LazyI18nString -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.api.serializers.item import QuestionSerializer @@ -57,15 +56,15 @@ def other_item(event): @pytest.fixture def order(event, item, other_item, taxrule): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PAID, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=46, locale='en' ) InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ')) @@ -104,15 +103,15 @@ def order(event, item, other_item, taxrule): @pytest.fixture def order2(event2, item_on_event2): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='BAR', event=event2, email='dummy@dummy.test', status=Order.STATUS_PAID, secret="ylptCPNOxTyA", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=46, locale='en' ) InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ')) diff --git a/src/tests/api/test_device_event_selection.py b/src/tests/api/test_device_event_selection.py index 9dc823d30..c8a309065 100644 --- a/src/tests/api/test_device_event_selection.py +++ b/src/tests/api/test_device_event_selection.py @@ -20,13 +20,13 @@ # . # from datetime import datetime +from zoneinfo import ZoneInfo import pytest -import pytz from django_scopes import scopes_disabled from freezegun import freeze_time -tz = pytz.timezone("Asia/Tokyo") +tz = ZoneInfo("Asia/Tokyo") @pytest.mark.django_db @@ -40,22 +40,22 @@ def test_choose_between_events(device_client, device): with scopes_disabled(): e1 = device.organizer.events.create( name="Event", slug="e1", live=True, - date_from=tz.localize(datetime(2020, 1, 10, 14, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 15, 0)), + date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz), ) cl1 = e1.checkin_lists.create(name="Same name") e2 = device.organizer.events.create( name="Event", slug="e2", live=True, - date_from=tz.localize(datetime(2020, 1, 10, 16, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 17, 0)), + date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz), ) e2.checkin_lists.create(name="Other name") cl2 = e2.checkin_lists.create(name="Same name") e2.checkin_lists.create(name="Yet another name") tomorrow = device.organizer.events.create( name="Event", slug="tomorrow", live=True, - date_from=tz.localize(datetime(2020, 1, 11, 15, 0)), - date_to=tz.localize(datetime(2020, 1, 11, 16, 0)), + date_from=datetime(2020, 1, 11, 15, 0, tzinfo=tz), + date_to=datetime(2020, 1, 11, 16, 0, tzinfo=tz), ) cl3 = tomorrow.checkin_lists.create(name="Just any name") for e in device.organizer.events.all(): @@ -117,7 +117,7 @@ def test_choose_between_events(device_client, device): assert resp.data['event']['slug'] == 'e2' # check for overlapping events - e2.date_admission = tz.localize(datetime(2020, 1, 10, 14, 45)) + e2.date_admission = datetime(2020, 1, 10, 14, 45, tzinfo=tz) e2.save() with freeze_time("2020-01-10T14:45:00+09:00"): resp = device_client.get('/api/v1/device/eventselection?current_event=e1') @@ -131,28 +131,28 @@ def test_choose_between_subevents(device_client, device): with scopes_disabled(): e = device.organizer.events.create( name="Event", slug="e1", live=True, - date_from=tz.localize(datetime(2020, 1, 10, 14, 0)), + date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz), has_subevents=True, ) e.settings.timezone = "Asia/Tokyo" se1 = e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 10, 14, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 15, 0)), + date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz), ) cl1 = e.checkin_lists.create(name="Same name", subevent=se1) se2 = e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 10, 16, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 17, 0)), + date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz), ) cl2 = e.checkin_lists.create(name="Same name", subevent=se2) cl3 = e.checkin_lists.create(name="Other name") e.checkin_lists.create(name="Yet another name", subevent=se2) se_tomorrow = e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 11, 15, 0)), - date_to=tz.localize(datetime(2020, 1, 11, 16, 0)), + date_from=datetime(2020, 1, 11, 15, 0, tzinfo=tz), + date_to=datetime(2020, 1, 11, 16, 0, tzinfo=tz), ) with freeze_time("2020-01-10T14:30:00+09:00"): resp = device_client.get(f'/api/v1/device/eventselection?current_event=e1¤t_subevent={se1.pk}') @@ -217,7 +217,7 @@ def test_choose_between_subevents(device_client, device): assert resp.data['subevent'] == se2.pk # check for overlapping events - se2.date_admission = tz.localize(datetime(2020, 1, 10, 14, 45)) + se2.date_admission = datetime(2020, 1, 10, 14, 45, tzinfo=tz) se2.save() with freeze_time("2020-01-10T14:45:00+09:00"): resp = device_client.get(f'/api/v1/device/eventselection?current_event=e1¤t_subevent={se1.pk}') @@ -234,25 +234,25 @@ def test_require_gate(device_client, device): device.save() e = device.organizer.events.create( name="Event", slug="e1", live=True, - date_from=tz.localize(datetime(2020, 1, 10, 14, 0)), + date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz), has_subevents=True, ) e.settings.timezone = "Asia/Tokyo" se0 = e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 10, 9, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 10, 0)), + date_from=datetime(2020, 1, 10, 9, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 10, 0, tzinfo=tz), ) e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 10, 14, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 15, 0)), + date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz), ) cl1 = e.checkin_lists.create(name="Same name", subevent=se0) se2 = e.subevents.create( name="Event", active=True, - date_from=tz.localize(datetime(2020, 1, 10, 16, 0)), - date_to=tz.localize(datetime(2020, 1, 10, 17, 0)), + date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz), + date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz), ) e.checkin_lists.create(name="Same name", subevent=se2) cl3 = e.checkin_lists.create(name="Other name", subevent=se2) diff --git a/src/tests/api/test_events.py b/src/tests/api/test_events.py index 6745d4423..c57e7953e 100644 --- a/src/tests/api/test_events.py +++ b/src/tests/api/test_events.py @@ -33,7 +33,7 @@ # License for the specific language governing permissions and limitations under the License. import copy -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from decimal import Decimal from unittest import mock @@ -43,7 +43,6 @@ from django.core.files.base import ContentFile from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.base.models import ( @@ -63,15 +62,15 @@ def variations(item): @pytest.fixture def order(event, item, taxrule): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc), + expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc), total=23, locale='en' ) o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'), diff --git a/src/tests/api/test_invoices.py b/src/tests/api/test_invoices.py index cefe96316..ef5e84e5f 100644 --- a/src/tests/api/test_invoices.py +++ b/src/tests/api/test_invoices.py @@ -27,7 +27,6 @@ import freezegun import pytest from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import InvoiceAddress, Order, OrderPosition from pretix.base.models.orders import OrderFee @@ -75,7 +74,7 @@ def quota(event, item): @pytest.fixture def order(event, item, taxrule, question): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) event.plugins += ",pretix.plugins.stripe" event.save() @@ -84,8 +83,8 @@ def order(event, item, taxrule, question): o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=23, locale='en' ) p1 = o.payments.create( @@ -140,7 +139,7 @@ def order(event, item, taxrule, question): @pytest.fixture def invoice(order): - testtime = datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime diff --git a/src/tests/api/test_items.py b/src/tests/api/test_items.py index 7f96d9365..b0ac60990 100644 --- a/src/tests/api/test_items.py +++ b/src/tests/api/test_items.py @@ -33,7 +33,7 @@ # License for the specific language governing permissions and limitations under the License. import os import time -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from decimal import Decimal from unittest import mock @@ -42,7 +42,6 @@ from django.conf import settings from django.core.files.base import ContentFile from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.base.channels import get_all_sales_channels @@ -73,15 +72,15 @@ def category3(event, item): @pytest.fixture def order(event, item, taxrule): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc), + expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc), total=23, locale='en' ) o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'), @@ -108,7 +107,7 @@ def order_position(item, order, taxrule, variations): @pytest.fixture def cart_position(event, item, variations): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime @@ -1771,7 +1770,7 @@ def test_quota_list(token_client, organizer, event, quota, item, subevent): '/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) assert [res] == resp.data['results'] with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) resp = token_client.get( '/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) assert [] == resp.data['results'] diff --git a/src/tests/api/test_membership.py b/src/tests/api/test_membership.py index a7d52770d..356762cb8 100644 --- a/src/tests/api/test_membership.py +++ b/src/tests/api/test_membership.py @@ -19,10 +19,9 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -from datetime import datetime +from datetime import datetime, timezone import pytest -import pytz from django_scopes import scopes_disabled from i18nfield.strings import LazyI18nString @@ -54,8 +53,8 @@ def customer(organizer): def membership(organizer, customer, membershiptype): return customer.memberships.create( membership_type=membershiptype, - date_start=datetime(2021, 4, 1, 0, 0, 0, 0, tzinfo=pytz.UTC), - date_end=datetime(2021, 4, 8, 23, 59, 59, 999999, tzinfo=pytz.UTC), + date_start=datetime(2021, 4, 1, 0, 0, 0, 0, tzinfo=timezone.utc), + date_end=datetime(2021, 4, 8, 23, 59, 59, 999999, tzinfo=timezone.utc), attendee_name_parts={ "_scheme": "given_family", 'given_name': 'John', diff --git a/src/tests/api/test_order_change.py b/src/tests/api/test_order_change.py index da78eba7a..e06085c5d 100644 --- a/src/tests/api/test_order_change.py +++ b/src/tests/api/test_order_change.py @@ -30,7 +30,6 @@ from django.core.files.base import ContentFile from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.base.models import ( @@ -90,7 +89,7 @@ def seat(event, organizer, item): @pytest.fixture def order(event, item, taxrule, question): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) event.plugins += ",pretix.plugins.stripe" event.save() @@ -99,8 +98,8 @@ def order(event, item, taxrule, question): o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=23, locale='en' ) p1 = o.payments.create( @@ -659,7 +658,7 @@ def test_orderposition_price_calculation_subevent(token_client, organizer, event def test_orderposition_price_calculation_subevent_with_override(token_client, organizer, event, order, subevent): with scopes_disabled(): item2 = event.items.create(name="Budget Ticket", default_price=23) - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) se2.subeventitem_set.create(item=item2, price=12) op = order.positions.first() op.subevent = subevent @@ -1201,7 +1200,7 @@ def test_position_update_change_item_variation_mismatch(token_client, organizer, @pytest.mark.django_db def test_position_update_change_subevent(token_client, organizer, event, order, quota, item, subevent): with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) q2 = se2.quotas.create(name="foo", size=1, event=event) q2.items.add(item) op = order.positions.first() @@ -1223,7 +1222,7 @@ def test_position_update_change_subevent(token_client, organizer, event, order, @pytest.mark.django_db def test_position_update_change_subevent_quota_empty(token_client, organizer, event, order, quota, item, subevent): with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) q2 = se2.quotas.create(name="foo", size=0, event=event) q2.items.add(item) op = order.positions.first() @@ -1304,7 +1303,7 @@ def test_position_update_change_subevent_keep_seat(token_client, organizer, even with scopes_disabled(): seat.subevent = subevent seat.save() - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) seat2 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2) q2 = se2.quotas.create(name="foo", size=1, event=event) q2.items.add(item) @@ -1331,7 +1330,7 @@ def test_position_update_change_subevent_missing_seat(token_client, organizer, e with scopes_disabled(): seat.subevent = subevent seat.save() - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc)) q2 = se2.quotas.create(name="foo", size=1, event=event) q2.items.add(item) op = order.positions.first() diff --git a/src/tests/api/test_order_create.py b/src/tests/api/test_order_create.py index 4cc127317..4533b9e63 100644 --- a/src/tests/api/test_order_create.py +++ b/src/tests/api/test_order_create.py @@ -31,7 +31,6 @@ from django.core.files.base import ContentFile from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from tests.const import SAMPLE_PNG from pretix.base.models import ( @@ -79,7 +78,7 @@ def quota(event, item): @pytest.fixture def order(event, item, taxrule, question): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) event.plugins += ",pretix.plugins.stripe" event.save() @@ -88,8 +87,8 @@ def order(event, item, taxrule, question): o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=23, locale='en' ) p1 = o.payments.create( diff --git a/src/tests/api/test_orders.py b/src/tests/api/test_orders.py index 0a205ec69..033333473 100644 --- a/src/tests/api/test_orders.py +++ b/src/tests/api/test_orders.py @@ -30,7 +30,6 @@ from django.core import mail as djmail from django.utils.timezone import now from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from stripe.error import APIConnectionError from tests.plugins.stripe.test_provider import MockedCharge @@ -77,7 +76,7 @@ def quota(event, item): @pytest.fixture def order(event, item, taxrule, question): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) event.plugins += ",pretix.plugins.stripe" event.save() @@ -86,8 +85,8 @@ def order(event, item, taxrule, question): o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc), + expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc), total=23, locale='en' ) p1 = o.payments.create( @@ -928,8 +927,8 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven with scopes_disabled(): cl = event.checkin_lists.create(name="Default") - c = op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl) - op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl, successful=False) + c = op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=datetime.timezone.utc), list=cl) + op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=datetime.timezone.utc), list=cl, successful=False) res['checkins'] = [{ # successful only 'id': c.pk, 'datetime': '2017-12-26T10:00:00Z', diff --git a/src/tests/api/test_shredders.py b/src/tests/api/test_shredders.py index 938ee132c..ca518c95f 100644 --- a/src/tests/api/test_shredders.py +++ b/src/tests/api/test_shredders.py @@ -34,13 +34,12 @@ import copy import uuid -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from decimal import Decimal import pytest from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import Order, OrderPosition @@ -56,8 +55,8 @@ def order(event, item): o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc), + expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc), total=23, locale='en' ) OrderPosition.objects.create( diff --git a/src/tests/api/test_subevents.py b/src/tests/api/test_subevents.py index 03846183f..f6258c21d 100644 --- a/src/tests/api/test_subevents.py +++ b/src/tests/api/test_subevents.py @@ -19,14 +19,13 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -from datetime import datetime +from datetime import datetime, timezone from decimal import Decimal from unittest import mock import pytest from django_countries.fields import Country from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import ( InvoiceAddress, Order, OrderPosition, SeatingPlan, SubEvent, @@ -52,15 +51,15 @@ def variations2(item2): @pytest.fixture def order(event, item, taxrule): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime o = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1", - datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC), - expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC), + datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc), + expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc), total=23, locale='en' ) o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'), @@ -344,8 +343,8 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2, assert resp.status_code == 200 with scopes_disabled(): subevent = event.subevents.get(id=subevent.id) - assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=UTC) - assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=UTC) + assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=timezone.utc) + assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=timezone.utc) resp = token_client.patch( '/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug, subevent.pk), diff --git a/src/tests/api/test_vouchers.py b/src/tests/api/test_vouchers.py index ba1d180bf..ee93311a5 100644 --- a/src/tests/api/test_vouchers.py +++ b/src/tests/api/test_vouchers.py @@ -40,7 +40,6 @@ import pytest from django.utils import timezone from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import Event, SeatingPlan, Voucher @@ -249,7 +248,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube '/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) assert [res] == resp.data['results'] with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) resp = token_client.get( '/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) @@ -611,7 +610,7 @@ def test_change_to_item_of_other_event(token_client, organizer, event, item): organizer=organizer, name='Dummy2', slug='dummy2', - date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC), + date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf' ) ticket2 = e2.items.create(name='Late-bird ticket', default_price=23) @@ -1254,8 +1253,8 @@ def test_set_seat_subevent(token_client, organizer, event, seatingplan, seat1, i with scopes_disabled(): event.has_subevents = True event.save() - se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) - se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) + se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1) event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2) v = event.vouchers.create(item=item) @@ -1277,8 +1276,8 @@ def test_set_seat_subevent_required(token_client, organizer, event, seatingplan, with scopes_disabled(): event.has_subevents = True event.save() - se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) - se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) + se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1) event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2) event.vouchers.create(item=item, seat=seat1) @@ -1297,8 +1296,8 @@ def test_set_seat_subevent_invalid(token_client, organizer, event, seatingplan, with scopes_disabled(): event.has_subevents = True event.save() - se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) - se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) + se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc)) seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1) event.seats.create(seat_number="B1", product=item, seat_guid="B1", subevent=se2) event.vouchers.create(item=item, seat=seat1, subevent=se2) diff --git a/src/tests/api/test_waitinglist.py b/src/tests/api/test_waitinglist.py index cf99b126a..79e3449a3 100644 --- a/src/tests/api/test_waitinglist.py +++ b/src/tests/api/test_waitinglist.py @@ -25,7 +25,6 @@ from unittest import mock import pytest from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import WaitingListEntry @@ -44,7 +43,7 @@ def quota(event, item): @pytest.fixture def wle(event, item): - testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.UTC) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime @@ -140,7 +139,7 @@ def test_wle_list(token_client, organizer, event, wle, item, subevent): '/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) assert [res] == resp.data['results'] with scopes_disabled(): - se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) + se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.UTC)) resp = token_client.get( '/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) diff --git a/src/tests/base/test_export.py b/src/tests/base/test_export.py index 892f98f5c..b5813062f 100644 --- a/src/tests/base/test_export.py +++ b/src/tests/base/test_export.py @@ -19,10 +19,9 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -from datetime import datetime, time, timedelta +from datetime import datetime, time, timedelta, timezone import pytest -import pytz from django.core import mail as djmail from django.utils.timezone import now from django_scopes import scope @@ -39,7 +38,7 @@ def event(): o = Organizer.objects.create(name='Dummy', slug='dummy') event = Event.objects.create( organizer=o, name='Dummy', slug='dummy', - date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=pytz.UTC), + date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer' ) o.settings.timezone = "Europe/Berlin" @@ -304,7 +303,7 @@ def test_organizer_limited_to_events(event, user, team): event2 = Event.objects.create( organizer=event.organizer, name='Dummy', slug='dummy2', - date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=pytz.UTC), + date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer' ) team.all_events = False @@ -344,7 +343,7 @@ def test_organizer_ok(event, user, team): Event.objects.create( organizer=event.organizer, name='Dummy', slug='dummy2', - date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=pytz.UTC), + date_from=datetime(2023, 1, 19, 2, 30, 0, tzinfo=timezone.utc), plugins='pretix.plugins.banktransfer' ) diff --git a/src/tests/base/test_memberships.py b/src/tests/base/test_memberships.py index 93f1ce0a4..5650b9af7 100644 --- a/src/tests/base/test_memberships.py +++ b/src/tests/base/test_memberships.py @@ -21,9 +21,9 @@ # from datetime import datetime, timedelta from decimal import Decimal +from zoneinfo import ZoneInfo import pytest -import pytz from django.conf import settings from django.core.exceptions import ValidationError from django.utils.timezone import now @@ -42,7 +42,7 @@ from pretix.base.services.orders import ( ) from pretix.plugins.banktransfer.payment import BankTransfer -TZ = pytz.timezone('Europe/Berlin') +TZ = ZoneInfo('Europe/Berlin') @pytest.fixture(scope='function') @@ -51,9 +51,9 @@ def event(): o.settings.customer_accounts = True event = Event.objects.create( organizer=o, name='Dummy', slug='dummy', - date_from=TZ.localize(datetime(2021, 4, 27, 10, 0, 0, 0)), - date_to=TZ.localize(datetime(2021, 4, 28, 10, 0, 0, 0)), - presale_end=TZ.localize(datetime(2221, 4, 28, 10, 0, 0, 0)), + date_from=datetime(2021, 4, 27, 10, 0, 0, 0, tzinfo=TZ), + date_to=datetime(2021, 4, 28, 10, 0, 0, 0, tzinfo=TZ), + presale_end=datetime(2221, 4, 28, 10, 0, 0, 0, tzinfo=TZ), plugins='pretix.plugins.banktransfer' ) event.settings.timezone = 'Europe/Berlin' @@ -75,8 +75,8 @@ def membership_type(event): def membership(event, membership_type, customer): return customer.memberships.create( membership_type=membership_type, - date_start=TZ.localize(datetime(2021, 4, 1, 0, 0, 0, 0)), - date_end=TZ.localize(datetime(2021, 4, 30, 23, 59, 59, 999999)), + date_start=datetime(2021, 4, 1, 0, 0, 0, 0, tzinfo=TZ), + date_end=datetime(2021, 4, 30, 23, 59, 59, 999999, tzinfo=TZ), ) @@ -107,7 +107,7 @@ def subevent(event): event.has_subevents = True return event.subevents.create( name='Foo', - date_from=TZ.localize(datetime(2021, 4, 29, 10, 0, 0, 0)), + date_from=datetime(2021, 4, 29, 10, 0, 0, 0, tzinfo=TZ), ) @@ -115,8 +115,8 @@ def subevent(event): def test_validity_membership_duration_like_event(event, granting_ticket, membership_type): granting_ticket.grant_membership_duration_like_event = True assert membership_validity(granting_ticket, None, event) == ( - TZ.localize(datetime(2021, 4, 27, 10, 0, 0, 0)), - TZ.localize(datetime(2021, 4, 28, 10, 0, 0, 0)), + datetime(2021, 4, 27, 10, 0, 0, 0, tzinfo=TZ), + datetime(2021, 4, 28, 10, 0, 0, 0, tzinfo=TZ), ) @@ -124,8 +124,8 @@ def test_validity_membership_duration_like_event(event, granting_ticket, members def test_validity_membership_duration_like_subevent_without_end(event, granting_ticket, subevent, membership_type): granting_ticket.grant_membership_duration_like_event = True assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 4, 29, 10, 0, 0, 0)), - TZ.localize(datetime(2021, 4, 29, 23, 59, 59, 999999)), + datetime(2021, 4, 29, 10, 0, 0, 0, tzinfo=TZ), + datetime(2021, 4, 29, 23, 59, 59, 999999, tzinfo=TZ), ) @@ -135,8 +135,8 @@ def test_validity_membership_duration_days(event, granting_ticket, membership_ty granting_ticket.grant_membership_duration_days = 3 with freeze_time("2021-04-10T11:00:00+02:00"): assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 4, 10, 0, 0, 0, 0)), - TZ.localize(datetime(2021, 4, 12, 23, 59, 59, 999999)), + datetime(2021, 4, 10, 0, 0, 0, 0, tzinfo=TZ), + datetime(2021, 4, 12, 23, 59, 59, 999999, tzinfo=TZ), ) @@ -146,13 +146,13 @@ def test_validity_membership_duration_months(event, granting_ticket, membership_ granting_ticket.grant_membership_duration_months = 1 with freeze_time("2021-02-01T11:00:00+01:00"): assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 2, 1, 0, 0, 0, 0)), - TZ.localize(datetime(2021, 2, 28, 23, 59, 59, 999999)), + datetime(2021, 2, 1, 0, 0, 0, 0, tzinfo=TZ), + datetime(2021, 2, 28, 23, 59, 59, 999999, tzinfo=TZ), ) with freeze_time("2021-02-28T11:00:00+01:00"): assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 2, 28, 0, 0, 0, 0)), - TZ.localize(datetime(2021, 3, 27, 23, 59, 59, 999999)), + datetime(2021, 2, 28, 0, 0, 0, 0, tzinfo=TZ), + datetime(2021, 3, 27, 23, 59, 59, 999999, tzinfo=TZ), ) @@ -163,13 +163,13 @@ def test_validity_membership_duration_months_plus_days(event, granting_ticket, m granting_ticket.grant_membership_duration_days = 2 with freeze_time("2021-02-01T11:00:00+01:00"): assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 2, 1, 0, 0, 0, 0)), - TZ.localize(datetime(2021, 3, 2, 23, 59, 59, 999999)), + datetime(2021, 2, 1, 0, 0, 0, 0, tzinfo=TZ), + datetime(2021, 3, 2, 23, 59, 59, 999999, tzinfo=TZ), ) with freeze_time("2021-02-28T11:00:00+01:00"): assert membership_validity(granting_ticket, subevent, event) == ( - TZ.localize(datetime(2021, 2, 28, 0, 0, 0, 0)), - TZ.localize(datetime(2021, 3, 29, 23, 59, 59, 999999)), + datetime(2021, 2, 28, 0, 0, 0, 0, tzinfo=TZ), + datetime(2021, 3, 29, 23, 59, 59, 999999, tzinfo=TZ), ) @@ -420,7 +420,7 @@ def test_validate_membership_max_usages(event, customer, membership, requiring_t def test_validate_membership_parallel(event, customer, membership, subevent, requiring_ticket, membership_type): se2 = event.subevents.create( name='Foo', - date_from=TZ.localize(datetime(2021, 4, 28, 10, 0, 0, 0)), + date_from=datetime(2021, 4, 28, 10, 0, 0, 0, tzinfo=TZ), ) membership_type.allow_parallel_usage = False @@ -585,5 +585,5 @@ def test_grant_when_paid_and_changed(event, customer, granting_ticket): m = customer.memberships.get() assert m.granted_in == order.positions.first() assert m.membership_type == granting_ticket.grant_membership_type - assert m.date_start == TZ.localize(datetime(2021, 4, 27, 10, 0, 0, 0)) - assert m.date_end == TZ.localize(datetime(2021, 4, 28, 10, 0, 0, 0)) + assert m.date_start == datetime(2021, 4, 27, 10, 0, 0, 0, tzinfo=TZ) + assert m.date_end == datetime(2021, 4, 28, 10, 0, 0, 0, tzinfo=TZ) diff --git a/src/tests/base/test_models.py b/src/tests/base/test_models.py index eb621ad9f..013491b9b 100644 --- a/src/tests/base/test_models.py +++ b/src/tests/base/test_models.py @@ -39,7 +39,6 @@ from datetime import date, timedelta from decimal import Decimal import pytest -import pytz from dateutil.tz import tzoffset from django.conf import settings from django.core.exceptions import ValidationError @@ -1188,13 +1187,13 @@ class OrderTestCase(BaseQuotaTestCase): @classscope(attr='o') def test_payment_term_last_relative(self): self.event.settings.set('payment_term_last', date(2017, 5, 3)) - assert self.order.payment_term_last == datetime.datetime(2017, 5, 3, 23, 59, 59, tzinfo=pytz.UTC) - self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=pytz.UTC) + assert self.order.payment_term_last == datetime.datetime(2017, 5, 3, 23, 59, 59, tzinfo=datetime.timezone.utc) + self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=datetime.timezone.utc) self.event.save() self.event.settings.set('payment_term_last', RelativeDateWrapper( RelativeDate(days_before=2, time=None, base_date_name='date_from', minutes_before=None) )) - assert self.order.payment_term_last == datetime.datetime(2017, 5, 1, 23, 59, 59, tzinfo=pytz.UTC) + assert self.order.payment_term_last == datetime.datetime(2017, 5, 1, 23, 59, 59, tzinfo=datetime.timezone.utc) @classscope(attr='o') def test_payment_term_last_subevent(self): @@ -1219,14 +1218,14 @@ class OrderTestCase(BaseQuotaTestCase): @classscope(attr='o') def test_ticket_download_date_relative(self): - self.event.settings.set('ticket_download_date', datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC)) - assert self.order.ticket_download_date == datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC) - self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=pytz.UTC) + self.event.settings.set('ticket_download_date', datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=datetime.timezone.utc)) + assert self.order.ticket_download_date == datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=datetime.timezone.utc) + self.event.date_from = datetime.datetime(2017, 5, 3, 12, 0, 0, tzinfo=datetime.timezone.utc) self.event.save() self.event.settings.set('ticket_download_date', RelativeDateWrapper( RelativeDate(days_before=2, time=None, base_date_name='date_from', minutes_before=None) )) - assert self.order.ticket_download_date == datetime.datetime(2017, 5, 1, 12, 0, 0, tzinfo=pytz.UTC) + assert self.order.ticket_download_date == datetime.datetime(2017, 5, 1, 12, 0, 0, tzinfo=datetime.timezone.utc) @classscope(attr='o') def test_ticket_download_date_subevent(self): diff --git a/src/tests/base/test_orders.py b/src/tests/base/test_orders.py index 1fd712b05..2e46143f4 100644 --- a/src/tests/base/test_orders.py +++ b/src/tests/base/test_orders.py @@ -22,9 +22,9 @@ import json from datetime import datetime, timedelta from decimal import Decimal +from zoneinfo import ZoneInfo import pytest -import pytz from django.core import mail as djmail from django.db.models import F, Sum from django.test import TestCase @@ -255,9 +255,9 @@ def test_expiry_last_relative_subevents(event): @pytest.mark.django_db def test_expiry_dst(event): event.settings.set('timezone', 'Europe/Berlin') - tz = pytz.timezone('Europe/Berlin') - utc = pytz.timezone('UTC') - today = tz.localize(datetime(2016, 10, 29, 12, 0, 0)).astimezone(utc) + tz = ZoneInfo('Europe/Berlin') + utc = ZoneInfo('UTC') + today = datetime(2016, 10, 29, 12, 0, 0, tzinfo=tz).astimezone(utc) order = _create_order(event, email='dummy@example.org', positions=[], now_dt=today, payment_requests=[{ diff --git a/src/tests/base/test_payment.py b/src/tests/base/test_payment.py index a6d830f35..f3983ac20 100644 --- a/src/tests/base/test_payment.py +++ b/src/tests/base/test_payment.py @@ -34,9 +34,9 @@ import datetime from decimal import Decimal +from zoneinfo import ZoneInfo import pytest -import pytz from django.utils.timezone import now from django_scopes import scope from tests.testdummy.payment import DummyPaymentProvider @@ -112,18 +112,18 @@ def test_availability_date_not_available(event): @pytest.mark.django_db def test_availability_date_relative(event): event.settings.set('timezone', 'US/Pacific') - tz = pytz.timezone('US/Pacific') - event.date_from = tz.localize(datetime.datetime(2016, 12, 3, 12, 0, 0)) + tz = ZoneInfo('US/Pacific') + event.date_from = datetime.datetime(2016, 12, 3, 12, 0, 0, tzinfo=tz) event.save() prov = DummyPaymentProvider(event) prov.settings.set('_availability_date', RelativeDateWrapper( RelativeDate(days_before=2, time=None, base_date_name='date_from', minutes_before=None) )) - utc = pytz.timezone('UTC') - assert prov._is_still_available(tz.localize(datetime.datetime(2016, 11, 30, 23, 0, 0)).astimezone(utc)) - assert prov._is_still_available(tz.localize(datetime.datetime(2016, 12, 1, 23, 59, 0)).astimezone(utc)) - assert not prov._is_still_available(tz.localize(datetime.datetime(2016, 12, 2, 0, 0, 1)).astimezone(utc)) + utc = datetime.timezone.utc + assert prov._is_still_available(datetime.datetime(2016, 11, 30, 23, 0, 0, tzinfo=tz).astimezone(utc)) + assert prov._is_still_available(datetime.datetime(2016, 12, 1, 23, 59, 0, tzinfo=tz).astimezone(utc)) + assert not prov._is_still_available(datetime.datetime(2016, 12, 2, 0, 0, 1, tzinfo=tz).astimezone(utc)) @pytest.mark.django_db @@ -132,11 +132,11 @@ def test_availability_date_timezones(event): prov = DummyPaymentProvider(event) prov.settings.set('_availability_date', '2016-12-01') - tz = pytz.timezone('US/Pacific') - utc = pytz.timezone('UTC') - assert prov._is_still_available(tz.localize(datetime.datetime(2016, 11, 30, 23, 0, 0)).astimezone(utc)) - assert prov._is_still_available(tz.localize(datetime.datetime(2016, 12, 1, 23, 59, 0)).astimezone(utc)) - assert not prov._is_still_available(tz.localize(datetime.datetime(2016, 12, 2, 0, 0, 1)).astimezone(utc)) + tz = ZoneInfo('US/Pacific') + utc = ZoneInfo('UTC') + assert prov._is_still_available(datetime.datetime(2016, 11, 30, 23, 0, 0, tzinfo=tz).astimezone(utc)) + assert prov._is_still_available(datetime.datetime(2016, 12, 1, 23, 59, 0, tzinfo=tz).astimezone(utc)) + assert not prov._is_still_available(datetime.datetime(2016, 12, 2, 0, 0, 1, tzinfo=tz).astimezone(utc)) @pytest.mark.django_db diff --git a/src/tests/base/test_reldate.py b/src/tests/base/test_reldate.py index f1498ad88..301dc781d 100644 --- a/src/tests/base/test_reldate.py +++ b/src/tests/base/test_reldate.py @@ -20,16 +20,16 @@ # . # from datetime import datetime, time +from zoneinfo import ZoneInfo import pytest -import pytz from django_scopes import scope from pretix.base.models import Event, Organizer from pretix.base.reldate import RelativeDate, RelativeDateWrapper -TOKYO = pytz.timezone('Asia/Tokyo') -BERLIN = pytz.timezone('Europe/Berlin') +TOKYO = ZoneInfo('Asia/Tokyo') +BERLIN = ZoneInfo('Europe/Berlin') @pytest.fixture @@ -37,8 +37,8 @@ def event(): o = Organizer.objects.create(name='Dummy', slug='dummy') event = Event.objects.create( organizer=o, name='Dummy', slug='dummy', - date_from=TOKYO.localize(datetime(2017, 12, 27, 5, 0, 0)), - presale_start=TOKYO.localize(datetime(2017, 12, 1, 5, 0, 0)), + date_from=datetime(2017, 12, 27, 5, 0, 0, tzinfo=TOKYO), + presale_start=datetime(2017, 12, 1, 5, 0, 0, tzinfo=TOKYO), plugins='pretix.plugins.banktransfer' ) @@ -57,7 +57,7 @@ def test_absolute_date(event): @pytest.mark.django_db def test_relative_date_without_time(event): rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='date_from', minutes_before=None)) - assert rdw.datetime(event).astimezone(TOKYO) == TOKYO.localize(datetime(2017, 12, 26, 5, 0, 0)) + assert rdw.datetime(event).astimezone(TOKYO) == datetime(2017, 12, 26, 5, 0, 0, tzinfo=TOKYO) assert rdw.to_string() == 'RELDATE/1/-/date_from/' @@ -65,64 +65,64 @@ def test_relative_date_without_time(event): def test_relative_date_other_base_point(event): with scope(organizer=event.organizer): rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_start', minutes_before=None)) - assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 11, 30, 5, 0, 0)) + assert rdw.datetime(event) == datetime(2017, 11, 30, 5, 0, 0, tzinfo=TOKYO) assert rdw.to_string() == 'RELDATE/1/-/presale_start/' # presale_end is unset, defaults to date_from rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_end', minutes_before=None)) - assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 12, 26, 5, 0, 0)) + assert rdw.datetime(event) == datetime(2017, 12, 26, 5, 0, 0, tzinfo=TOKYO) assert rdw.to_string() == 'RELDATE/1/-/presale_end/' # subevent base - se = event.subevents.create(name="SE1", date_from=TOKYO.localize(datetime(2017, 11, 27, 5, 0, 0))) + se = event.subevents.create(name="SE1", date_from=datetime(2017, 11, 27, 5, 0, 0, tzinfo=TOKYO)) rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='date_from', minutes_before=None)) - assert rdw.datetime(se) == TOKYO.localize(datetime(2017, 11, 26, 5, 0, 0)) + assert rdw.datetime(se) == datetime(2017, 11, 26, 5, 0, 0, tzinfo=TOKYO) # presale_start is unset on subevent, default to event rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_start', minutes_before=None)) - assert rdw.datetime(se) == TOKYO.localize(datetime(2017, 11, 30, 5, 0, 0)) + assert rdw.datetime(se) == datetime(2017, 11, 30, 5, 0, 0, tzinfo=TOKYO) # presale_end is unset on all, default to date_from of subevent rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_end', minutes_before=None)) - assert rdw.datetime(se) == TOKYO.localize(datetime(2017, 11, 26, 5, 0, 0)) + assert rdw.datetime(se) == datetime(2017, 11, 26, 5, 0, 0, tzinfo=TOKYO) @pytest.mark.django_db def test_relative_date_in_minutes(event): rdw = RelativeDateWrapper(RelativeDate(days_before=0, time=None, base_date_name='date_from', minutes_before=60)) assert rdw.to_string() == 'RELDATE/minutes/60/date_from/' - assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 12, 27, 4, 0, 0)) + assert rdw.datetime(event) == datetime(2017, 12, 27, 4, 0, 0, tzinfo=TOKYO) @pytest.mark.django_db def test_relative_date_with_time(event): rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=time(8, 5, 13), base_date_name='date_from', minutes_before=None)) assert rdw.to_string() == 'RELDATE/1/08:05:13/date_from/' - assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 12, 26, 8, 5, 13)) + assert rdw.datetime(event) == datetime(2017, 12, 26, 8, 5, 13, tzinfo=TOKYO) @pytest.mark.django_db def test_relative_date_with_time_around_dst(event): event.settings.timezone = "Europe/Berlin" - event.date_from = BERLIN.localize(datetime(2020, 3, 29, 18, 0, 0)) + event.date_from = datetime(2020, 3, 29, 18, 0, 0, tzinfo=BERLIN) rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=time(18, 0, 0), base_date_name='date_from', minutes_before=None)) assert rdw.to_string() == 'RELDATE/1/18:00:00/date_from/' - assert rdw.datetime(event) == BERLIN.localize(datetime(2020, 3, 28, 18, 0, 0)) + assert rdw.datetime(event) == datetime(2020, 3, 28, 18, 0, 0, tzinfo=BERLIN) rdw = RelativeDateWrapper(RelativeDate(days_before=0, time=time(2, 30, 0), base_date_name='date_from', minutes_before=None)) assert rdw.to_string() == 'RELDATE/0/02:30:00/date_from/' - assert rdw.datetime(event) == BERLIN.localize(datetime(2020, 3, 29, 2, 30, 0)) + assert rdw.datetime(event) == datetime(2020, 3, 29, 2, 30, 0, tzinfo=BERLIN) - event.date_from = BERLIN.localize(datetime(2020, 10, 25, 18, 0, 0)) + event.date_from = datetime(2020, 10, 25, 18, 0, 0, tzinfo=BERLIN) rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=time(18, 0, 0), base_date_name='date_from', minutes_before=None)) assert rdw.to_string() == 'RELDATE/1/18:00:00/date_from/' - assert rdw.datetime(event) == BERLIN.localize(datetime(2020, 10, 24, 18, 0, 0)) + assert rdw.datetime(event) == datetime(2020, 10, 24, 18, 0, 0, tzinfo=BERLIN) rdw = RelativeDateWrapper(RelativeDate(days_before=0, time=time(2, 30, 0), base_date_name='date_from', minutes_before=None)) assert rdw.to_string() == 'RELDATE/0/02:30:00/date_from/' - assert rdw.datetime(event) == BERLIN.localize(datetime(2020, 10, 25, 2, 30, 0)) + assert rdw.datetime(event) == datetime(2020, 10, 25, 2, 30, 0, tzinfo=BERLIN) def test_unserialize(): diff --git a/src/tests/base/test_timeframes.py b/src/tests/base/test_timeframes.py index 0f9f454d9..246873143 100644 --- a/src/tests/base/test_timeframes.py +++ b/src/tests/base/test_timeframes.py @@ -21,20 +21,20 @@ # from datetime import date, datetime +from zoneinfo import ZoneInfo import pytest -import pytz from pretix.base.timeframes import ( REPORTING_DATE_TIMEFRAMES, resolve_timeframe_to_dates_inclusive, resolve_timeframe_to_datetime_start_inclusive_end_exclusive, ) -tz = pytz.timezone("Europe/Berlin") +tz = ZoneInfo("Europe/Berlin") def dt(*args): - return tz.localize(datetime(*args)) + return datetime(*args, tzinfo=tz) ref_date = date(2023, 3, 28) diff --git a/src/tests/base/test_timeline.py b/src/tests/base/test_timeline.py index 5fcfaea03..c61befa1e 100644 --- a/src/tests/base/test_timeline.py +++ b/src/tests/base/test_timeline.py @@ -21,16 +21,16 @@ # from datetime import datetime from decimal import Decimal +from zoneinfo import ZoneInfo import pytest -import pytz from django_scopes import scope from pretix.base.i18n import language from pretix.base.models import Event, Organizer from pretix.base.timeline import timeline_for_event -tz = pytz.timezone('Europe/Berlin') +tz = ZoneInfo('Europe/Berlin') def one(iterable): diff --git a/src/tests/control/test_events.py b/src/tests/control/test_events.py index 0d56f75d3..6072b398c 100644 --- a/src/tests/control/test_events.py +++ b/src/tests/control/test_events.py @@ -37,14 +37,13 @@ import datetime import time from decimal import Decimal from smtplib import SMTPResponseException +from zoneinfo import ZoneInfo import pytest -import pytz from django.test.utils import override_settings from django.utils.timezone import now from django_scopes import scopes_disabled from i18nfield.strings import LazyI18nString -from pytz import timezone from tests.base import SoupTest, extract_form_fields from pretix.base.models import Event, LogEntry, Order, Organizer, Team, User @@ -835,11 +834,11 @@ class EventsTest(SoupTest): assert ev.location == LazyI18nString({'de': 'Hamburg', 'en': 'Hamburg'}) assert Team.objects.filter(limit_events=ev, members=self.user).exists() - berlin_tz = timezone('Europe/Berlin') - assert ev.date_from == berlin_tz.localize(datetime.datetime(2016, 12, 27, 10, 0, 0)).astimezone(pytz.utc) - assert ev.date_to == berlin_tz.localize(datetime.datetime(2016, 12, 30, 19, 0, 0)).astimezone(pytz.utc) - assert ev.presale_start == berlin_tz.localize(datetime.datetime(2016, 11, 1, 10, 0, 0)).astimezone(pytz.utc) - assert ev.presale_end == berlin_tz.localize(datetime.datetime(2016, 11, 30, 18, 0, 0)).astimezone(pytz.utc) + berlin_tz = ZoneInfo('Europe/Berlin') + assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.date_to == datetime.datetime(2016, 12, 30, 19, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_start == datetime.datetime(2016, 11, 1, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_end == datetime.datetime(2016, 11, 30, 18, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) assert ev.tax_rules.filter(rate=Decimal('19.00')).exists() @@ -954,11 +953,11 @@ class EventsTest(SoupTest): assert Team.objects.filter(limit_events=ev, members=self.user).exists() assert ev.items.count() == 1 - berlin_tz = timezone('Europe/Berlin') - assert ev.date_from == berlin_tz.localize(datetime.datetime(2016, 12, 27, 10, 0, 0)).astimezone(pytz.utc) - assert ev.date_to == berlin_tz.localize(datetime.datetime(2016, 12, 30, 19, 0, 0)).astimezone(pytz.utc) - assert ev.presale_start == berlin_tz.localize(datetime.datetime(2016, 11, 1, 10, 0, 0)).astimezone(pytz.utc) - assert ev.presale_end == berlin_tz.localize(datetime.datetime(2016, 11, 30, 18, 0, 0)).astimezone(pytz.utc) + berlin_tz = ZoneInfo('Europe/Berlin') + assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.date_to == datetime.datetime(2016, 12, 30, 19, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_start == datetime.datetime(2016, 11, 1, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_end == datetime.datetime(2016, 11, 30, 18, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) assert ev.tax_rules.filter(rate=Decimal('19.00')).count() == 1 i = ev.items.get() @@ -1027,11 +1026,11 @@ class EventsTest(SoupTest): assert Team.objects.filter(limit_events=ev, members=self.user).exists() assert ev.items.count() == 1 - berlin_tz = timezone('Europe/Berlin') - assert ev.date_from == berlin_tz.localize(datetime.datetime(2016, 12, 27, 10, 0, 0)).astimezone(pytz.utc) - assert ev.date_to == berlin_tz.localize(datetime.datetime(2016, 12, 30, 19, 0, 0)).astimezone(pytz.utc) - assert ev.presale_start == berlin_tz.localize(datetime.datetime(2016, 11, 1, 10, 0, 0)).astimezone(pytz.utc) - assert ev.presale_end == berlin_tz.localize(datetime.datetime(2016, 11, 30, 18, 0, 0)).astimezone(pytz.utc) + berlin_tz = ZoneInfo('Europe/Berlin') + assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.date_to == datetime.datetime(2016, 12, 30, 19, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_start == datetime.datetime(2016, 11, 1, 10, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) + assert ev.presale_end == datetime.datetime(2016, 11, 30, 18, 0, 0, tzinfo=berlin_tz).astimezone(datetime.timezone.utc) assert ev.tax_rules.filter(rate=Decimal('19.00')).count() == 1 @@ -1079,7 +1078,7 @@ class EventsTest(SoupTest): assert ev.organizer == self.orga1 assert ev.location == LazyI18nString({'en': 'Hamburg'}) assert Team.objects.filter(limit_events=ev, members=self.user).exists() - assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=pytz.utc) + assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc) assert ev.date_to is None assert ev.presale_start is None assert ev.presale_end is None @@ -1128,7 +1127,7 @@ class EventsTest(SoupTest): assert ev.location == LazyI18nString({'en': 'Hamburg'}) team = Team.objects.filter(limit_events=ev, members=self.user).first() assert team == self.team2 - assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=pytz.utc) + assert ev.date_from == datetime.datetime(2016, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc) assert ev.date_to is None assert ev.presale_start is None assert ev.presale_end is None diff --git a/src/tests/plugins/banktransfer/test_api.py b/src/tests/plugins/banktransfer/test_api.py index 161aeb987..0b31e65fc 100644 --- a/src/tests/plugins/banktransfer/test_api.py +++ b/src/tests/plugins/banktransfer/test_api.py @@ -21,13 +21,12 @@ # import copy import json -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from unittest import mock import pytest from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import ( Event, Item, Order, OrderPosition, Organizer, Quota, Team, User, @@ -89,7 +88,7 @@ RES_JOB = { @pytest.mark.django_db def test_api_list(env, client): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime @@ -109,7 +108,7 @@ def test_api_list(env, client): @pytest.mark.django_db def test_api_detail(env, client): - testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC) + testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.UTC) with mock.patch('django.utils.timezone.now') as mock_now: mock_now.return_value = testtime diff --git a/src/tests/plugins/sendmail/test_rules.py b/src/tests/plugins/sendmail/test_rules.py index 972e11a2e..d4e0f8462 100644 --- a/src/tests/plugins/sendmail/test_rules.py +++ b/src/tests/plugins/sendmail/test_rules.py @@ -21,9 +21,9 @@ # import datetime +from zoneinfo import ZoneInfo import pytest -import pytz from django.core import mail as djmail from django.utils.timezone import now, utc from django_scopes import scopes_disabled @@ -46,8 +46,8 @@ def test_sendmail_rule_create_single(event): dt_now = now() -NZ = pytz.timezone('NZ') -Berlin = pytz.timezone('Europe/Berlin') +NZ = ZoneInfo('NZ') +Berlin = ZoneInfo('Europe/Berlin') @pytest.mark.django_db @@ -101,28 +101,28 @@ Berlin = pytz.timezone('Europe/Berlin') datetime.datetime(2020, 2, 29, 9, tzinfo=utc) ), ( # Test timezone far off from UTC - NZ.localize(datetime.datetime(2021, 5, 17, 22)), + datetime.datetime(2021, 5, 17, 22, tzinfo=NZ), None, 'NZ', Rule(date_is_absolute=False, offset_is_after=True, send_offset_days=1, send_offset_time=datetime.time(hour=9)), - NZ.localize(datetime.datetime(2021, 5, 18, 9)) + datetime.datetime(2021, 5, 18, 9, tzinfo=NZ) ), ( # Test across DST change - Berlin.localize(datetime.datetime(2021, 10, 29, 16, 30)), + datetime.datetime(2021, 10, 29, 16, 30, tzinfo=Berlin), None, 'Europe/Berlin', Rule(date_is_absolute=False, offset_is_after=True, send_offset_days=4, send_offset_time=datetime.time(hour=2, minute=30)), - Berlin.localize(datetime.datetime(2021, 11, 2, 2, 30)) + datetime.datetime(2021, 11, 2, 2, 30, tzinfo=Berlin) ), ( # Test ambiguous time at DST change - Berlin.localize(datetime.datetime(2021, 10, 29, 18, 30)), + datetime.datetime(2021, 10, 29, 18, 30, tzinfo=Berlin), None, 'Europe/Berlin', Rule(date_is_absolute=False, offset_is_after=True, send_offset_days=2, send_offset_time=datetime.time(hour=2, minute=30)), datetime.datetime(2021, 10, 31, 1, 30, tzinfo=utc) ), ( # Test non-existing time at DST change - Berlin.localize(datetime.datetime(2021, 3, 29, 14, 30)), + datetime.datetime(2021, 3, 29, 14, 30, tzinfo=Berlin), None, 'Europe/Berlin', Rule(date_is_absolute=False, offset_is_after=False, send_offset_days=1, send_offset_time=datetime.time(hour=2, minute=30)), diff --git a/src/tests/plugins/test_checkinlist.py b/src/tests/plugins/test_checkinlist.py index 105d3f457..6c212a7f8 100644 --- a/src/tests/plugins/test_checkinlist.py +++ b/src/tests/plugins/test_checkinlist.py @@ -23,7 +23,6 @@ import datetime from decimal import Decimal import pytest -import pytz from django.utils.timezone import now from django_scopes import scope @@ -51,7 +50,7 @@ def event(): order_paid = Order.objects.create( code='FOO', event=event, email='dummy@dummy.test', phone="+498912345678", status=Order.STATUS_PAID, - datetime=datetime.datetime(2019, 2, 22, 14, 0, 0, tzinfo=pytz.UTC), expires=now() + datetime.timedelta(days=10), + datetime=datetime.datetime(2019, 2, 22, 14, 0, 0, tzinfo=datetime.timezone.utc), expires=now() + datetime.timedelta(days=10), total=33, locale='en' ) item_ticket = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True) @@ -147,7 +146,7 @@ def test_csv_order_by_inherited_name_parts(event): # noqa order2 = Order.objects.create( code='BAR', event=event, email='dummy@dummy.test', phone='+498912345678', status=Order.STATUS_PAID, - datetime=datetime.datetime(2019, 2, 22, 14, 0, 0, tzinfo=pytz.UTC), expires=now() + datetime.timedelta(days=10), + datetime=datetime.datetime(2019, 2, 22, 14, 0, 0, tzinfo=datetime.timezone.utc), expires=now() + datetime.timedelta(days=10), total=33, locale='en' ) OrderPosition.objects.create( diff --git a/src/tests/presale/test_event.py b/src/tests/presale/test_event.py index 9346ad38a..d2dd8742a 100644 --- a/src/tests/presale/test_event.py +++ b/src/tests/presale/test_event.py @@ -37,6 +37,7 @@ import datetime import re from decimal import Decimal from json import loads +from zoneinfo import ZoneInfo from django.conf import settings from django.core import mail @@ -44,7 +45,6 @@ from django.core.exceptions import ValidationError from django.test import TestCase from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import timezone from tests.base import SoupTest from tests.testdummy.signals import FoobarSalesChannel @@ -1390,11 +1390,11 @@ class EventIcalDownloadTest(EventTestMixin, SoupTest): fmt = '%Y%m%dT%H%M%S' self.assertIn('DTSTART;TZID=%s:%s' % (self.event.settings.timezone, - self.event.date_from.astimezone(timezone(self.event.settings.timezone)).strftime(fmt)), + self.event.date_from.astimezone(ZoneInfo(self.event.settings.timezone)).strftime(fmt)), ical, 'incorrect start time') self.assertIn('DTEND;TZID=%s:%s' % (self.event.settings.timezone, - self.event.date_to.astimezone(timezone(self.event.settings.timezone)).strftime(fmt)), + self.event.date_to.astimezone(ZoneInfo(self.event.settings.timezone)).strftime(fmt)), ical, 'incorrect end time') self.assertIn('TZID:%s' % self.event.settings.timezone, ical, 'missing VCALENDAR') @@ -1413,7 +1413,7 @@ class EventIcalDownloadTest(EventTestMixin, SoupTest): fmt = '%Y%m%dT%H%M%S' self.assertIn('DTSTART;TZID=%s:%s' % (self.event.settings.timezone, - self.event.date_from.astimezone(timezone(self.event.settings.timezone)).strftime(fmt)), + self.event.date_from.astimezone(ZoneInfo(self.event.settings.timezone)).strftime(fmt)), ical, 'incorrect start time') self.assertNotIn('DTEND', ical, 'unexpected end time attribute') diff --git a/src/tests/presale/test_organizer_page.py b/src/tests/presale/test_organizer_page.py index 164bb3a56..b8811f235 100644 --- a/src/tests/presale/test_organizer_page.py +++ b/src/tests/presale/test_organizer_page.py @@ -19,12 +19,11 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone import pytest from django.utils.timezone import now from django_scopes import scopes_disabled -from pytz import UTC from pretix.base.models import Event, Organizer @@ -149,7 +148,7 @@ def test_calendar(env, client): env[0].settings.event_list_type = 'calendar' e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=False ) r = client.get('/mrmcd/?style=calendar') @@ -169,7 +168,7 @@ def test_week_calendar(env, client): env[0].settings.event_list_type = 'calendar' e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=False ) r = client.get('/mrmcd/?style=week') @@ -187,7 +186,7 @@ def test_attributes_in_calendar(env, client): env[0].settings.event_list_type = 'calendar' e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=True ) prop = env[0].meta_properties.create(name='loc') @@ -203,7 +202,7 @@ def test_attributes_in_calendar(env, client): def test_ics(env, client): e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=False ) r = client.get('/mrmcd/events/ical/') @@ -218,7 +217,7 @@ def test_ics(env, client): def test_ics_subevents(env, client): e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=True, has_subevents=True ) with scopes_disabled(): @@ -232,12 +231,12 @@ def test_ics_subevents(env, client): def test_ics_subevents_attributes(env, client): e0 = Event.objects.create( organizer=env[0], name='DS2017', slug='DS2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=True ) e = Event.objects.create( organizer=env[0], name='MRMCD2017', slug='2017', - date_from=datetime(now().year + 1, 9, 1, tzinfo=UTC), + date_from=datetime(now().year + 1, 9, 1, tzinfo=timezone.utc), live=True, is_public=True, has_subevents=True ) with scopes_disabled():