From cd5055835a08686533b57c4003ee94927758a7a5 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 13:33:46 +0200 Subject: [PATCH 01/15] [Django 1.9] TemplateDoesNotExist removed TemplateDoesNotExist is a private function that should never be used. In Django 1.9, upstream authors decided to move it to another path. This patch defines TemplateDoesNotExist directly in jingo instead of using the internal Django version. --- jingo/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index 503200a..59603ed 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -8,7 +8,7 @@ from django.apps import apps from django.conf import settings -from django.template.base import Origin, TemplateDoesNotExist +from django.template.base import Origin from django.template.loader import BaseLoader try: @@ -72,6 +72,8 @@ def get_standard_processors(): _helpers_loaded = False +class TemplateDoesNotExist(Exception): + pass class Template(jinja2.Template): From cd8bfdfbe063352cf05194b0020d70bc592e1a00 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 13:35:07 +0200 Subject: [PATCH 02/15] [Django 1.9] run_tests.py must call django.setup() This patch adds a call to django.setup() which is now needed in Django. --- run_tests.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/run_tests.py b/run_tests.py index 14186d5..0ba13d2 100644 --- a/run_tests.py +++ b/run_tests.py @@ -10,9 +10,11 @@ os.environ['PYTHONPATH'] = os.pathsep.join([ROOT, os.path.join(ROOT, 'examples')]) +import django +if hasattr(django, 'setup'): + django.setup() + +from django.contrib.contenttypes.models import ContentType + if __name__ == '__main__': - if hasattr(django, 'setup'): - # Django's app registry was added in 1.7. We need to call `setup` to - # initiate it. - django.setup() nose.main() From 46a6b36a04565295cd4254e7f8fb960403f5c97f Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 13:36:01 +0200 Subject: [PATCH 03/15] [Django 1.9] Use six, but not from Django Django 1.9 removed django.utils.six. Jingo then should use six directly, not from Django. --- jingo/ext.py | 2 +- jingo/monkey.py | 2 +- jingo/tests/test_helpers.py | 2 +- jingo/tests/test_monkey.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jingo/ext.py b/jingo/ext.py index 10294c9..cfed547 100644 --- a/jingo/ext.py +++ b/jingo/ext.py @@ -10,7 +10,7 @@ from django.core.urlresolvers import reverse from django.http import QueryDict from django.template.defaulttags import CsrfTokenNode -from django.utils import six +import six from django.utils.encoding import smart_str try: from django.utils.encoding import smart_unicode as smart_text diff --git a/jingo/monkey.py b/jingo/monkey.py index 231c338..41e076a 100644 --- a/jingo/monkey.py +++ b/jingo/monkey.py @@ -20,7 +20,7 @@ from __future__ import absolute_import, print_function, unicode_literals -from django.utils import six +import six def __html__(self): diff --git a/jingo/tests/test_helpers.py b/jingo/tests/test_helpers.py index ce387cc..c6202d5 100644 --- a/jingo/tests/test_helpers.py +++ b/jingo/tests/test_helpers.py @@ -7,7 +7,7 @@ from datetime import datetime from collections import namedtuple -from django.utils import six +import six from jinja2 import Markup try: from unittest.mock import patch diff --git a/jingo/tests/test_monkey.py b/jingo/tests/test_monkey.py index c9e4bee..dc0217c 100644 --- a/jingo/tests/test_monkey.py +++ b/jingo/tests/test_monkey.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django import forms -from django.utils import six +import six from jinja2 import escape from nose.tools import eq_ From cf4ef5591092da24dd1b23cd15359f652827e903 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 13:37:36 +0200 Subject: [PATCH 04/15] [Django 1.10] django.template.loader.BaseLoader removed In Django 1.10, django.template.loader.BaseLoader is removed completely. This patch uses django.template.loaders.base.Loader instead. --- jingo/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index 59603ed..810d520 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -9,7 +9,7 @@ from django.apps import apps from django.conf import settings from django.template.base import Origin -from django.template.loader import BaseLoader +from django.template.loaders.base import Loader as BaseLoader try: from importlib import import_module From 7368caa5d2378cbfee9db282f74b9f0f1887806a Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 13:38:55 +0200 Subject: [PATCH 05/15] [Django 1.10] add a few things to INSTALLED_APPS In Django 1.10, we need to add this to INSTALLED_APPS: django.contrib.sites django.contrib.contenttypes django.contrib.auth Without this, unit tests are failing over with not-found templates. --- fake_settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fake_settings.py b/fake_settings.py index 8ed2717..d2dff7c 100644 --- a/fake_settings.py +++ b/fake_settings.py @@ -7,6 +7,9 @@ 'django.contrib.admin.apps.SimpleAdminConfig', 'jingo.tests.jinja_app', 'jingo.tests.django_app', + 'django.contrib.sites', + 'django.contrib.contenttypes', + 'django.contrib.auth', ) TEMPLATE_LOADERS = ( 'jingo.Loader', From 27c96cfc8ab75d2c558d858e7a3c3845fd4a2db0 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:26:31 +0200 Subject: [PATCH 06/15] [Django 1.10] defines TEMPLATES In Django 1.10, many things which were previously declared separatly now have to go in a TEMPLATES = [] object. --- fake_settings.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fake_settings.py b/fake_settings.py index d2dff7c..5ab1314 100644 --- a/fake_settings.py +++ b/fake_settings.py @@ -21,3 +21,24 @@ ROOT_URLCONF = 'jingo.tests.urls' SECRET_KEY = 'jingo' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [path('jingo/tests/templates'),], + 'OPTIONS': { + 'debug': True, + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + 'loaders': [ + 'jingo.Loader', + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', + ], + }, + }, +] From 2f9ec3f1a403f87e034388374c7f34a8fe2ad010 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:27:37 +0200 Subject: [PATCH 07/15] [Django 1.10] Object settings.TEMPLATE_DEBUG doesn't exist In Django 1.10, settings.TEMPLATE_DEBUG. Instead, we should use settings.TEMPLATES[0]['OPTIONS']['debug']. --- jingo/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index 810d520..ed5d7ff 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -5,6 +5,7 @@ import functools import logging import re +from copy import deepcopy from django.apps import apps from django.conf import settings @@ -96,7 +97,8 @@ class FakeRequestContext: context = FakeRequestContext() # Used by debug_toolbar. - if settings.TEMPLATE_DEBUG: + TEMPLATES_copy = deepcopy(settings.TEMPLATES) + if TEMPLATES_copy[0]['OPTIONS']['debug']: from django.test import signals self.origin = Origin(self.filename) signals.template_rendered.send(sender=self, template=self, From ef02f428946183522f4c1c23cff73897b3d4dee4 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:29:26 +0200 Subject: [PATCH 08/15] [Django 1.10] django.forms.util renamed In Django 1.10, django.forms.util was renamed django.forms.utils (deprecation cycle ended, and there's no fallback). --- jingo/monkey.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jingo/monkey.py b/jingo/monkey.py index 41e076a..6c6528c 100644 --- a/jingo/monkey.py +++ b/jingo/monkey.py @@ -28,15 +28,15 @@ def __html__(self): def patch(): - from django.forms import forms, formsets, util, widgets + from django.forms import forms, formsets, utils, widgets # Add __html__ methods to these classes: classes = [ forms.BaseForm, forms.BoundField, formsets.BaseFormSet, - util.ErrorDict, - util.ErrorList, + utils.ErrorDict, + utils.ErrorList, widgets.Media, widgets.RadioFieldRenderer, ] From 5aa719e12453f08fbf14ca16e56e4effb9ac2586 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:30:16 +0200 Subject: [PATCH 09/15] [Django 1.10] Loader method __init__() takes 2 args In Django 1.10, the __init__() method of the Loader class takes 2 args, not 1 anymore. This patch fixes that. --- jingo/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index ed5d7ff..875fa61 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -239,7 +239,7 @@ def wrapper(*args, **kw): class Loader(BaseLoader): is_usable = True - def __init__(self): + def __init__(self, args): if has_engine: super(Loader, self).__init__(Engine.get_default()) else: From 91faddabf4c4d04a274a9ae983b128737ebbf29a Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:31:22 +0200 Subject: [PATCH 10/15] [Django 1.10] urls.patterns-removed In Django 1.10, django.conf.urls.patterns (and its associated function) doesn't exist anymore, and we *must* use url(), not just () for the urlpatterns tuples. --- jingo/tests/urls.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jingo/tests/urls.py b/jingo/tests/urls.py index f062720..e256c9b 100644 --- a/jingo/tests/urls.py +++ b/jingo/tests/urls.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals -from django.conf.urls import patterns +from django.conf.urls import url -urlpatterns = patterns('', - (r'^url/(\d+)/(\w+)/$', lambda r: None, {}, "url-args"), - (r'^url/(?P\d+)/(?P\w+)/$', lambda r: None, {}, "url-kwargs"), -) +urlpatterns = [ + url(r'^url/(\d+)/(\w+)/$', lambda r: None, {}, "url-args"), + url(r'^url/(?P\d+)/(?P\w+)/$', lambda r: None, {}, "url-kwargs"), +] From a5b782ee737e8275aa084fb2502e2d40d2386257 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 14:53:46 +0200 Subject: [PATCH 11/15] [Django 1.7] Retain django 1.7 compat django.template.loaders.base doesn't exist in Django 1.7. This patch makes the Django 1.10 to continue to work with older version. --- jingo/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index 875fa61..c8e4973 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -10,7 +10,10 @@ from django.apps import apps from django.conf import settings from django.template.base import Origin -from django.template.loaders.base import Loader as BaseLoader +try: + from django.template.loader import BaseLoader +except ImportError: + from django.template.loaders.base import Loader as BaseLoader try: from importlib import import_module From d1d1a414297b847db45e0d37dec88aae06a7ba90 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 15:08:12 +0200 Subject: [PATCH 12/15] [Django 1.9] Also test with Django 1.9 --- tox.ini | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index d3805bc..b8eac7a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-1.7, py27-1.8, py33-1.7, py33-1.8, py34-1.7, py34-1.8 +envlist = py27-1.7, py27-1.8, py27-1.9, py33-1.7, py33-1.8, py34-1.7, py34-1.8, py34-1.9 toxworkdir = {homedir}/.tox-jingo [testenv] @@ -22,6 +22,12 @@ deps = Django>=1.8,<1.9 {[testenv]deps} +[testenv:py27-1.9] +basepython = python2.7 +deps = + Django>=1.9,<1.10 + {[testenv]deps} + [testenv:py33-1.7] basepython = python3.3 deps = @@ -46,6 +52,12 @@ deps = Django>=1.8,<1.9 {[testenv]deps} +[testenv:py34-1.9] +basepython = python3.4 +deps = + Django>=1.9,<1.10 + {[testenv]deps} + [testenv:py35-1.8] basepython = python3.5 deps = From 692f15bd4dae13b5a5e3f41b40e5e23704b7d0de Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 15:31:58 +0200 Subject: [PATCH 13/15] [Django 1.9] As six as runtime requires Previous commit uses six, not from Django. This patch adds six as runtime requires. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0fbc4ea..4ffb440 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ packages=['jingo'], include_package_data=True, zip_safe=False, - install_requires=['jinja2'], + install_requires=['jinja2', 'six'], classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', From bbbcee2f2894f860562b7104e5815871312494e2 Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 15:34:00 +0200 Subject: [PATCH 14/15] [Django < 1.10] Set the 2nd param of __init__ optional Previous commit added a 2nd param for the __init__ of the Loader class. However, this broke compat with older version of Django. This patch solves that by making this 2nd parameter optional. --- jingo/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jingo/__init__.py b/jingo/__init__.py index c8e4973..7914e91 100644 --- a/jingo/__init__.py +++ b/jingo/__init__.py @@ -242,7 +242,7 @@ def wrapper(*args, **kw): class Loader(BaseLoader): is_usable = True - def __init__(self, args): + def __init__(self, args=None): if has_engine: super(Loader, self).__init__(Engine.get_default()) else: From 90c3aa21344645cb375c271a3c3db59b2ac9a66a Mon Sep 17 00:00:00 2001 From: Thomas Goirand Date: Mon, 25 Jul 2016 15:36:23 +0200 Subject: [PATCH 15/15] Also add six as deps in tox.ini --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index b8eac7a..9d46902 100644 --- a/tox.ini +++ b/tox.ini @@ -9,6 +9,7 @@ deps = jinja2 nose mock + six [testenv:py27-1.7] basepython = python2.7