[Python-modules-team] Bug#865053: python-django: python3.6 compatibility

Steve Langasek steve.langasek at canonical.com
Sun Jun 18 21:14:38 UTC 2017


Package: python-django
Version: 1:1.10.7-2
Severity: important
Tags: patch
User: ubuntu-devel at lists.ubuntu.com
Usertags: origin-ubuntu artful ubuntu-patch

Hi folks,

Upon merging the new version of python-django from Debian into Ubuntu, I
found that it failed to build because Ubuntu has started the python3.6
transition and django 1.10.7 is not compatible with python3.6.  It looks
like the only changes needed are to the tests, not to the runtime code.

Attached is a patch which cherry-picks the python3.6 compatibility commits
from upstream.  The patch is applied in Ubuntu; please consider applying it
in Debian as well (or fix the python3.6 compatibility some other way, such
as uploading a newer upstream release), since the python3.6 transition will
be starting in Debian soon.

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slangasek at ubuntu.com                                     vorlon at debian.org
-------------- next part --------------
diff -Nru python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-couple-timezone-tests-for-Python-.patch python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-couple-timezone-tests-for-Python-.patch
--- python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-couple-timezone-tests-for-Python-.patch	1969-12-31 16:00:00.000000000 -0800
+++ python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-couple-timezone-tests-for-Python-.patch	2017-06-17 23:33:25.000000000 -0700
@@ -0,0 +1,72 @@
+From a7a7ecd2b026c61a39a46d2d7eced0e06a92c970 Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Tue, 9 Aug 2016 18:14:15 -0400
+Subject: [PATCH] Refs #27025 -- Fixed a couple timezone tests for Python 3.6.
+
+Reflects behavior changes in PEP 495 (Local Time Disambiguation).
+---
+ tests/utils_tests/test_timezone.py | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py
+index 87df6b92eb..072e4b699d 100644
+--- a/tests/utils_tests/test_timezone.py
++++ b/tests/utils_tests/test_timezone.py
+@@ -1,9 +1,10 @@
+ import copy
+ import datetime
+ import pickle
++import sys
+ import unittest
+ 
+-from django.test import override_settings
++from django.test import SimpleTestCase, override_settings
+ from django.utils import timezone
+ 
+ try:
+@@ -18,8 +19,10 @@ if pytz is not None:
+ EAT = timezone.get_fixed_timezone(180)      # Africa/Nairobi
+ ICT = timezone.get_fixed_timezone(420)      # Asia/Bangkok
+ 
++PY36 = sys.version_info >= (3, 6)
+ 
+-class TimezoneTests(unittest.TestCase):
++
++class TimezoneTests(SimpleTestCase):
+ 
+     def test_localtime(self):
+         now = datetime.datetime.utcnow().replace(tzinfo=timezone.utc)
+@@ -28,8 +31,12 @@ class TimezoneTests(unittest.TestCase):
+         self.assertEqual(local_now.tzinfo, local_tz)
+ 
+     def test_localtime_naive(self):
+-        with self.assertRaises(ValueError):
+-            timezone.localtime(datetime.datetime.now())
++        now = datetime.datetime.now()
++        if PY36:
++            self.assertEqual(timezone.localtime(now), now.replace(tzinfo=timezone.LocalTimezone()))
++        else:
++            with self.assertRaisesMessage(ValueError, 'astimezone() cannot be applied to a naive datetime'):
++                timezone.localtime(now)
+ 
+     def test_localtime_out_of_range(self):
+         local_tz = timezone.LocalTimezone()
+@@ -136,8 +143,13 @@ class TimezoneTests(unittest.TestCase):
+         self.assertEqual(
+             timezone.make_naive(datetime.datetime(2011, 9, 1, 17, 20, 30, tzinfo=ICT), EAT),
+             datetime.datetime(2011, 9, 1, 13, 20, 30))
+-        with self.assertRaises(ValueError):
+-            timezone.make_naive(datetime.datetime(2011, 9, 1, 13, 20, 30), EAT)
++
++        args = (datetime.datetime(2011, 9, 1, 13, 20, 30), EAT)
++        if PY36:
++            self.assertEqual(timezone.make_naive(*args), datetime.datetime(2011, 9, 1, 21, 20, 30))
++        else:
++            with self.assertRaisesMessage(ValueError, 'astimezone() cannot be applied to a naive datetime'):
++                timezone.make_naive(*args)
+ 
+     @requires_pytz
+     def test_make_aware2(self):
+-- 
+2.11.0
+
diff -Nru python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-servers-test-on-Python-3.6.patch python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-servers-test-on-Python-3.6.patch
--- python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-servers-test-on-Python-3.6.patch	1969-12-31 16:00:00.000000000 -0800
+++ python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-servers-test-on-Python-3.6.patch	2017-06-17 23:33:25.000000000 -0700
@@ -0,0 +1,29 @@
+From 35225e2ade08ea32e36a994cd4ff90842c599e20 Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Mon, 8 Aug 2016 16:50:48 -0400
+Subject: [PATCH] Refs #27025 -- Fixed a servers test on Python 3.6.
+
+After https://hg.python.org/cpython/rev/4ea79767ff75/,
+test_strips_underscore_headers fails with:
+'Stub' object has no attribute 'sendall'.
+---
+ tests/servers/test_basehttp.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tests/servers/test_basehttp.py b/tests/servers/test_basehttp.py
+index 239016e635..cd9bcd2e86 100644
+--- a/tests/servers/test_basehttp.py
++++ b/tests/servers/test_basehttp.py
+@@ -12,6 +12,9 @@ class Stub(object):
+     def __init__(self, **kwargs):
+         self.__dict__.update(kwargs)
+ 
++    def sendall(self, data):
++        self.makefile('wb').write(data)
++
+ 
+ class WSGIRequestHandlerTestCase(SimpleTestCase):
+ 
+-- 
+2.11.0
+
diff -Nru python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-test-for-the-new-re.RegexFlag-in-.patch python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-test-for-the-new-re.RegexFlag-in-.patch
--- python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-test-for-the-new-re.RegexFlag-in-.patch	1969-12-31 16:00:00.000000000 -0800
+++ python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-test-for-the-new-re.RegexFlag-in-.patch	2017-06-17 23:26:47.000000000 -0700
@@ -0,0 +1,47 @@
+From 49412f55a5de7c3fa773e8a911439beb1568b901 Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Thu, 15 Sep 2016 12:12:26 -0400
+Subject: [PATCH] Refs #27025 -- Fixed a test for the new re.RegexFlag in
+ Python 3.6.
+
+http://bugs.python.org/issue28082
+---
+ tests/migrations/test_writer.py | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
+index 8febf40f03..ad77b51ae7 100644
+--- a/tests/migrations/test_writer.py
++++ b/tests/migrations/test_writer.py
+@@ -7,6 +7,7 @@ import functools
+ import math
+ import os
+ import re
++import sys
+ import tokenize
+ import unittest
+ 
+@@ -35,6 +36,8 @@ try:
+ except ImportError:
+     enum = None
+ 
++PY36 = sys.version_info >= (3, 6)
++
+ 
+ class Money(decimal.Decimal):
+     def deconstruct(self):
+@@ -412,7 +415,10 @@ class WriterTests(SimpleTestCase):
+         # Test a string regex with flag
+         validator = RegexValidator(r'^[0-9]+$', flags=re.U)
+         string = MigrationWriter.serialize(validator)[0]
+-        self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=32)")
++        if PY36:
++            self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=re.RegexFlag(32))")
++        else:
++            self.assertEqual(string, "django.core.validators.RegexValidator('^[0-9]+$', flags=32)")
+         self.serialize_round_trip(validator)
+ 
+         # Test message and code
+-- 
+2.11.0
+
diff -Nru python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-timezone-test-for-Python-3.6.patch python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-timezone-test-for-Python-3.6.patch
--- python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-timezone-test-for-Python-3.6.patch	1969-12-31 16:00:00.000000000 -0800
+++ python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-a-timezone-test-for-Python-3.6.patch	2017-06-17 23:28:34.000000000 -0700
@@ -0,0 +1,34 @@
+From e43ea36b7681e43ea99505a2cf7550d4d36016b3 Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Sat, 17 Sep 2016 12:12:52 -0400
+Subject: [PATCH] Refs #27025 -- Fixed a timezone test for Python 3.6.
+
+Reflects behavior changes in PEP 495 (Local Time Disambiguation).
+---
+ tests/utils_tests/test_timezone.py | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py
+index 9dc7941b4b..1be1d63b2c 100644
+--- a/tests/utils_tests/test_timezone.py
++++ b/tests/utils_tests/test_timezone.py
+@@ -193,8 +193,14 @@ class TimezoneTests(SimpleTestCase):
+                 pytz.timezone("Asia/Bangkok").localize(datetime.datetime(2011, 9, 1, 17, 20, 30)), CET
+             ),
+             datetime.datetime(2011, 9, 1, 12, 20, 30))
+-        with self.assertRaises(ValueError):
+-            timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET)
++        if PY36:
++            self.assertEqual(
++                timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET),
++                datetime.datetime(2011, 9, 1, 19, 20, 30)
++            )
++        else:
++            with self.assertRaises(ValueError):
++                timezone.make_naive(datetime.datetime(2011, 9, 1, 12, 20, 30), CET)
+ 
+     @requires_pytz
+     def test_make_aware_pytz_ambiguous(self):
+-- 
+2.11.0
+
diff -Nru python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-tests-for-the-new-ModuleNotFoundErr.patch python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-tests-for-the-new-ModuleNotFoundErr.patch
--- python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-tests-for-the-new-ModuleNotFoundErr.patch	1969-12-31 16:00:00.000000000 -0800
+++ python-django-1.10.7/debian/patches/0001-Refs-27025-Fixed-tests-for-the-new-ModuleNotFoundErr.patch	2017-06-17 23:24:02.000000000 -0700
@@ -0,0 +1,58 @@
+From 16202863facc8629a7422cf74cd3df30142d3aaf Mon Sep 17 00:00:00 2001
+From: Tim Graham <timograham at gmail.com>
+Date: Thu, 15 Sep 2016 11:54:22 -0400
+Subject: [PATCH] Refs #27025 -- Fixed tests for the new ModuleNotFoundError in
+ Python 3.6.
+
+http://bugs.python.org/issue15767
+---
+ tests/admin_scripts/tests.py         | 3 ++-
+ tests/view_tests/tests/test_debug.py | 4 +++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
+index 5ac24db6ea..567a8f14f8 100644
+--- a/tests/admin_scripts/tests.py
++++ b/tests/admin_scripts/tests.py
+@@ -34,6 +34,7 @@ from django.utils.six import PY2, PY3, StringIO
+ 
+ custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates')
+ 
++PY36 = sys.version_info >= (3, 6)
+ SYSTEM_CHECK_MSG = 'System check identified no issues'
+ 
+ 
+@@ -1166,7 +1167,7 @@ class ManageCheck(AdminScriptTestCase):
+         args = ['check']
+         out, err = self.run_manage(args)
+         self.assertNoOutput(out)
+-        self.assertOutput(err, 'ImportError')
++        self.assertOutput(err, 'ModuleNotFoundError' if PY36 else 'ImportError')
+         self.assertOutput(err, 'No module named')
+         self.assertOutput(err, 'admin_scriptz')
+ 
+diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
+index 7a450306f5..ba6e6defee 100644
+--- a/tests/view_tests/tests/test_debug.py
++++ b/tests/view_tests/tests/test_debug.py
+@@ -36,6 +36,8 @@ from ..views import (
+ if six.PY3:
+     from .py3_test_debug import Py3ExceptionReporterTests  # NOQA
+ 
++PY36 = sys.version_info >= (3, 6)
++
+ 
+ class User(object):
+     def __str__(self):
+@@ -430,7 +432,7 @@ class ExceptionReporterTests(SimpleTestCase):
+             exc_type, exc_value, tb = sys.exc_info()
+         reporter = ExceptionReporter(request, exc_type, exc_value, tb)
+         html = reporter.get_traceback_html()
+-        self.assertIn('<h1>ImportError at /test_view/</h1>', html)
++        self.assertIn('<h1>%sError at /test_view/</h1>' % 'ModuleNotFound' if PY36 else 'Import', html)
+ 
+     def test_ignore_traceback_evaluation_exceptions(self):
+         """
+-- 
+2.11.0
+
diff -Nru python-django-1.10.7/debian/patches/series python-django-1.10.7/debian/patches/series
--- python-django-1.10.7/debian/patches/series	2017-06-17 21:55:34.000000000 -0700
+++ python-django-1.10.7/debian/patches/series	2017-06-17 23:33:25.000000000 -0700
@@ -3,3 +3,8 @@
 fix-migration-fake-initial-1.patch
 fix-migration-fake-initial-2.patch
 fix-test-middleware-classes-headers.patch
+0001-Refs-27025-Fixed-tests-for-the-new-ModuleNotFoundErr.patch
+0001-Refs-27025-Fixed-a-test-for-the-new-re.RegexFlag-in-.patch
+0001-Refs-27025-Fixed-a-couple-timezone-tests-for-Python-.patch
+0001-Refs-27025-Fixed-a-timezone-test-for-Python-3.6.patch
+0001-Refs-27025-Fixed-a-servers-test-on-Python-3.6.patch


More information about the Python-modules-team mailing list