From: Radek Czajka Date: Mon, 5 Jul 2021 22:07:17 +0000 (+0200) Subject: 0.5: Django 3.2 support, drop Django<1.11, Python<3.6, remove some compatibility... X-Git-Tag: 0.5 X-Git-Url: https://git.mdrn.pl/fnpdjango.git/commitdiff_plain/1be598eb573f9ad234ba4ab8e467f07fd8351fa8?ds=inline 0.5: Django 3.2 support, drop Django<1.11, Python<3.6, remove some compatibility stubs. --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec1475..0208d6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ This document records all notable changes to fnpdjango. +## 0.5 (2021-07-05) + +- Support for Django up to 3.2. +- Dropped support for Django < 1.11 and Python < 3.6. +- GzipPipelineCachedStorage replaced by GzipPipelineManifestStorage +- Removed `utils.urls.i18n_patterns` and `URLLocaleMiddleware` in favor + of stock `i18n_patterns(prefix_default_language=False) and + `LocaleMiddleware`. + + ## 0.4.5 (2020-03-26) - Support for Django up do 3.0. diff --git a/fnpdjango/actions.py b/fnpdjango/actions.py index 1e1316a..0855f72 100644 --- a/fnpdjango/actions.py +++ b/fnpdjango/actions.py @@ -1,17 +1,8 @@ # Source: https://gist.github.com/jeremyjbowers/e8d007446155c12033e6 -from __future__ import unicode_literals - import csv from django.http import HttpResponse from django.utils.translation import ugettext_lazy as _ -try: - unicode -except NameError: - pass -else: - str = unicode - def export_as_csv_action(description=_("Export selected objects as CSV file"), fields=None, exclude=None, header=True): """ diff --git a/fnpdjango/management/commands/makecontribmessages.py b/fnpdjango/management/commands/makecontribmessages.py index 966988c..6e7c3d3 100755 --- a/fnpdjango/management/commands/makecontribmessages.py +++ b/fnpdjango/management/commands/makecontribmessages.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from __future__ import print_function - import os from optparse import make_option from django.core.management.base import BaseCommand diff --git a/fnpdjango/middleware.py b/fnpdjango/middleware.py index 734e878..14ac28e 100644 --- a/fnpdjango/middleware.py +++ b/fnpdjango/middleware.py @@ -1,46 +1,6 @@ +from django.utils.deprecation import MiddlewareMixin from . import app_settings -try: - # Django >= 1.10 - from django.utils.deprecation import MiddlewareMixin -except ImportError: - # Django <= 1.9 - MiddlewareMixin = object - - from django.conf import settings - from django.http import Http404 - from django.utils import translation - - class URLLocaleMiddleware(MiddlewareMixin): - """Decides which translation to use, based on path only.""" - def process_request(self, request): - language = translation.get_language_from_path(request.path_info) - if language: - translation.activate(language) - request.LANGUAGE_CODE = translation.get_language() - if language == settings.LANGUAGE_CODE: - raise Http404 - - def process_response(self, request, response): - language = translation.get_language() - translation.deactivate() - if 'Content-Language' not in response: - response['Content-Language'] = language - return response -else: - # Django >= 1.10 - import warnings - from django.middleware.locale import LocaleMiddleware - - class URLLocaleMiddleware(LocaleMiddleware): - def __init__(self, *args, **kwargs): - warnings.warn( - "As of Django 1.10, fnpdjango.middleware.URLLocaleMiddleware " - "is deprecated in favor of " - "django.middleware.locale.LocaleMiddleware.", - DeprecationWarning) - super(URLLocaleMiddleware, self).__init__(*args, **kwargs) - class SetRemoteAddrFromXRealIP(MiddlewareMixin): """Sets REMOTE_ADDR from the X-Real-IP header, as set by Nginx.""" diff --git a/fnpdjango/pipeline_storage.py b/fnpdjango/pipeline_storage.py index eb12f07..85e44c8 100644 --- a/fnpdjango/pipeline_storage.py +++ b/fnpdjango/pipeline_storage.py @@ -1,6 +1,7 @@ from pipeline.storage import GZIPMixin -from pipeline.storage import PipelineCachedStorage +from pipeline.storage import PipelineManifestStorage -class GzipPipelineCachedStorage(GZIPMixin, PipelineCachedStorage): + +class GzipPipelineManifestStorage(GZIPMixin, PipelineManifestStorage): pass diff --git a/fnpdjango/storage.py b/fnpdjango/storage.py index 31674e8..f282745 100644 --- a/fnpdjango/storage.py +++ b/fnpdjango/storage.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # diff --git a/fnpdjango/templatetags/fnp_lang.py b/fnpdjango/templatetags/fnp_lang.py index dd6c339..14e0318 100644 --- a/fnpdjango/templatetags/fnp_lang.py +++ b/fnpdjango/templatetags/fnp_lang.py @@ -1,10 +1,5 @@ from django.conf import settings - -try: - from django.urls import resolve, reverse, Resolver404 -except ImportError: - from django.core.urlresolvers import resolve, reverse, Resolver404 - +from django.urls import resolve, reverse, Resolver404 from django import template from django.utils import translation from ..utils.views import get_current_object diff --git a/fnpdjango/templatetags/fnp_prevnext.py b/fnpdjango/templatetags/fnp_prevnext.py index cb4efe2..a808e6e 100644 --- a/fnpdjango/templatetags/fnp_prevnext.py +++ b/fnpdjango/templatetags/fnp_prevnext.py @@ -1,11 +1,7 @@ from copy import copy +from urllib.parse import urlencode from django.template import Library -try: - from urllib.parse import urlencode -except ImportError: - from urllib import urlencode - register = Library() diff --git a/fnpdjango/utils/fields.py b/fnpdjango/utils/fields.py index e638db5..4127e9d 100644 --- a/fnpdjango/utils/fields.py +++ b/fnpdjango/utils/fields.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from django.forms import CharField, ValidationError from .text.textilepl import textile_pl diff --git a/fnpdjango/utils/settings.py b/fnpdjango/utils/settings.py index 1f5ea2d..83b0302 100644 --- a/fnpdjango/utils/settings.py +++ b/fnpdjango/utils/settings.py @@ -1,19 +1,9 @@ """ Utilities for global settings. """ -from django.utils.encoding import python_2_unicode_compatible from django.utils.functional import Promise -# Use Python3 str. -try: - unicode -except NameError: - pass -else: - str = unicode - -@python_2_unicode_compatible class LazyUGettextLazy(Promise): """You can use it to internationalize strings in settings. diff --git a/fnpdjango/utils/text/__init__.py b/fnpdjango/utils/text/__init__.py index 5ebc318..d1cf41d 100644 --- a/fnpdjango/utils/text/__init__.py +++ b/fnpdjango/utils/text/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Text utilities. """ diff --git a/fnpdjango/utils/urls.py b/fnpdjango/utils/urls.py deleted file mode 100644 index 4e9916f..0000000 --- a/fnpdjango/utils/urls.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Utilities for urlconfs. -""" - -import django -if django.VERSION >= (1, 10): - import warnings - from django.conf.urls.i18n import i18n_patterns as django_i18n_patterns - - def i18n_patterns(*args): - warnings.warn( - "As of Django 1.10, fnpdjango.utils.urls.i18n_patterns " - "is deprecated in favor of directly using " - "django.urls.i18n_patterns(prefix_default_language=False).", - DeprecationWarning) - return django_i18n_patterns(*args, prefix_default_language=False) - -else: - # Django <= 1.9 - import re - from django.conf import settings - from django.core.urlresolvers import LocaleRegexURLResolver - from django.utils.translation import get_language - - class MyLocaleRegexURLResolver(LocaleRegexURLResolver): - """ - A URL resolver that always matches the active language code as URL prefix. - - Rather than taking a regex argument, we just override the ``regex`` - function to always return the active language-code as regex. - """ - @property - def regex(self): - language_code = get_language() - if language_code == settings.LANGUAGE_CODE: - return re.compile('') - if language_code not in self._regex_dict: - regex_compiled = re.compile('^%s/' % language_code, re.UNICODE) - self._regex_dict[language_code] = regex_compiled - return self._regex_dict[language_code] - - def i18n_patterns(*args): - """ - Adds the language code prefix to every URL pattern within this - function. This may only be used in the root URLconf, not in an included - URLconf. - """ - pattern_list = list(args) - if not settings.USE_I18N: - return pattern_list - return pattern_list + [MyLocaleRegexURLResolver(pattern_list)] diff --git a/runtests.py b/runtests.py index bb6ba15..c5b392f 100644 --- a/runtests.py +++ b/runtests.py @@ -1,13 +1,10 @@ #!/usr/bin/env python -# -*- coding: utf-8 # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See README.md for more information. # """ Creates a simple Django configuration and runs tests for fnpdjango. """ -from __future__ import unicode_literals - import sys import os from os.path import dirname, abspath @@ -39,6 +36,7 @@ if not settings.configured and not os.environ.get('DJANGO_SETTINGS_MODULE'): 'django.contrib.messages', 'django.contrib.sessions', 'django.contrib.sites', + 'django.contrib.staticfiles', 'fnpdjango', 'tests', @@ -46,17 +44,10 @@ if not settings.configured and not os.environ.get('DJANGO_SETTINGS_MODULE'): LANGUAGE_CODE='pl', MEDIA_ROOT=media_root, STATIC_URL='/static/', - MIDDLEWARE_CLASSES=[ # Django <= 1.9 - 'django.middleware.common.CommonMiddleware', - 'fnpdjango.middleware.URLLocaleMiddleware', - 'fnpdjango.middleware.SetRemoteAddrFromXRealIP', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - ], + STATIC_ROOT='./static/', + STATICFILES_STORAGE = 'fnpdjango.pipeline_storage.GzipPipelineManifestStorage', MIDDLEWARE=[ 'django.middleware.common.CommonMiddleware', - 'fnpdjango.middleware.URLLocaleMiddleware', 'fnpdjango.middleware.SetRemoteAddrFromXRealIP', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -82,15 +73,13 @@ if not settings.configured and not os.environ.get('DJANGO_SETTINGS_MODULE'): SECRET_KEY='x', DEBUG=True, SITE_ID=1, + + PIPELINE={} ) else: media_root = None -try: - from django.test.runner import DiscoverRunner -except ImportError: - # Django < 1.6 - from django.test.simple import DjangoTestSuiteRunner as DiscoverRunner +from django.test.runner import DiscoverRunner def runtests(*test_args, **kwargs): @@ -100,13 +89,8 @@ def runtests(*test_args, **kwargs): parent = dirname(abspath(__file__)) sys.path.insert(0, parent) - # For Django 1.7+ - try: - from django import setup - except ImportError: - pass - else: - setup() + from django import setup + setup() test_runner = DiscoverRunner( verbosity=kwargs.get('verbosity', 1), diff --git a/setup.py b/setup.py index 1a392f1..448d1f2 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # import os.path from setuptools import setup, find_packages @@ -23,7 +22,7 @@ def whole_trees(package_dir, paths): setup( name='fnpdjango', - version='0.4.5', + version='0.5', author='Radek Czajka', author_email='radekczajka@nowoczesnapolska.org.pl', url='', @@ -33,7 +32,7 @@ setup( 'fnpdjango.management.commands': ['babel.cfg'], }, install_requires=[ - 'Django>=1.4,<3.1', + 'Django>=1.11,<4.0', ], extras_require={ 'textile': [ diff --git a/tests/tests/__init__.py b/tests/tests/__init__.py index ef64f9f..e69de29 100644 --- a/tests/tests/__init__.py +++ b/tests/tests/__init__.py @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See README.md for more information. -# -""" -This file works only for django.test.simple.DjangoTestSuiteRunner -in Django<1.6. The newer django.test.runner.DiscoverRunner finds -test_* modules by itself. - -""" -from .test_actions import * -from .test_middleware import * -from .test_storage import * -from .test_templatetags_fnp_annoy import * -from .test_templatetags_fnp_markup import * -from .test_templatetags_macros import * -from .test_utils_settings import * -from .test_utils_urls import * diff --git a/tests/tests/test_storage.py b/tests/tests/test_storage.py index 2cfe79c..3da792f 100644 --- a/tests/tests/test_storage.py +++ b/tests/tests/test_storage.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See README.md for more information. # -from __future__ import unicode_literals - from tempfile import NamedTemporaryFile from django.core.files.base import ContentFile from django.test import TestCase diff --git a/tests/tests/test_templatetags_fnp_annoy.py b/tests/tests/test_templatetags_fnp_annoy.py index 8ed80b1..e0ed677 100644 --- a/tests/tests/test_templatetags_fnp_annoy.py +++ b/tests/tests/test_templatetags_fnp_annoy.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See README.md for more information. # -from __future__ import unicode_literals - from django.test import TestCase from django.test.utils import override_settings diff --git a/tests/tests/test_templatetags_fnp_markup.py b/tests/tests/test_templatetags_fnp_markup.py index 82fba0c..b858391 100644 --- a/tests/tests/test_templatetags_fnp_markup.py +++ b/tests/tests/test_templatetags_fnp_markup.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See README.md for more information. # -from __future__ import unicode_literals - from django.test import TestCase diff --git a/tests/tests/test_templatetags_macros.py b/tests/tests/test_templatetags_macros.py index 8fd7823..f45ee54 100644 --- a/tests/tests/test_templatetags_macros.py +++ b/tests/tests/test_templatetags_macros.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.test import TestCase from django.template import Template, Context diff --git a/tests/tests/test_utils_settings.py b/tests/tests/test_utils_settings.py index 7dc0f7d..66f3279 100644 --- a/tests/tests/test_utils_settings.py +++ b/tests/tests/test_utils_settings.py @@ -1,19 +1,9 @@ -# -*- coding: utf-8 -*- # This file is part of FNPDjango, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See README.md for more information. # -from __future__ import unicode_literals - from django.conf import settings from django.test import TestCase -try: - unicode -except NameError: - pass -else: - str = unicode - class UtilsSettingsTestCase(TestCase): def test_lazy_ugettext_lazy(self): diff --git a/tests/tests/test_utils_urls.py b/tests/tests/test_utils_urls.py deleted file mode 100644 index 397e54d..0000000 --- a/tests/tests/test_utils_urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.test import TestCase - - -class UrlsTestCase(TestCase): - def test_i18n_patterns(self): - self.assertEqual(self.client.get('/').content.decode('latin1'), 'pl') - self.assertEqual(self.client.get('/en/').content.decode('latin1'), 'en') diff --git a/tests/urls.py b/tests/urls.py index e9ee19f..bffe5bb 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -1,15 +1,9 @@ from django.conf.urls import url from django.contrib import admin -from fnpdjango.utils.urls import i18n_patterns from . import views -# For Django < 1.7. -admin.autodiscover() - urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^ip/$', views.ip), -] + i18n_patterns( - url(r'^$', views.get_lang), -) +] diff --git a/tests/views.py b/tests/views.py index 0c8ee47..c473923 100644 --- a/tests/views.py +++ b/tests/views.py @@ -1,9 +1,4 @@ from django.http import HttpResponse -from django.utils.translation import get_language - - -def get_lang(request): - return HttpResponse(get_language()) def ip(request): diff --git a/tox.ini b/tox.ini index 22102fa..dc820d4 100644 --- a/tox.ini +++ b/tox.ini @@ -3,31 +3,26 @@ # [tox] envlist=clear, - d1{4,5,6}-py27, - d17-py27, - d{18,19,110}-py{27,35}, - d111-py{27,35,36,37}, - d20-py{35,36,37}, - d21-py{35,36,37}, - d22-py{35,36,37,38}, + d111-py{36,37}, + d20-py{36,37}, + d21-py{36,37}, + d22-py{36,37,38}, d30-py{36,37,38}, + d31-py{36,37,38,39}, + d32-py{36,37,38,39}, stats [testenv] commands=coverage run --source=fnpdjango --append --branch runtests.py deps= - d14: Django>=1.4,<1.5 - d15: Django>=1.5,<1.6 - d16: Django>=1.6,<1.7 - d17: Django>=1.7,<1.8 - d18: Django>=1.8,<1.9 - d19: Django>=1.9,<1.10 - d110: Django>=1.10,<1.11 + django-pipeline==2.0.5 d111: Django>=1.11,<2.0 d20: Django>=2.0,<2.1 d21: Django>=2.1,<2.2 d22: Django>=2.2,<3.0 d30: Django>=3.0,<3.1 + d31: Django>=3.1,<3.2 + d32: Django>=3.2,<4.0 coverage extras= textile