Skip to content

Commit

Permalink
Replace use of pytz with built-in timezone
Browse files Browse the repository at this point in the history
Now that we're on Python 3.10, we can just use the built-in `timezone`
module instead of installing `pytz`.

`pytz` remains a Django dependency (for now), but we at least can remove
our direct dependence on it.
  • Loading branch information
DavidCain committed Jul 15, 2022
1 parent b32b7b5 commit 7bcfa7e
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 38 deletions.
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,13 @@ freezegun = "*"
isort = { version = "^5.8", extras = ["pyproject"] } # Version 5 introduces black compatibility
lxml = "*"
pylint = "^2.8"
pytz = "*" # (It's a production dependency by way of Django, but used directly in tests)
responses = "*"

# Dependencies for static type checking
django-stubs = { version = "^1.9" }
mypy = { version = "*"}
types-certifi = { version = "*" }
types-cryptography = { version = "*" }
types-pytz = { version = "*" }
types-requests = { version = "*" }

# Dependencies helpful for local development, not used otherwise
Expand Down
2 changes: 1 addition & 1 deletion ws/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Django settings for ws project.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
https://docs.djangoproject.com/en/3.2/topics/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
Expand Down
5 changes: 2 additions & 3 deletions ws/tests/factories.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone

import allauth.account.models as account_models
import factory
import factory.fuzzy
import pytz
from factory.django import DjangoModelFactory
from mitoc_const import affiliations

Expand Down Expand Up @@ -138,7 +137,7 @@ class Meta:

participant = factory.SubFactory(ParticipantFactory)
reminder_sent_at = factory.fuzzy.FuzzyDateTime(
start_dt=datetime(2021, 11, 13, tzinfo=pytz.UTC)
start_dt=datetime(2021, 11, 13, tzinfo=timezone.utc)
)


Expand Down
7 changes: 3 additions & 4 deletions ws/tests/test_merge.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import unittest
from datetime import datetime
from datetime import datetime, timezone

import pytz
from django.contrib.auth.models import Permission, User
from django.db import connections
from django.db.utils import IntegrityError
Expand Down Expand Up @@ -145,10 +144,10 @@ def test_password_quality(self):

def test_membership_reminders(self):
"""The newest reminder is honored, even if delivered to the older participant."""
newer_reminder_sent_at = datetime(2020, 12, 25, tzinfo=pytz.UTC)
newer_reminder_sent_at = datetime(2020, 12, 25, tzinfo=timezone.utc)
factories.MembershipReminderFactory.create(
participant=self.tim,
reminder_sent_at=datetime(2020, 10, 1, tzinfo=pytz.UTC),
reminder_sent_at=datetime(2020, 10, 1, tzinfo=timezone.utc),
)
factories.MembershipReminderFactory.create(
participant=self.old,
Expand Down
11 changes: 5 additions & 6 deletions ws/tests/test_tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from datetime import date, datetime
from datetime import date, datetime, timezone
from unittest import mock
from unittest.mock import patch

import pytz
from django.core import mail
from django.core.cache import cache
from django.test import SimpleTestCase
Expand Down Expand Up @@ -246,7 +245,7 @@ def test_nobody_needs_reminding():
)
factories.MembershipReminderFactory.create(
participant=already_reminded,
reminder_sent_at=datetime(2020, 12, 25, tzinfo=pytz.UTC),
reminder_sent_at=datetime(2020, 12, 25, tzinfo=timezone.utc),
)

with patch.object(tasks.remind_lapsed_participant_to_renew, 'delay') as email:
Expand All @@ -272,7 +271,7 @@ def test_can_be_reminded_once_a_year():
# We reminded them once before, but it was for the previous year's membership
factories.MembershipReminderFactory.create(
participant=par,
reminder_sent_at=datetime(2017, 12, 25, tzinfo=pytz.UTC),
reminder_sent_at=datetime(2017, 12, 25, tzinfo=timezone.utc),
)
with patch.object(tasks.remind_lapsed_participant_to_renew, 'delay') as email:
tasks.remind_participants_to_renew()
Expand All @@ -298,7 +297,7 @@ def test_success(self):
)
self.assertEqual(reminder.participant, par)
self.assertEqual(
reminder.reminder_sent_at, datetime(2019, 1, 25, 17, 0, tzinfo=pytz.UTC)
reminder.reminder_sent_at, datetime(2019, 1, 25, 17, 0, tzinfo=timezone.utc)
)

def test_idempotent(self):
Expand Down Expand Up @@ -336,7 +335,7 @@ def test_tried_to_remind_again_too_soon(self):
)
factories.MembershipReminderFactory.create(
participant=par,
reminder_sent_at=datetime(2018, 4, 25, tzinfo=pytz.UTC),
reminder_sent_at=datetime(2018, 4, 25, tzinfo=timezone.utc),
)

with patch.object(renew, 'send_email_reminding_to_renew') as email:
Expand Down
19 changes: 9 additions & 10 deletions ws/tests/utils/test_dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest import mock
from zoneinfo import ZoneInfo

import pytz
from freezegun import freeze_time

from ws import enums
Expand Down Expand Up @@ -123,27 +122,27 @@ def test_closest_wednesday(self, local_now):
self.assertLess(test_date, closest_wed)

def test_closest_wed_at_noon(self):
est = pytz.timezone('America/New_York')
eastern = ZoneInfo('America/New_York')

# On Wednesday, we return the same day
with freeze_time("2016-12-28 23:22 EST"):
self.assertEqual(
date_utils.closest_wed_at_noon(),
est.localize(datetime(2016, 12, 28, 12, 0, 0)),
datetime(2016, 12, 28, 12, 0, 0, tzinfo=eastern),
)

