Skip to content

Commit

Permalink
Merge pull request #4026 from jams2/django-50
Browse files Browse the repository at this point in the history
Support Django 5.0
  • Loading branch information
Zac-HD committed Jul 4, 2024
2 parents c96e3bf + b31cea0 commit 8926fc2
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 15 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ jobs:
- check-py39-pytest46
- check-py39-pytest54
- check-pytest62
- check-django50
- check-django42
- check-django41
- check-django32
- check-pandas22
- check-pandas21
- check-pandas20
Expand Down
5 changes: 5 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
RELEASE_TYPE: minor

This release improves support for Django 5.0, and drops support for end-of-life Django versions (< 4.2).

Thanks to Joshua Munn for this contribution.
4 changes: 3 additions & 1 deletion hypothesis-python/src/hypothesis/extra/django/_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ def inner(field):
def timezones():
# From Django 4.0, the default is to use zoneinfo instead of pytz.
assert getattr(django.conf.settings, "USE_TZ", False)
if getattr(django.conf.settings, "USE_DEPRECATED_PYTZ", True):
if django.VERSION < (5, 0, 0) and getattr(
django.conf.settings, "USE_DEPRECATED_PYTZ", True
):
from hypothesis.extra.pytz import timezones
else:
from hypothesis.strategies import timezones
Expand Down
1 change: 1 addition & 0 deletions hypothesis-python/src/hypothesis/extra/django/_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def from_model(
name not in field_strategies
and not field.auto_created
and not isinstance(field, dm.AutoField)
and not isinstance(field, getattr(dm, "GeneratedField", ()))
and field.default is dm.fields.NOT_PROVIDED
):
field_strategies[name] = from_field(field)
Expand Down
6 changes: 6 additions & 0 deletions hypothesis-python/tests/django/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
except ImportError:
RemovedInDjango50Warning = ()

try:
from django.utils.deprecation import RemovedInDjango60Warning
except ImportError:
RemovedInDjango60Warning = ()

with warnings.catch_warnings():
warnings.simplefilter("ignore", category=RemovedInDjango50Warning)
warnings.simplefilter("ignore", category=RemovedInDjango60Warning)
execute_from_command_line(sys.argv)
9 changes: 8 additions & 1 deletion hypothesis-python/tests/django/toys/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import os

import django

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

Expand Down Expand Up @@ -85,7 +87,8 @@

USE_I18N = True

USE_L10N = True
if django.VERSION < (5, 0, 0):
USE_L10N = True

USE_TZ = os.environ.get("HYPOTHESIS_DJANGO_USETZ", "TRUE") == "TRUE"

Expand Down Expand Up @@ -121,3 +124,7 @@
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

# Transitional setting until 6.0. See
# https://docs.djangoproject.com/en/5.0/ref/forms/fields/#django.forms.URLField.assume_scheme
FORMS_URLFIELD_ASSUME_HTTPS = True
22 changes: 22 additions & 0 deletions hypothesis-python/tests/django/toystore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

import django
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db import models


Expand Down Expand Up @@ -149,3 +151,23 @@ class CompanyExtension(models.Model):

class UserSpecifiedAutoId(models.Model):
my_id = models.AutoField(primary_key=True)


if django.VERSION >= (5, 0, 0):
import math

class Pizza(models.Model):
AREA = math.pi * models.F("radius") ** 2

radius = models.IntegerField(validators=[MinValueValidator(1)])
slices = models.PositiveIntegerField(validators=[MinValueValidator(2)])
total_area = models.GeneratedField(
expression=AREA,
output_field=models.FloatField(),
db_persist=True,
)
slice_area = models.GeneratedField(
expression=AREA / models.F("slices"),
output_field=models.FloatField(),
db_persist=False,
)
17 changes: 17 additions & 0 deletions hypothesis-python/tests/django/toystore/test_given_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import datetime as dt
from uuid import UUID

import django
from django.conf import settings as django_settings
from django.contrib.auth.models import User

Expand Down Expand Up @@ -210,3 +211,19 @@ class TestUserSpecifiedAutoId(TestCase):
def test_user_specified_auto_id(self, user_specified_auto_id):
self.assertIsInstance(user_specified_auto_id, UserSpecifiedAutoId)
self.assertIsNotNone(user_specified_auto_id.pk)


if django.VERSION >= (5, 0, 0):
from tests.django.toystore.models import Pizza

class TestModelWithGeneratedField(TestCase):
@given(from_model(Pizza))
def test_create_pizza(self, pizza):
"""
Strategies are not inferred for GeneratedField.
"""

pizza.full_clean()
# Check the expected types of the generated fields.
self.assertIsInstance(pizza.slice_area, float)
self.assertIsInstance(pizza.total_area, float)
16 changes: 6 additions & 10 deletions hypothesis-python/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -156,22 +156,18 @@ commands =
niche: bash scripts/other-tests.sh
custom: python -bb -X dev -m pytest {posargs}

[testenv:django32]
commands =
pip install .[pytz]
pip install django~=3.2.15
python -bb -X dev -m tests.django.manage test tests.django {posargs}

[testenv:django41]
[testenv:django42]
setenv=
PYTHONWARNDEFAULTENCODING=1
commands =
pip install django~=4.1.0
pip install django~=4.2.0
python -bb -X dev -m tests.django.manage test tests.django {posargs}

[testenv:django42]
[testenv:django50]
setenv=
PYTHONWARNDEFAULTENCODING=1
commands =
pip install django~=4.2.0
pip install django~=5.0.0
python -bb -X dev -m tests.django.manage test tests.django {posargs}

[testenv:py{37,38,39}-nose]
Expand Down
2 changes: 1 addition & 1 deletion tooling/src/hypothesistooling/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ def standard_tox_task(name, py=ci_version):
standard_tox_task("py39-pytest54", py="3.9")
standard_tox_task("pytest62")

for n in [32, 41, 42]:
for n in [42, 50]:
standard_tox_task(f"django{n}")

for n in [13, 14, 15, 20, 21, 22]:
Expand Down

0 comments on commit 8926fc2

Please sign in to comment.