Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django 4.0 and Python 3.10 support #528

Merged
merged 15 commits into from
Jun 4, 2022
Merged
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ python:
- 3.7
- 3.8
- 3.9
- 3.10
env:
- DJANGO=2.2
- DJANGO=3.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our travis CI don't work anymore, I am working on moving to github actions

- DJANGO=3.1
- DJANGO=3.2
- DJANGO=4.0
os:
- linux
matrix:
Expand All @@ -29,6 +29,8 @@ matrix:
- { python: 3.6, env: TOXENV=upgradebeat140 }
- { python: 3.8, env: TOXENV=flake8 }
- { python: 3.8, env: TOXENV=pydocstyle }
exclude:
- { python: 3.10, env: DJANGO=2.2 }
install: travis_retry pip install -U tox-travis
services: rabbitmq
script: tox -v -- -v
Expand Down
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Important Warning about Time Zones



.. note::
.. note::
This will reset the state as if the periodic tasks have never run before.


Expand Down Expand Up @@ -95,7 +95,7 @@ create the interval object:
.. code-block:: Python

>>> from django_celery_beat.models import PeriodicTask, IntervalSchedule

# executes every 10 seconds.
>>> schedule, created = IntervalSchedule.objects.get_or_create(
... every=10,
Expand Down Expand Up @@ -181,7 +181,7 @@ of a ``30 * * * *`` (execute every 30 minutes) crontab entry you specify:
... day_of_week='*',
... day_of_month='*',
... month_of_year='*',
... timezone=pytz.timezone('Canada/Pacific')
... timezone=zoneinfo.ZoneInfo('Canada/Pacific')
... )

The crontab schedule is linked to a specific timezone using the 'timezone' input parameter.
Expand Down Expand Up @@ -288,7 +288,7 @@ After installation, add ``django_celery_beat`` to Django's settings module:
Run the ``django_celery_beat`` migrations using:

.. code-block:: bash

$ python manage.py migrate django_celery_beat


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.0.3 on 2022-03-21 20:20

from django.db import migrations
import django_celery_beat.models
import timezone_field.fields


class Migration(migrations.Migration):

dependencies = [
('django_celery_beat', '0015_edit_solarschedule_events_choices'),
]

operations = [
migrations.AlterField(
model_name='crontabschedule',
name='timezone',
field=timezone_field.fields.TimeZoneField(
default=
django_celery_beat.models.crontab_schedule_celery_timezone,
help_text=
'Timezone to Run the Cron Schedule on. Default is UTC.',
use_pytz=False, verbose_name='Cron Timezone'),
),
]
12 changes: 8 additions & 4 deletions django_celery_beat/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
"""Database models."""
try:
from zoneinfo import available_timezones
except ImportError:
from backports.zoneinfo import available_timezones
from datetime import timedelta

import timezone_field
Expand Down Expand Up @@ -66,10 +70,9 @@ def crontab_schedule_celery_timezone():
settings, '%s_TIMEZONE' % current_app.namespace)
except AttributeError:
return 'UTC'
return CELERY_TIMEZONE if CELERY_TIMEZONE in [
choice[0].zone for choice in timezone_field.
TimeZoneField.default_choices
] else 'UTC'
if CELERY_TIMEZONE in available_timezones():
return CELERY_TIMEZONE
return 'UTC'


class SolarSchedule(models.Model):
Expand Down Expand Up @@ -297,6 +300,7 @@ class CrontabSchedule(models.Model):

