diff --git a/compressor/base.py b/compressor/base.py index 8c53db2..624a273 100644 --- a/compressor/base.py +++ b/compressor/base.py @@ -2,9 +2,8 @@ from __future__ import with_statement, unicode_literals import os import codecs +import django from django.core.files.base import ContentFile -from django.template import Context -from django.template.loader import render_to_string try: from importlib import import_module except: @@ -32,6 +31,18 @@ SOURCE_HUNK, SOURCE_FILE = 'inline', 'file' METHOD_INPUT, METHOD_OUTPUT = 'input', 'output' +if django.VERSION < (1, 8): + # Provide render_to_string that is similar to Django 1.8 version, for our + # needs, using what < 1.8 provides: + from django.template.loader import render_to_string as django_render_to_string + + def render_to_string(template_name, context=None): + return django_render_to_string(template_name, dictionary=context) + +else: + from django.template.loader import render_to_string + + class Compressor(object): """ Base compressor object to be subclassed for content type @@ -347,8 +358,14 @@ class Compressor(object): self.context['compressed'].update(context or {}) self.context['compressed'].update(self.extra_context) - final_context = Context(self.context) + if hasattr(self.context, 'flatten'): + # Django 1.8 complains about Context being passed to its + # Template.render function. + final_context = self.context.flatten() + else: + final_context = self.context + post_compress.send(sender=self.__class__, type=self.type, mode=mode, context=final_context) template_name = self.get_template_name(mode) - return render_to_string(template_name, context_instance=final_context) + return render_to_string(template_name, context=final_context) diff --git a/compressor/management/commands/compress.py b/compressor/management/commands/compress.py index 629d9cd..7b706fa 100644 --- a/compressor/management/commands/compress.py +++ b/compressor/management/commands/compress.py @@ -60,8 +60,6 @@ class Command(NoArgsCommand): dest="engine"), ) - requires_model_validation = False - def get_loaders(self): if django.VERSION < (1, 8): from django.template.loader import template_source_loaders @@ -302,3 +300,9 @@ class Command(NoArgsCommand): "Offline compression is disabled. Set " "COMPRESS_OFFLINE or use the --force to override.") self.compress(sys.stdout, **options) + + +if django.VERSION < (1, 7): + Command.requires_model_validation = False +else: + Command.requires_system_checks = False diff --git a/compressor/parser/default_htmlparser.py b/compressor/parser/default_htmlparser.py index 80272cb..825808b 100644 --- a/compressor/parser/default_htmlparser.py +++ b/compressor/parser/default_htmlparser.py @@ -1,3 +1,5 @@ +import sys + from django.utils import six from django.utils.encoding import smart_text @@ -5,9 +7,26 @@ from compressor.exceptions import ParserError from compressor.parser import ParserBase +# Starting in Python 3.2, the HTMLParser constructor takes a 'strict' +# argument which default to True (which we don't want). +# In Python 3.3, it defaults to False. +# In Python 3.4, passing it at all raises a deprecation warning. +# So we only pass it for 3.2. +# In Python 3.4, it also takes a 'convert_charrefs' argument +# which raises a warning if we don't pass it. +major, minor, release = sys.version_info[:3] +CONSTRUCTOR_TAKES_STRICT = major == 3 and minor == 2 +CONSTRUCTOR_TAKES_CONVERT_CHARREFS = major == 3 and minor >= 4 +HTML_PARSER_ARGS = {} +if CONSTRUCTOR_TAKES_STRICT: + HTML_PARSER_ARGS['strict'] = False +if CONSTRUCTOR_TAKES_CONVERT_CHARREFS: + HTML_PARSER_ARGS['convert_charrefs'] = False + + class DefaultHtmlParser(ParserBase, six.moves.html_parser.HTMLParser): def __init__(self, content): - six.moves.html_parser.HTMLParser.__init__(self) + six.moves.html_parser.HTMLParser.__init__(self, **HTML_PARSER_ARGS) self.content = content self._css_elems = [] self._js_elems = [] diff --git a/compressor/storage.py b/compressor/storage.py index 16419a8..6fe994e 100644 --- a/compressor/storage.py +++ b/compressor/storage.py @@ -36,7 +36,7 @@ class CompressorFileStorage(FileSystemStorage): def modified_time(self, name): return datetime.fromtimestamp(os.path.getmtime(self.path(name))) - def get_available_name(self, name): + def get_available_name(self, name, max_length=None): """ Deletes the given file if it exists. """ diff --git a/compressor/tests/test_offline.py b/compressor/tests/test_offline.py index aa10cf0..3a7f1b2 100644 --- a/compressor/tests/test_offline.py +++ b/compressor/tests/test_offline.py @@ -201,9 +201,6 @@ class OfflineCompressBasicTestCase(OfflineTestCaseMixin, TestCase): for engine in self.engines: self._test_deleting_manifest_does_not_affect_rendering(engine) - def test_requires_model_validation(self): - self.assertFalse(CompressCommand.requires_model_validation) - def test_get_loaders(self): TEMPLATE_LOADERS = ( ('django.template.loaders.cached.Loader', (