diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d55b1752c..544d71fedb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - python-version: ['3.10', '3.13'] + python-version: ['3.10', '3.14'] db-backend: [mysql, postgres] steps: - uses: actions/checkout@v6 @@ -94,7 +94,7 @@ jobs: - name: Run package status tests first run: | pytest rdmo/core/tests/test_package_status.py --nomigrations --verbose - if: matrix.python-version == '3.13' && matrix.db-backend == 'postgres' + if: matrix.python-version == '3.14' && matrix.db-backend == 'postgres' - name: Run Tests run: | pytest -p randomly -p no:cacheprovider --cov --reuse-db --numprocesses=auto --dist=loadscope @@ -114,7 +114,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - python-version: ['3.13'] + python-version: ['3.14'] db-backend: [postgres] steps: - uses: actions/checkout@v6 @@ -184,7 +184,7 @@ jobs: persist-credentials: false - uses: actions/setup-python@v6 with: - python-version: "3.13" + python-version: "3.14" cache: pip - run: python -Im pip install --editable .[dev] - run: python -Ic 'import rdmo; print(rdmo.__version__)' @@ -199,7 +199,7 @@ jobs: persist-credentials: false - uses: actions/setup-python@v6 with: - python-version: "3.13" + python-version: "3.14" cache: pip - name: Download wheel uses: actions/download-artifact@v6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 170b542dd5..3b51214069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog 📔 +## [RDMO 2.5.0](https://github.com/rdmorganiser/rdmo/releases/tag/2.5.0) + +**Milestone**: [2.5.0](https://github.com/rdmorganiser/rdmo/milestone/26) + +**Commit history**: [2.4.0...2.5.0](https://github.com/rdmorganiser/rdmo/compare/2.4.0...2.5.0) + + ## [RDMO 2.4.0](https://github.com/rdmorganiser/rdmo/releases/tag/2.4.0) (December 15, 2025) ### Main improvements ⭐ diff --git a/pyproject.toml b/pyproject.toml index 92ab2654e5..be816f08ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ requires-python = ">=3.10" classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", - "Framework :: Django :: 4.2", + "Framework :: Django :: 5.2", "Intended Audience :: Science/Research", "Operating System :: OS Independent", "Programming Language :: Python", @@ -31,6 +31,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dynamic = [ "version", @@ -41,7 +42,7 @@ dependencies = [ # in minor version updates anytime "defusedcsv>=2.0,<4.0", "defusedxml>=0.7.1,<1.0", - "django>=4.2,<5.0", + "django>=5.2.8,<6.0", "django-cleanup>=8.0,<10.0", "django-compressor>=4.4,<5.0", "django-extensions>=3.2,<5.0", @@ -79,7 +80,7 @@ allauth = [ dev = [ "pipdeptree>=2.13,<3.0", "pre-commit>=3.4,<5.0", - "setuptools>=73,<81", + "setuptools>=73,<83", ] gunicorn = [ "gunicorn>=23.0,<24.0", @@ -203,15 +204,11 @@ markers = [ "e2e: marks tests as end-to-end tests using playwright (deselect with '-m \"not e2e\"')", ] filterwarnings = [ - # fail on RemovedInDjango50Warning exception - "error::django.utils.deprecation.RemovedInDjango50Warning", + # throw an error when using methods deprecated in the next django version + "error::django.utils.deprecation.RemovedInNextVersionWarning", # ignore warnings raised by widget_tweaks.py "ignore:'maxsplit' is passed as positional argument", - - # ignore warnings raised from within django itself - # django/core/files/storage/__init__.py - "ignore:django.core.files.storage.get_storage_class is deprecated:django.utils.deprecation.RemovedInDjango51Warning", ] [tool.coverage.run] diff --git a/rdmo/core/settings.py b/rdmo/core/settings.py index 237846cef6..2531e8c4b4 100644 --- a/rdmo/core/settings.py +++ b/rdmo/core/settings.py @@ -75,6 +75,8 @@ }, ] +MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage" + COMPRESS_PRECOMPILERS = ( ('text/x-scss', 'django_libsass.SassCompiler'), ) diff --git a/rdmo/core/tests/test_utils.py b/rdmo/core/tests/test_utils.py index 2c446d5192..eae862cbe7 100644 --- a/rdmo/core/tests/test_utils.py +++ b/rdmo/core/tests/test_utils.py @@ -42,7 +42,11 @@ ] invalid_date_strings = [ - ("2025-02-31","day is out of range for month"), + ("2025-02-31", ( + "day is out of range for month", # Python 3.10 + "day 31 must be in range 1..28 for month 2 in year 2025" # Python 3.14 + ) + ), ("2025-17-02", "month must be in 1..12"), ("99/99/9999", "Invalid date format"), ("abcd-ef-gh", "Invalid date format"), @@ -91,11 +95,14 @@ def test_parse_date_from_string_valid_formats(settings, locale, date_string, exp @pytest.mark.parametrize("invalid_date, error_msg", invalid_date_strings) def test_parse_date_from_string_invalid_formats(settings, invalid_date, error_msg): - if not isinstance(invalid_date,str): - with pytest.raises(TypeError, match=error_msg): + patterns = error_msg if isinstance(error_msg, (tuple, list)) else (error_msg,) + match = "|".join(f"(?:{pattern})" for pattern in patterns) + + if not isinstance(invalid_date, str): + with pytest.raises(TypeError, match=match): parse_date_from_string(invalid_date) else: - with pytest.raises(ValueError,match=error_msg): + with pytest.raises(ValueError, match=match): parse_date_from_string(invalid_date) diff --git a/rdmo/views/templates/views/tags/value.html b/rdmo/views/templates/views/tags/value.html index 0e307fa2bd..61f4826ffe 100644 --- a/rdmo/views/templates/views/tags/value.html +++ b/rdmo/views/templates/views/tags/value.html @@ -1,5 +1 @@ -{% if value.file_url %} -{% include 'views/tags/value_file.html' %} -{% else %} -{{ value.value_and_unit }} -{% endif %} +{% if value.file_url %}{% include 'views/tags/value_file.html' %}{% else %}{{ value.value_and_unit }}{% endif %} \ No newline at end of file diff --git a/rdmo/views/templates/views/tags/value_inline_list.html b/rdmo/views/templates/views/tags/value_inline_list.html index b446d846c4..b7ee8b014f 100644 --- a/rdmo/views/templates/views/tags/value_inline_list.html +++ b/rdmo/views/templates/views/tags/value_inline_list.html @@ -1,3 +1 @@ -{% for value in values %} - {{ value.value_and_unit }}{% if not forloop.last %}; {% endif %} -{% endfor %} +{% for value in values %}{{ value.value_and_unit }}{% if not forloop.last %}; {% endif %}{% endfor %} \ No newline at end of file diff --git a/testing/config/settings/base.py b/testing/config/settings/base.py index 23cd12fa07..d53b5f583f 100644 --- a/testing/config/settings/base.py +++ b/testing/config/settings/base.py @@ -1,4 +1,5 @@ import os +from warnings import filterwarnings from django.utils.translation import gettext_lazy as _ @@ -110,3 +111,13 @@ PROJECT_CONTACT = True PROJECT_CONTACT_RECIPIENTS = ['email@example.com'] + +# Ref: https://adamj.eu/tech/2023/12/07/django-fix-urlfield-assume-scheme-warnings +filterwarnings( + "ignore", "The FORMS_URLFIELD_ASSUME_HTTPS transitional setting is deprecated." +) +# This value will change from False to True in Django 6.0 +# Refs: +# - https://docs.djangoproject.com/en/5.2/ref/settings/#forms-urlfield-assume-https +# - https://docs.djangoproject.com/en/5.2/ref/forms/fields/#django.forms.URLField.assume_scheme +FORMS_URLFIELD_ASSUME_HTTPS = True diff --git a/testing/export/project.html b/testing/export/project.html index 956c01e3ce..2094cb854e 100644 --- a/testing/export/project.html +++ b/testing/export/project.html @@ -8,34 +8,34 @@
Text?
-Lorem ipsum dolor sit amet + Lorem ipsum dolor sit amet
Textarea?
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Yes or no?
-Yes + Yes
Radio buttons?
-Text: Lorem ipsum + Text: Lorem ipsum
Select drop-down?
-One + One
Select drop-down (free)?
Range slider?
-37 + 37
File?
@@ -45,66 +45,66 @@Date picker?
-Jan. 1, 2018 + Jan. 1, 2018
Text?
Textarea?
Yes or no?
Radio buttons?
Select drop-down?
Range slider?
Date picker?
Checkbox?
Text?
-Lorem ipsum dolor sit amet + Lorem ipsum dolor sit amet
Textarea?
-Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Yes or no?
-Yes + Yes
Radio buttons?
-Text: Lorem ipsum + Text: Lorem ipsum
Select drop-down?
-One + One
Select drop-down (free)?
Range slider?
-37 + 37
Date picker?
-Jan. 1, 2018 + Jan. 1, 2018
File?
@@ -194,80 +194,80 @@
Text?
Textarea?
Yes or no?
Radio buttons?
Select drop-down?
Select drop-down (free)?
Range slider?
Date picker?
File?
@@ -282,96 +282,96 @@Checkbox?
Text?
Set "First": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr + Lorem ipsum dolor sit amet, consetetur sadipscing elitr
Set "Second": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr + Lorem ipsum dolor sit amet, consetetur sadipscing elitr
Textarea?
Set "First": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Set "Second": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Yes or no?
Set "First": -Yes + Yes
Set "Second": -No + No
Radio buttons?
Set "First": -One + One
Set "Second": -Two + Two
Select drop-down?
Set "First": -One + One
Set "Second": -Two + Two
Select drop-down (free)?
Range slider?
Set "First": -1 + 1
Set "Second": -2 + 2
Date picker?
Set "First": -Jan. 7, 2018 + Jan. 7, 2018
Set "Second": -Feb. 7, 2018 + Feb. 7, 2018
File?
Text?
Set "First": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr + Lorem ipsum dolor sit amet, consetetur sadipscing elitr
Set "Second": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr + Lorem ipsum dolor sit amet, consetetur sadipscing elitr
Textarea?
Set "First": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Set "Second": -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est. Lorem ipsum dolor sit amet.
Yes or no?
@@ -379,13 +379,13 @@
@@ -393,13 +393,13 @@
Radio buttons?
@@ -408,13 +408,13 @@@@ -422,13 +422,13 @@
Select drop-down?
@@ -437,15 +437,15 @@Set "Second": -Three + Three
Select drop-down (free)?
Range slider?
@@ -454,15 +454,15 @@Set "Second": -86 + 86
Date picker?
@@ -470,10 +470,10 @@
@@ -481,10 +481,10 @@
File?
@@ -494,37 +494,37 @@Set "Second": -One + One
Text
-test + test
Option
-One + One
text_contains?
-test + test
text empty?
text_equal?
-test + test
text_greater_than?
@@ -537,7 +537,7 @@text_not_empty?
-test + test
text_not_equal?
@@ -546,12 +546,12 @@option_equal?
-One + One
option_not_empty?
-One + One
option_not_equal?
@@ -594,20 +594,20 @@A?
Set "First", Block #1: -a0 + a0
Set "First", Block #2: -a1 + a1
B?
Set "First", Block #1: -b1 + b1
Set "First", Block #2: -b1 + b1
C?
@@ -615,10 +615,10 @@
@@ -626,40 +626,40 @@
Y?
Set "First", Block #1, Set #1: -Three + Three
Set "First", Block #2, Set #1: -Three + Three
Set "Second", Block #1, Set #1: -Three + Three
Set "Second", Block #2, Set #1: -Three + Three
Set "Second", Block #3, Set #1: -One + One
Set "Second", Block #3, Set #2: -Two + Two
Set "Second", Block #3, Set #3: -Three + Three
Question