From b4934d17e00aa88c508a901e912d56d60b6f39d8 Mon Sep 17 00:00:00 2001 From: Peter Belanyi Date: Mon, 17 Mar 2014 15:41:04 +0100 Subject: [PATCH] Patch Django 1.4 on Python 2.7.4 or greater This fix provides a patch for Django 1.4 to get rid of the issues with django.test.assertContains in the py27dj14 test environment. Change-Id: I4c7a225ef1095999f7c109e77c95e1a6fe04db8c Closes-Bug: #1273943 --- horizon/test/patches.py | 70 ++++++++++++++++++++++++++++++++++++++++ horizon/test/settings.py | 8 +++++ 2 files changed, 78 insertions(+) create mode 100644 horizon/test/patches.py diff --git a/horizon/test/patches.py b/horizon/test/patches.py new file mode 100644 index 0000000000..e827aea873 --- /dev/null +++ b/horizon/test/patches.py @@ -0,0 +1,70 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import HTMLParser as _HTMLParser +import re + + +def parse_starttag_patched(self, i): + """This method is a patched version of the parse_starttag method from + django.utils.html_parser.HTMLParser class, used to patch bug 1273943. + The code is taken from file django/utils/html_parser.py, commit 6bc1b22299. + """ + self.__starttag_text = None + endpos = self.check_for_whole_start_tag(i) + if endpos < 0: + return endpos + rawdata = self.rawdata + self.__starttag_text = rawdata[i:endpos] + + # Now parse the data between i+1 and j into a tag and attrs + attrs = [] + tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*') + match = tagfind.match(rawdata, i + 1) + assert match, 'unexpected call to parse_starttag()' + k = match.end() + self.lasttag = tag = match.group(1).lower() + + while k < endpos: + m = _HTMLParser.attrfind.match(rawdata, k) + if not m: + break + attrname, rest, attrvalue = m.group(1, 2, 3) + if not rest: + attrvalue = None + elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ + attrvalue[:1] == '"' == attrvalue[-1:]: + attrvalue = attrvalue[1:-1] + if attrvalue: + attrvalue = self.unescape(attrvalue) + attrs.append((attrname.lower(), attrvalue)) + k = m.end() + + end = rawdata[k:endpos].strip() + if end not in (">", "/>"): + lineno, offset = self.getpos() + if "\n" in self.__starttag_text: + lineno = lineno + self.__starttag_text.count("\n") + offset = len(self.__starttag_text) \ + - self.__starttag_text.rfind("\n") + else: + offset = offset + len(self.__starttag_text) + self.error("junk characters in start tag: %r" + % (rawdata[k:endpos][:20],)) + if end.endswith('/>'): + # XHTML-style empty tag: + self.handle_startendtag(tag, attrs) + else: + self.handle_starttag(tag, attrs) + if tag in self.CDATA_CONTENT_ELEMENTS: + self.set_cdata_mode(tag) # <--------------------------- Changed + return endpos diff --git a/horizon/test/settings.py b/horizon/test/settings.py index 1502b79dcd..391f6f536b 100644 --- a/horizon/test/settings.py +++ b/horizon/test/settings.py @@ -20,7 +20,15 @@ import os import socket +import sys +import django +from django.utils import html_parser +from horizon.test import patches + +# Patch django.utils.html_parser.HTMLParser as a workaround for bug 1273943 +if django.get_version() == '1.4' and sys.version_info[:3] > (2, 7, 3): + html_parser.HTMLParser.parse_starttag = patches.parse_starttag_patched socket.setdefaulttimeout(1)