# 3 days to the next Wednesday, 4 days to the previous
with freeze_time("2016-12-25 10:00 EST"):
self.assertEqual(
date_utils.closest_wed_at_noon(),
est.localize(datetime(2016, 12, 28, 12, 0, 0)),
datetime(2016, 12, 28, 12, 0, 0, tzinfo=eastern),
)

# 4 days to the next Wednesday, 3 days to the previous
with freeze_time("2016-12-24 10:00 EST"):
self.assertEqual(
date_utils.closest_wed_at_noon(),
est.localize(datetime(2016, 12, 21, 12, 0, 0)),
datetime(2016, 12, 21, 12, 0, 0, tzinfo=eastern),
)

def test_is_currently_iap(self):
Expand All @@ -165,8 +164,8 @@ def test_is_currently_iap(self):
self.assertFalse(date_utils.is_currently_iap())

def test_fcfs_close_time(self):
est = pytz.timezone('America/New_York')
thur_night = est.localize(datetime(2019, 1, 24, 23, 59, 59))
eastern = ZoneInfo("America/New_York")
thur_night = datetime(2019, 1, 24, 23, 59, 59, tzinfo=eastern)

# For the usual case (trips over the weekend), it's the Thursday beforehand
(fri, sat, sun, mon) = (date(2019, 1, dom) for dom in [25, 26, 27, 28])
Expand All @@ -187,9 +186,9 @@ def test_fcfs_close_time(self):
self.assertEqual(date_utils.fcfs_close_time(date(2019, 1, 24)), wed_night)

def test_next_lottery(self):
est = pytz.timezone('America/New_York')
friday_the_23rd = est.localize(datetime(2019, 1, 23, 9, 0, 0))
friday_the_30th = est.localize(datetime(2019, 1, 30, 9, 0, 0))
eastern = ZoneInfo("America/New_York")
friday_the_23rd = datetime(2019, 1, 23, 9, 0, 0, tzinfo=eastern)
friday_the_30th = datetime(2019, 1, 30, 9, 0, 0, tzinfo=eastern)

# Normal cases: lottery is always just the next Wednesday morning
with freeze_time("Fri, 25 Jan 2019 03:00:00 EST"):
Expand Down
11 changes: 5 additions & 6 deletions ws/tests/views/test_account.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from datetime import datetime, timezone
from unittest import mock

import pytz
from bs4 import BeautifulSoup
from freezegun import freeze_time
from pwned_passwords_django import api
Expand Down Expand Up @@ -73,7 +72,7 @@ def test_known_bad_password(self, mocked_settings):
self.assertFalse(quality.is_insecure)
self.assertEqual(
quality.last_checked,
datetime(2019, 8, 29, 16, 25, tzinfo=pytz.utc),
datetime(2019, 8, 29, 16, 25, tzinfo=timezone.utc),
)

# Log in again, but this time with DEBUG off (& whitelist still present)
Expand Down Expand Up @@ -111,7 +110,7 @@ def test_previously_secure_password(self):
self.assertTrue(quality.is_insecure)
self.assertEqual(
quality.last_checked,
datetime(2019, 8, 29, 16, 25, tzinfo=pytz.utc),
datetime(2019, 8, 29, 16, 25, tzinfo=timezone.utc),
)

# Because the user's password is insecure, they're prompted to change it
Expand Down Expand Up @@ -162,7 +161,7 @@ def test_password_is_marked_secure(self):
self.assertFalse(participant.passwordquality.is_insecure)
self.assertEqual(
participant.passwordquality.last_checked,
datetime(2019, 8, 29, 16, 25, tzinfo=pytz.utc),
datetime(2019, 8, 29, 16, 25, tzinfo=timezone.utc),
)

def test_redirect_should_be_preserved(self):
Expand Down Expand Up @@ -218,7 +217,7 @@ def test_change_password_fram_insecure(self):
self.assertFalse(par.passwordquality.is_insecure)
self.assertEqual(
par.passwordquality.last_checked,
datetime(2019, 7, 15, 16, 45, tzinfo=pytz.utc),
datetime(2019, 7, 15, 16, 45, tzinfo=timezone.utc),
)

def test_user_without_participant(self):
Expand Down
5 changes: 2 additions & 3 deletions ws/tests/views/test_participant.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import random
from datetime import date, datetime
from datetime import date, datetime, timezone
from unittest import mock

import pytz
from bs4 import BeautifulSoup
from django.contrib.auth.models import Group
from freezegun import freeze_time
Expand Down Expand Up @@ -317,7 +316,7 @@ def test_new_participant(self):
task_update.delay.assert_called_with(participant.pk)

# We then update the timestamps!
now = datetime(2019, 2, 15, 17, 25, tzinfo=pytz.utc)
now = datetime(2019, 2, 15, 17, 25, tzinfo=timezone.utc)
self.assertEqual(participant.last_updated, now)
# Since the participant modified their own profile, we save `profile_last_updated`
self.assertEqual(participant.profile_last_updated, now)
Expand Down
3 changes: 1 addition & 2 deletions ws/utils/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ def localize(dt_time: datetime) -> datetime:
>>> localize(datetime(2018, 10, 27, 4, 30)
datetime.datetime(2018, 10, 27, 4, 30, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
"""
pytz_timezone = timezone.get_default_timezone()
return pytz_timezone.localize(dt_time)
return timezone.get_default_timezone().localize(dt_time)


def itinerary_available_at(trip_date: date) -> datetime:
Expand Down

0 comments on commit 7bcfa7e

Please sign in to comment.