From ff6fa993b4c95cc150ba01a3d32459134afb1ff0 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Fri, 23 Oct 2015 10:17:23 +0100 Subject: [PATCH 1/4] Fixed deprecation warnings for calling HTMLParser on Python 3.X The logic here comes from http://bazaar.launchpad.net/~leonardr/beautifulsoup/bs4/view/head:/bs4/builder/_htmlparser.py#L20, inspecting the stdlib code in different versions, and simplifying. I haven't included the monkey patch from beautifulsoup for Python 3.2.2 because I don't think the bug affects django-compressor's parsing of script tags. --- compressor/parser/default_htmlparser.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) 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 = [] From c76f76bdd47636c77a4ad16acc52b8cac2ab2b44 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Fri, 23 Oct 2015 10:30:42 +0100 Subject: [PATCH 2/4] Fixed Django 1.8+ deprecation warnings for changed render_to_string/render See https://docs.djangoproject.com/en/dev/releases/1.8/#dictionary-and-context-instance-arguments-of-rendering-functions Note we are fixing both the changed render_to_string function and the fact that Template.render doesn't want a 'Context' instance any more. There is a slight backwards incompatible change: the post_compress signal now receives a dictionary instead of a Context instance as its 'context' argument. However, this is compatible with what is publicly documented, which specifies a 'context dictionary': http://django-compressor.readthedocs.org/en/latest/usage/?highlight=context#compressor.signals.post_compress --- compressor/base.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) 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) From 544a63779c19b8ae1156c993e5875108010ec573 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Fri, 23 Oct 2015 11:13:03 +0100 Subject: [PATCH 3/4] Fixed Django 1.7+ deprecation warning for requires_model_validation See https://docs.djangoproject.com/en/1.8/howto/custom-management-commands/#django.core.management.BaseCommand.requires_system_checks Also removed a rather low value test which wasn't worth rewriting. --- compressor/management/commands/compress.py | 8 ++++++-- compressor/tests/test_offline.py | 3 --- 2 files changed, 6 insertions(+), 5 deletions(-) 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/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', ( From 2e8e8debcecf15d683ee35fec025c866fd28c5ed Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Fri, 23 Oct 2015 11:23:17 +0100 Subject: [PATCH 4/4] Fixed Django 1.8+ deprecation warning for Storage.get_available_name See https://docs.djangoproject.com/en/1.8/releases/1.8/#file-storage --- compressor/storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. """