timezone = timezone_field.TimeZoneField(
default=crontab_schedule_celery_timezone,
use_pytz=False,
verbose_name=_('Cron Timezone'),
help_text=_(
'Timezone to Run the Cron Schedule on. Default is UTC.'),
Expand Down
6 changes: 1 addition & 5 deletions django_celery_beat/schedulers.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,8 @@ def is_due(self):
return self.schedule.is_due(last_run_at_in_tz)

def _default_now(self):
# The PyTZ datetime must be localised for the Django-Celery-Beat
# scheduler to work. Keep in mind that timezone arithmatic
# with a localized timezone may be inaccurate.
if getattr(settings, 'DJANGO_CELERY_BEAT_TZ_AWARE', True):
now = self.app.now()
now = now.tzinfo.localize(now.replace(tzinfo=None))
now = datetime.datetime.now(self.app.timezone)
else:
# this ends up getting passed to maybe_make_aware, which expects
# all naive datetime objects to be in utc time.
Expand Down
9 changes: 3 additions & 6 deletions django_celery_beat/tzcrontab.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
from celery import schedules

from collections import namedtuple
from datetime import datetime
import pytz
from datetime import datetime, timezone


schedstate = namedtuple('schedstate', ('is_due', 'next'))
Expand All @@ -14,7 +13,7 @@ class TzAwareCrontab(schedules.crontab):

def __init__(
self, minute='*', hour='*', day_of_week='*',
day_of_month='*', month_of_year='*', tz=pytz.utc, app=None
day_of_month='*', month_of_year='*', tz=timezone.utc, app=None
):
"""Overwrite Crontab constructor to include a timezone argument."""
self.tz = tz
Expand All @@ -28,9 +27,7 @@ def __init__(
)

def nowfunc(self):
return self.tz.normalize(
pytz.utc.localize(datetime.utcnow())
)
return datetime.now(self.tz)

def is_due(self, last_run_at):
"""Calculate when the next run will take place.
Expand Down
3 changes: 2 additions & 1 deletion requirements/default.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
celery>=5.2.3,<6.0
django-timezone-field>=4.2.3
django-timezone-field>=5.0
tzdata
python-crontab>=2.3.4
ElSaico marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 1 addition & 2 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
case>=1.3.1
pytest-django>=2.2,<4.0
pytz>dev
pytest<4.0.0
pytest>=6.2.5
pytest-timeout
ephem
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ def _pyimp():
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Framework :: Django
Framework :: Django :: 2.2
Framework :: Django :: 3.0
Framework :: Django :: 3.1
Framework :: Django :: 3.2
Framework :: Django :: 4.0
Operating System :: OS Independent
Topic :: Communications
Topic :: System :: Distributed Computing
Expand Down
4 changes: 2 additions & 2 deletions t/proj/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.conf.urls import url
from django.urls import path
from django.contrib import admin

urlpatterns = [
url(r'^admin/', admin.site.urls),
path(r'admin/', admin.site.urls),
ElSaico marked this conversation as resolved.
Show resolved Hide resolved
]
9 changes: 5 additions & 4 deletions t/unit/test_models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import os
try:
from zoneinfo import available_timezones
except ImportError:
from backports.zoneinfo import available_timezones

from celery import schedules
from django.test import TestCase, override_settings
Expand All @@ -9,8 +13,6 @@
from django.db.migrations.questioner import NonInteractiveMigrationQuestioner
from django.utils import timezone

import timezone_field

from django_celery_beat import migrations as beat_migrations
from django_celery_beat.models import (
crontab_schedule_celery_timezone,
Expand Down Expand Up @@ -83,8 +85,7 @@ def _test_duplicate_schedules(self, cls, kwargs, schedule=None):


class CrontabScheduleTestCase(TestCase, TestDuplicatesMixin):
FIRST_VALID_TIMEZONE = timezone_field.\
TimeZoneField.default_choices[0][0].zone
FIRST_VALID_TIMEZONE = available_timezones().pop()

def test_default_timezone_without_settings_config(self):
assert crontab_schedule_celery_timezone() == "UTC"
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ envlist =
py37-django{22,32}
py38-django{22,32,40}
py39-django{22,32,40}
py310-django{32,40}
pypy3-django{22,32}
flake8
apicheck
Expand All @@ -26,7 +27,7 @@ deps=

django22: -r{toxinidir}/requirements/test-django22.txt
django32: -r{toxinidir}/requirements/test-django32.txt
django32: -r{toxinidir}/requirements/test-django40.txt
django40: -r{toxinidir}/requirements/test-django40.txt

linkcheck,apicheck: -r{toxinidir}/requirements/docs.txt
flake8,flakeplus,pydocstyle: -r{toxinidir}/requirements/pkgutils.txt
Expand Down