Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' into schema-alteration

  • Loading branch information...
commit 828d691f62814edf3e93d981c0f991a48781fb79 2 parents ca9c3cd + 5999eb4
Andrew Godwin authored September 07, 2012

Showing 59 changed files with 414 additions and 415 deletions. Show diff stats Hide diff stats

  1. 11  django/contrib/auth/tests/models.py
  2. 10  django/contrib/localflavor/hr/forms.py
  3. 22  django/contrib/localflavor/ro/forms.py
  4. 2  django/core/cache/backends/memcached.py
  5. 2  django/core/mail/backends/console.py
  6. 7  django/db/backends/creation.py
  7. 5  django/db/backends/sqlite3/base.py
  8. 12  django/db/models/sql/compiler.py
  9. 5  django/db/models/sql/query.py
  10. 36  django/forms/formsets.py
  11. 8  django/forms/widgets.py
  12. 5  django/http/multipartparser.py
  13. 2  django/test/testcases.py
  14. 7  django/utils/six.py
  15. 2  docs/intro/tutorial03.txt
  16. 26  docs/ref/contrib/gis/install.txt
  17. 5  docs/ref/forms/validation.txt
  18. 4  docs/ref/forms/widgets.txt
  19. 7  docs/ref/models/options.txt
  20. 3  docs/ref/models/querysets.txt
  21. 2  docs/releases/1.3.txt
  22. 4  docs/topics/db/queries.txt
  23. 18  docs/topics/python3.txt
  24. 32  docs/topics/security.txt
  25. 28  tests/modeltests/basic/tests.py
  26. 7  tests/modeltests/empty/tests.py
  27. 34  tests/modeltests/fixtures/tests.py
  28. 3  tests/modeltests/many_to_many/tests.py
  29. 2  tests/modeltests/many_to_one/tests.py
  30. 2  tests/modeltests/raw_query/tests.py
  31. 3  tests/modeltests/update_only_fields/tests.py
  32. 3  tests/modeltests/validation/test_error_messages.py
  33. 7  tests/regressiontests/admin_filters/tests.py
  34. 6  tests/regressiontests/admin_scripts/tests.py
  35. 2  tests/regressiontests/backends/tests.py
  36. 7  tests/regressiontests/cache/tests.py
  37. 2  tests/regressiontests/file_storage/tests.py
  38. 16  tests/regressiontests/file_uploads/tests.py
  39. 44  tests/regressiontests/fixtures_regress/tests.py
  40. 6  tests/regressiontests/forms/tests/fields.py
  41. 10  tests/regressiontests/forms/tests/widgets.py
  42. 4  tests/regressiontests/handlers/tests.py
  43. 9  tests/regressiontests/i18n/commands/compilation.py
  44. 4  tests/regressiontests/inline_formsets/tests.py
  45. 32  tests/regressiontests/localflavor/tr/tests.py
  46. 5  tests/regressiontests/m2m_regress/tests.py
  47. 5  tests/regressiontests/many_to_one_regress/tests.py
  48. 128  tests/regressiontests/modeladmin/tests.py
  49. 5  tests/regressiontests/queries/tests.py
  50. 22  tests/regressiontests/settings_tests/tests.py
  51. 70  tests/regressiontests/signals_regress/tests.py
  52. 2  tests/regressiontests/staticfiles_tests/tests.py
  53. 51  tests/regressiontests/templates/custom.py
  54. 12  tests/regressiontests/templates/loaders.py
  55. 6  tests/regressiontests/test_utils/tests.py
  56. 22  tests/regressiontests/transactions_regress/tests.py
  57. 8  tests/regressiontests/urlpatterns_reverse/tests.py
  58. 18  tests/regressiontests/utils/crypto.py
  59. 7  tests/regressiontests/wsgi/tests.py
11  django/contrib/auth/tests/models.py
... ...
@@ -1,8 +1,9 @@
1 1
 from django.conf import settings
  2
+from django.contrib.auth.models import (Group, User, SiteProfileNotAvailable,
  3
+    UserManager)
2 4
 from django.test import TestCase
3 5
 from django.test.utils import override_settings
4  
-from django.contrib.auth.models import (Group, User,
5  
-    SiteProfileNotAvailable, UserManager)
  6
+from django.utils import six
6 7
 
7 8
 
8 9
 @override_settings(USE_TZ=False, AUTH_PROFILE_MODULE='')
@@ -13,19 +14,19 @@ def test_site_profile_not_available(self):
13 14
 
14 15
         # calling get_profile without AUTH_PROFILE_MODULE set
15 16
         del settings.AUTH_PROFILE_MODULE
16  
-        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  17
+        with six.assertRaisesRegex(self, SiteProfileNotAvailable,
17 18
                 "You need to set AUTH_PROFILE_MODULE in your project"):
18 19
             user.get_profile()
19 20
 
20 21
         # Bad syntax in AUTH_PROFILE_MODULE:
21 22
         settings.AUTH_PROFILE_MODULE = 'foobar'
22  
-        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  23
+        with six.assertRaisesRegex(self, SiteProfileNotAvailable,
23 24
                 "app_label and model_name should be separated by a dot"):
24 25
             user.get_profile()
25 26
 
26 27
         # module that doesn't exist
27 28
         settings.AUTH_PROFILE_MODULE = 'foo.bar'
28  
-        with self.assertRaisesRegexp(SiteProfileNotAvailable,
  29
+        with six.assertRaisesRegex(self, SiteProfileNotAvailable,
29 30
                 "Unable to load the profile model"):
30 31
             user.get_profile()
31 32
 
10  django/contrib/localflavor/hr/forms.py
@@ -4,6 +4,7 @@
4 4
 """
5 5
 from __future__ import absolute_import, unicode_literals
6 6
 
  7
+import datetime
7 8
 import re
8 9
 
9 10
 from django.contrib.localflavor.hr.hr_choices import (
@@ -91,17 +92,16 @@ def clean(self, value):
91 92
         dd = int(matches.group('dd'))
92 93
         mm = int(matches.group('mm'))
93 94
         yyy = int(matches.group('yyy'))
94  
-        import datetime
95 95
         try:
96  
-            datetime.date(yyy,mm,dd)
97  
-        except:
  96
+            datetime.date(yyy, mm, dd)
  97
+        except ValueError:
98 98
             raise ValidationError(self.error_messages['date'])
99 99
 
100 100
         # Validate checksum.
101 101
         k = matches.group('k')
102 102
         checksum = 0
103  
-        for i,j in zip(range(7,1,-1),range(6)):
104  
-            checksum+=i*(int(value[j])+int(value[13-i]))
  103
+        for i, j in zip(range(7, 1, -1), range(6)):
  104
+            checksum += i * (int(value[j]) + int(value[13 - i]))
105 105
         m = 11 - checksum % 11
106 106
         if m == 10:
107 107
             raise ValidationError(self.error_messages['invalid'])
22  django/contrib/localflavor/ro/forms.py
@@ -4,6 +4,8 @@
4 4
 """
5 5
 from __future__ import absolute_import, unicode_literals
6 6
 
  7
+import datetime
  8
+
7 9
 from django.contrib.localflavor.ro.ro_counties import COUNTIES_CHOICES
8 10
 from django.core.validators import EMPTY_VALUES
9 11
 from django.forms import ValidationError, Field, RegexField, Select
@@ -69,10 +71,9 @@ def clean(self, value):
69 71
         if value in EMPTY_VALUES:
70 72
             return ''
71 73
         # check birthdate digits
72  
-        import datetime
73 74
         try:
74  
-            datetime.date(int(value[1:3]),int(value[3:5]),int(value[5:7]))
75  
-        except:
  75
+            datetime.date(int(value[1:3]), int(value[3:5]), int(value[5:7]))
  76
+        except ValueError:
76 77
             raise ValidationError(self.error_messages['invalid'])
77 78
         # checksum
78 79
         key = '279146358279'
@@ -118,7 +119,7 @@ def clean(self, value):
118 119
         # search for county name
119 120
         normalized_CC = []
120 121
         for entry in COUNTIES_CHOICES:
121  
-            normalized_CC.append((entry[0],entry[1].upper()))
  122
+            normalized_CC.append((entry[0], entry[1].upper()))
122 123
         for entry in normalized_CC:
123 124
             if entry[1] == value:
124 125
                 return entry[0]
@@ -153,8 +154,8 @@ def clean(self, value):
153 154
         value = super(ROIBANField, self).clean(value)
154 155
         if value in EMPTY_VALUES:
155 156
             return ''
156  
-        value = value.replace('-','')
157  
-        value = value.replace(' ','')
  157
+        value = value.replace('-', '')
  158
+        value = value.replace(' ', '')
158 159
         value = value.upper()
159 160
         if value[0:2] != 'RO':
160 161
             raise ValidationError(self.error_messages['invalid'])
@@ -185,10 +186,10 @@ def clean(self, value):
185 186
         value = super(ROPhoneNumberField, self).clean(value)
186 187
         if value in EMPTY_VALUES:
187 188
             return ''
188  
-        value = value.replace('-','')
189  
-        value = value.replace('(','')
190  
-        value = value.replace(')','')
191  
-        value = value.replace(' ','')
  189
+        value = value.replace('-', '')
  190
+        value = value.replace('(', '')
  191
+        value = value.replace(')', '')
  192
+        value = value.replace(' ', '')
192 193
         if len(value) != 10:
193 194
             raise ValidationError(self.error_messages['invalid'])
194 195
         return value
@@ -202,4 +203,3 @@ class ROPostalCodeField(RegexField):
202 203
     def __init__(self, max_length=6, min_length=6, *args, **kwargs):
203 204
         super(ROPostalCodeField, self).__init__(r'^[0-9][0-8][0-9]{4}$',
204 205
                 max_length, min_length, *args, **kwargs)
205  
-
2  django/core/cache/backends/memcached.py
@@ -141,7 +141,7 @@ def __init__(self, server, params):
141 141
         )
142 142
         try:
143 143
             import memcache
144  
-        except:
  144
+        except ImportError:
145 145
             raise InvalidCacheBackendError(
146 146
                 "Memcached cache backend requires either the 'memcache' or 'cmemcache' library"
147 147
                 )
2  django/core/mail/backends/console.py
@@ -21,7 +21,7 @@ def send_messages(self, email_messages):
21 21
                 stream_created = self.open()
22 22
                 for message in email_messages:
23 23
                     self.stream.write('%s\n' % message.message().as_string())
24  
-                    self.stream.write('-'*79)
  24
+                    self.stream.write('-' * 79)
25 25
                     self.stream.write('\n')
26 26
                     self.stream.flush()  # flush after each message
27 27
                 if stream_created:
7  django/db/backends/creation.py
... ...
@@ -1,8 +1,10 @@
  1
+import hashlib
1 2
 import sys
2 3
 import time
3 4
 
4 5
 from django.conf import settings
5 6
 from django.db.utils import load_backend
  7
+from django.utils.encoding import force_bytes
6 8
 from django.utils.six.moves import input
7 9
 
8 10
 # The prefix to put on the default database name when creating
@@ -29,7 +31,10 @@ def _digest(cls, *args):
29 31
         Generates a 32-bit digest of a set of arguments that can be used to
30 32
         shorten identifying names.
31 33
         """
32  
-        return '%x' % (abs(hash(args)) % 4294967296)    # 2**32
  34
+        h = hashlib.md5()
  35
+        for arg in args:
  36
+            h.update(force_bytes(arg))
  37
+        return h.hexdigest()[:8]
33 38
 
34 39
     def sql_create_model(self, model, style, known_models=set()):
35 40
         """
5  django/db/backends/sqlite3/base.py
@@ -419,7 +419,4 @@ def _sqlite_format_dtdelta(dt, conn, days, secs, usecs):
419 419
     return str(dt)
420 420
 
421 421
 def _sqlite_regexp(re_pattern, re_string):
422  
-    try:
423  
-        return bool(re.search(re_pattern, re_string))
424  
-    except:
425  
-        return False
  422
+    return bool(re.search(re_pattern, re_string))
12  django/db/models/sql/compiler.py
@@ -4,7 +4,8 @@
4 4
 from django.db import transaction
5 5
 from django.db.backends.util import truncate_name
6 6
 from django.db.models.query_utils import select_related_descend
7  
-from django.db.models.sql.constants import *
  7
+from django.db.models.sql.constants import (SINGLE, MULTI, ORDER_DIR,
  8
+    LOOKUP_SEP, GET_ITERATOR_CHUNK_SIZE)
8 9
 from django.db.models.sql.datastructures import EmptyResultSet
9 10
 from django.db.models.sql.expressions import SQLEvaluator
10 11
 from django.db.models.sql.query import get_order_dir, Query
@@ -811,7 +812,7 @@ def execute_sql(self, result_type=MULTI):
811 812
                 raise EmptyResultSet
812 813
         except EmptyResultSet:
813 814
             if result_type == MULTI:
814  
-                return empty_iter()
  815
+                return iter([])
815 816
             else:
816 817
                 return
817 818
 
@@ -1088,13 +1089,6 @@ def results_iter(self):
1088 1089
                 yield date
1089 1090
 
1090 1091
 
1091  
-def empty_iter():
1092  
-    """
1093  
-    Returns an iterator containing no results.
1094  
-    """
1095  
-    yield next(iter([]))
1096  
-
1097  
-
1098 1092
 def order_modified_iter(cursor, trim, sentinel):
1099 1093
     """
1100 1094
     Yields blocks of rows from a cursor. We use this iterator in the special
5  django/db/models/sql/query.py
@@ -17,9 +17,9 @@
17 17
 from django.db.models import signals
18 18
 from django.db.models.expressions import ExpressionNode
19 19
 from django.db.models.fields import FieldDoesNotExist
20  
-from django.db.models.query_utils import InvalidQuery
21 20
 from django.db.models.sql import aggregates as base_aggregates_module
22  
-from django.db.models.sql.constants import *
  21
+from django.db.models.sql.constants import (QUERY_TERMS, LOOKUP_SEP, ORDER_DIR,
  22
+    SINGLE, ORDER_PATTERN, JoinInfo)
23 23
 from django.db.models.sql.datastructures import EmptyResultSet, Empty, MultiJoin
24 24
 from django.db.models.sql.expressions import SQLEvaluator
25 25
 from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
@@ -28,6 +28,7 @@
28 28
 
29 29
 __all__ = ['Query', 'RawQuery']
30 30
 
  31
+
31 32
 class RawQuery(object):
32 33
     """
33 34
     A single raw SQL query
36  django/forms/formsets.py
@@ -71,7 +71,8 @@ def __bool__(self):
71 71
         return True
72 72
     __nonzero__ = __bool__ # Python 2
73 73
 
74  
-    def _management_form(self):
  74
+    @property
  75
+    def management_form(self):
75 76
         """Returns the ManagementForm instance for this FormSet."""
76 77
         if self.is_bound:
77 78
             form = ManagementForm(self.data, auto_id=self.auto_id, prefix=self.prefix)
@@ -84,7 +85,6 @@ def _management_form(self):
84 85
                 MAX_NUM_FORM_COUNT: self.max_num
85 86
             })
86 87
         return form
87  
-    management_form = property(_management_form)
88 88
 
89 89
     def total_form_count(self):
90 90
         """Returns the total number of forms in this FormSet."""
@@ -140,17 +140,18 @@ def _construct_form(self, i, **kwargs):
140 140
         self.add_fields(form, i)
141 141
         return form
142 142
 
143  
-    def _get_initial_forms(self):
  143
+    @property
  144
+    def initial_forms(self):
144 145
         """Return a list of all the initial forms in this formset."""
145 146
         return self.forms[:self.initial_form_count()]
146  
-    initial_forms = property(_get_initial_forms)
147 147
 
148  
-    def _get_extra_forms(self):
  148
+    @property
  149
+    def extra_forms(self):
149 150
         """Return a list of all the extra forms in this formset."""
150 151
         return self.forms[self.initial_form_count():]
151  
-    extra_forms = property(_get_extra_forms)
152 152
 
153  
-    def _get_empty_form(self, **kwargs):
  153
+    @property
  154
+    def empty_form(self, **kwargs):
154 155
         defaults = {
155 156
             'auto_id': self.auto_id,
156 157
             'prefix': self.add_prefix('__prefix__'),
@@ -160,19 +161,19 @@ def _get_empty_form(self, **kwargs):
160 161
         form = self.form(**defaults)
161 162
         self.add_fields(form, None)
162 163
         return form
163  
-    empty_form = property(_get_empty_form)
164 164
 
165 165
     # Maybe this should just go away?
166  
-    def _get_cleaned_data(self):
  166
+    @property
  167
+    def cleaned_data(self):
167 168
         """
168 169
         Returns a list of form.cleaned_data dicts for every form in self.forms.
169 170
         """
170 171
         if not self.is_valid():
171 172
             raise AttributeError("'%s' object has no attribute 'cleaned_data'" % self.__class__.__name__)
172 173
         return [form.cleaned_data for form in self.forms]
173  
-    cleaned_data = property(_get_cleaned_data)
174 174
 
175  
-    def _get_deleted_forms(self):
  175
+    @property
  176
+    def deleted_forms(self):
176 177
         """
177 178
         Returns a list of forms that have been marked for deletion. Raises an
178 179
         AttributeError if deletion is not allowed.
@@ -191,9 +192,9 @@ def _get_deleted_forms(self):
191 192
                 if self._should_delete_form(form):
192 193
                     self._deleted_form_indexes.append(i)
193 194
         return [self.forms[i] for i in self._deleted_form_indexes]
194  
-    deleted_forms = property(_get_deleted_forms)
195 195
 
196  
-    def _get_ordered_forms(self):
  196
+    @property
  197
+    def ordered_forms(self):
197 198
         """
198 199
         Returns a list of form in the order specified by the incoming data.
199 200
         Raises an AttributeError if ordering is not allowed.
@@ -228,7 +229,6 @@ def compare_ordering_key(k):
228 229
         # Return a list of form.cleaned_data dicts in the order specified by
229 230
         # the form data.
230 231
         return [self.forms[i[0]] for i in self._ordering]
231  
-    ordered_forms = property(_get_ordered_forms)
232 232
 
233 233
     @classmethod
234 234
     def get_default_prefix(cls):
@@ -244,14 +244,14 @@ def non_form_errors(self):
244 244
             return self._non_form_errors
245 245
         return self.error_class()
246 246
 
247  
-    def _get_errors(self):
  247
+    @property
  248
+    def errors(self):
248 249
         """
249 250
         Returns a list of form.errors for every form in self.forms.
250 251
         """
251 252
         if self._errors is None:
252 253
             self.full_clean()
253 254
         return self._errors
254  
-    errors = property(_get_errors)
255 255
 
256 256
     def _should_delete_form(self, form):
257 257
         """
@@ -332,14 +332,14 @@ def is_multipart(self):
332 332
         """
333 333
         return self.forms and self.forms[0].is_multipart()
334 334
 
335  
-    def _get_media(self):
  335
+    @property
  336
+    def media(self):
336 337
         # All the forms on a FormSet are the same, so you only need to
337 338
         # interrogate the first form for media.
338 339
         if self.forms:
339 340
             return self.forms[0].media
340 341
         else:
341 342
             return Media()
342  
-    media = property(_get_media)
343 343
 
344 344
     def as_table(self):
345 345
         "Returns this formset rendered as HTML <tr>s -- excluding the <table></table>."
8  django/forms/widgets.py
@@ -507,11 +507,7 @@ def __init__(self, attrs=None, check_test=None):
507 507
 
508 508
     def render(self, name, value, attrs=None):
509 509
         final_attrs = self.build_attrs(attrs, type='checkbox', name=name)
510  
-        try:
511  
-            result = self.check_test(value)
512  
-        except: # Silently catch exceptions
513  
-            result = False
514  
-        if result:
  510
+        if self.check_test(value):
515 511
             final_attrs['checked'] = 'checked'
516 512
         if not (value is True or value is False or value is None or value == ''):
517 513
             # Only add the 'value' attribute if a value is non-empty.
@@ -525,7 +521,7 @@ def value_from_datadict(self, data, files, name):
525 521
             return False
526 522
         value = data.get(name)
527 523
         # Translate true and false strings to boolean values.
528  
-        values =  {'true': True, 'false': False}
  524
+        values = {'true': True, 'false': False}
529 525
         if isinstance(value, six.string_types):
530 526
             value = values.get(value.lower(), value)
531 527
         return value
5  django/http/multipartparser.py
@@ -68,11 +68,10 @@ def __init__(self, META, input_data, upload_handlers, encoding=None):
68 68
         if not boundary or not cgi.valid_boundary(boundary):
69 69
             raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)
70 70
 
71  
-
72 71
         # Content-Length should contain the length of the body we are about
73 72
         # to receive.
74 73
         try:
75  
-            content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH',0)))
  74
+            content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH', 0)))
76 75
         except (ValueError, TypeError):
77 76
             content_length = 0
78 77
 
@@ -178,7 +177,7 @@ def parse(self):
178 177
 
179 178
                     content_type = meta_data.get('content-type', ('',))[0].strip()
180 179
                     try:
181  
-                        charset = meta_data.get('content-type', (0,{}))[1].get('charset', None)
  180
+                        charset = meta_data.get('content-type', (0, {}))[1].get('charset', None)
182 181
                     except:
183 182
                         charset = None
184 183
 
2  django/test/testcases.py
@@ -358,7 +358,7 @@ def assertRaisesMessage(self, expected_exception, expected_message,
358 358
             args: Extra args.
359 359
             kwargs: Extra kwargs.
360 360
         """
361  
-        return self.assertRaisesRegexp(expected_exception,
  361
+        return six.assertRaisesRegex(self, expected_exception,
362 362
                 re.escape(expected_message), callable_obj, *args, **kwargs)
363 363
 
364 364
     def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None,
7  django/utils/six.py
@@ -370,13 +370,20 @@ def with_metaclass(meta, base=object):
370 370
 
371 371
 if PY3:
372 372
     _iterlists = "lists"
  373
+    _assertRaisesRegex = "assertRaisesRegex"
373 374
 else:
374 375
     _iterlists = "iterlists"
  376
+    _assertRaisesRegex = "assertRaisesRegexp"
  377
+
375 378
 
376 379
 def iterlists(d):
377 380
     """Return an iterator over the values of a MultiValueDict."""
378 381
     return getattr(d, _iterlists)()
379 382
 
380 383
 
  384
+def assertRaisesRegex(self, *args, **kwargs):
  385
+    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
  386
+
  387
+
381 388
 add_move(MovedModule("_dummy_thread", "dummy_thread"))
382 389
 add_move(MovedModule("_thread", "thread"))
2  docs/intro/tutorial03.txt
@@ -517,7 +517,7 @@ URLconf by removing the leading "polls/" from each line, and removing the
517 517
 lines registering the admin site. Your ``polls/urls.py`` file should now look like
518 518
 this::
519 519
 
520  
-    from django.conf.urls import patterns, include, url
  520
+    from django.conf.urls import patterns, url
521 521
 
522 522
     urlpatterns = patterns('polls.views',
523 523
         url(r'^$', 'index'),
26  docs/ref/contrib/gis/install.txt
@@ -80,7 +80,7 @@ geospatial libraries:
80 80
 Program                   Description                           Required                          Supported Versions
81 81
 ========================  ====================================  ================================  ==========================
82 82
 :ref:`GEOS <ref-geos>`    Geometry Engine Open Source           Yes                               3.3, 3.2, 3.1, 3.0
83  
-`PROJ.4`_                 Cartographic Projections library      Yes (PostgreSQL and SQLite only)  4.7, 4.6, 4.5, 4.4
  83
+`PROJ.4`_                 Cartographic Projections library      Yes (PostgreSQL and SQLite only)  4.8, 4.7, 4.6, 4.5, 4.4
84 84
 :ref:`GDAL <ref-gdal>`    Geospatial Data Abstraction Library   No (but, required for SQLite)     1.9, 1.8, 1.7, 1.6, 1.5
85 85
 :ref:`GeoIP <ref-geoip>`  IP-based geolocation library          No                                1.4
86 86
 `PostGIS`__               Spatial extensions for PostgreSQL     Yes (PostgreSQL only)             1.5, 1.4, 1.3
@@ -140,16 +140,16 @@ internal geometry representation used by GeoDjango (it's behind the "lazy"
140 140
 geometries).  Specifically, the C API library is called (e.g., ``libgeos_c.so``)
141 141
 directly from Python using ctypes.
142 142
 
143  
-First, download GEOS 3.3.0 from the refractions Web site and untar the source
  143
+First, download GEOS 3.3.5 from the refractions Web site and untar the source
144 144
 archive::
145 145
 
146  
-    $ wget http://download.osgeo.org/geos/geos-3.3.0.tar.bz2
147  
-    $ tar xjf geos-3.3.0.tar.bz2
  146
+    $ wget http://download.osgeo.org/geos/geos-3.3.5.tar.bz2
  147
+    $ tar xjf geos-3.3.5.tar.bz2
148 148
 
149 149
 Next, change into the directory where GEOS was unpacked, run the configure
150 150
 script, compile, and install::
151 151
 
152  
-    $ cd geos-3.3.0
  152
+    $ cd geos-3.3.5
153 153
     $ ./configure
154 154
     $ make
155 155
     $ sudo make install
@@ -203,15 +203,15 @@ reference systems.
203 203
 
204 204
 First, download the PROJ.4 source code and datum shifting files [#]_::
205 205
 
206  
-    $ wget http://download.osgeo.org/proj/proj-4.7.0.tar.gz
207  
-    $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.zip
  206
+    $ wget http://download.osgeo.org/proj/proj-4.8.0.tar.gz
  207
+    $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.tar.gz
208 208
 
209 209
 Next, untar the source code archive, and extract the datum shifting files in the
210 210
 ``nad`` subdirectory.  This must be done *prior* to configuration::
211 211
 
212  
-    $ tar xzf proj-4.7.0.tar.gz
213  
-    $ cd proj-4.7.0/nad
214  
-    $ unzip ../../proj-datumgrid-1.5.zip
  212
+    $ tar xzf proj-4.8.0.tar.gz
  213
+    $ cd proj-4.8.0/nad
  214
+    $ tar xzf ../../proj-datumgrid-1.5.tar.gz
215 215
     $ cd ..
216 216
 
217 217
 Finally, configure, make and install PROJ.4::
@@ -239,9 +239,9 @@ installed prior to building PostGIS.
239 239
 
240 240
 First download the source archive, and extract::
241 241
 
242  
-    $ wget http://postgis.refractions.net/download/postgis-1.5.2.tar.gz
243  
-    $ tar xzf postgis-1.5.2.tar.gz
244  
-    $ cd postgis-1.5.2
  242
+    $ wget http://postgis.refractions.net/download/postgis-1.5.5.tar.gz
  243
+    $ tar xzf postgis-1.5.5.tar.gz
  244
+    $ cd postgis-1.5.5
245 245
 
246 246
 Next, configure, make and install PostGIS::
247 247
 
5  docs/ref/forms/validation.txt
@@ -70,9 +70,8 @@ overridden:
70 70
   formfield-specific piece of validation and, possibly,
71 71
   cleaning/normalizing the data.
72 72
 
73  
-  Just like the general field ``clean()`` method, above, this method
74  
-  should return the cleaned data, regardless of whether it changed
75  
-  anything or not.
  73
+  This method should return the cleaned value obtained from cleaned_data,
  74
+  regardless of whether it changed anything or not.
76 75
 
77 76
 * The Form subclass's ``clean()`` method. This method can perform
78 77
   any validation that requires access to multiple fields from the form at
4  docs/ref/forms/widgets.txt
@@ -310,6 +310,10 @@ commonly used groups of widgets:
310 310
         A callable that takes the value of the CheckBoxInput and returns
311 311
         ``True`` if the checkbox should be checked for that value.
312 312
 
  313
+        .. versionchanged:: 1.5
  314
+            Exceptions from ``check_test`` used to be silenced by its caller,
  315
+            this is no longer the case, they will propagate upwards.
  316
+
313 317
 ``Select``
314 318
 ~~~~~~~~~~
315 319
 
7  docs/ref/models/options.txt
@@ -83,9 +83,10 @@ Django quotes column and table names behind the scenes.
83 83
 
84 84
 .. attribute:: Options.get_latest_by
85 85
 
86  
-    The name of a :class:`DateField` or :class:`DateTimeField` in the model.
87  
-    This specifies the default field to use in your model :class:`Manager`'s
88  
-    :class:`~QuerySet.latest` method.
  86
+    The name of an orderable field in the model, typically a :class:`DateField`,
  87
+    :class:`DateTimeField`, or :class:`IntegerField`. This specifies the default
  88
+    field to use in your model :class:`Manager`'s :class:`~QuerySet.latest`
  89
+    method.
89 90
 
90 91
     Example::
91 92
 
3  docs/ref/models/querysets.txt
@@ -2064,7 +2064,7 @@ Note this is only available in MySQL and requires direct manipulation of the
2064 2064
 database to add the full-text index. By default Django uses BOOLEAN MODE for
2065 2065
 full text searches. See the `MySQL documentation`_ for additional details.
2066 2066
 
2067  
-.. _MySQL documentation: http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html>
  2067
+.. _MySQL documentation: http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html
2068 2068
 
2069 2069
 
2070 2070
 .. fieldlookup:: regex
@@ -2236,4 +2236,3 @@ Variance
2236 2236
         extension.
2237 2237
 
2238 2238
 .. _SQLite documentation: http://www.sqlite.org/contrib
2239  
-
2  docs/releases/1.3.txt
@@ -587,7 +587,7 @@ gettext domain):
587 587
   ones listed later.
588 588
 
589 589
 * The ``locale`` subdirectory of the directory containing the settings, that
590  
-  usually coincides with and is know as the *project directory* is being
  590
+  usually coincides with and is known as the *project directory* is being
591 591
   deprecated in this release as a source of translations. (the precedence of
592 592
   these translations is intermediate between applications and :setting:`LOCALE_PATHS`
593 593
   translations). See the `corresponding deprecated features section`_
4  docs/topics/db/queries.txt
@@ -235,14 +235,14 @@ refinements together. For example::
235 235
     ... ).exclude(
236 236
     ...     pub_date__gte=datetime.now()
237 237
     ... ).filter(
238  
-    ...     pub_date__gte=datetime(2005, 1, 1)
  238
+    ...     pub_date__gte=datetime(2005, 1, 30)
239 239
     ... )
240 240
 
241 241
 This takes the initial :class:`~django.db.models.query.QuerySet` of all entries
242 242
 in the database, adds a filter, then an exclusion, then another filter. The
243 243
 final result is a :class:`~django.db.models.query.QuerySet` containing all
244 244
 entries with a headline that starts with "What", that were published between
245  
-January 1, 2005, and the current day.
  245
+January 30, 2005, and the current day.
246 246
 
247 247
 .. _filtered-querysets-are-unique:
248 248
 
18  docs/topics/python3.txt
@@ -25,10 +25,11 @@ free to chose another strategy for your own code, especially if you don't need
25 25
 to stay compatible with Python 2. But authors of pluggable applications are
26 26
 encouraged to use the same porting strategy as Django itself.
27 27
 
28  
-Writing compatible code is much easier if you target Python ≥ 2.6. You will
29  
-most likely take advantage of the compatibility functions introduced in Django
30  
-1.5, like :mod:`django.utils.six`, so your application will also require
31  
-Django ≥ 1.5.
  28
+Writing compatible code is much easier if you target Python ≥ 2.6. Django 1.5
  29
+introduces compatibility tools such as :mod:`django.utils.six`. For
  30
+convenience, forwards-compatible aliases were introduced in Django 1.4.2. If
  31
+your application takes advantage of these tools, it will require Django ≥
  32
+1.4.2.
32 33
 
33 34
 Obviously, writing compatible source code adds some overhead, and that can
34 35
 cause frustration. Django's developers have found that attempting to write
@@ -102,6 +103,8 @@ Old name            New name
102 103
 For backwards compatibility, the old names still work on Python 2. Under
103 104
 Python 3, ``smart_str`` is an alias for ``smart_text``.
104 105
 
  106
+For forwards compatibility, the new names work as of Django 1.4.2.
  107
+
105 108
 .. note::
106 109
 
107 110
     :mod:`django.utils.encoding` was deeply refactored in Django 1.5 to
@@ -126,6 +129,8 @@ For backwards compatibility, the old names still work on Python 2. Under
126 129
 Python 3, ``EscapeString`` and ``SafeString`` are aliases for ``EscapeText``
127 130
 and ``SafeText`` respectively.
128 131
 
  132
+For forwards compatibility, the new names work as of Django 1.4.2.
  133
+
129 134
 :meth:`__str__` and :meth:`__unicode__` methods
130 135
 -----------------------------------------------
131 136
 
@@ -166,6 +171,8 @@ On Python 3, the decorator is a no-op. On Python 2, it defines appropriate
166 171
 
167 172
 This technique is the best match for Django's porting philosophy.
168 173
 
  174
+For forwards compatibility, this decorator is available as of Django 1.4.2.
  175
+
169 176
 Finally, note that :meth:`__repr__` must return a :class:`str` on all versions
170 177
 of Python.
171 178
 
@@ -317,7 +324,8 @@ Writing compatible code with six
317 324
 six_ is the canonical compatibility library for supporting Python 2 and 3 in
318 325
 a single codebase. Read its documentation!
319 326
 
320  
-:mod:`six` is bundled with Django: you can import it as :mod:`django.utils.six`.
  327
+:mod`six` is bundled with Django as of version 1.4.2. You can import it as
  328
+:mod`django.utils.six`.
321 329
 
322 330
 Here are the most common changes required to write compatible code.
323 331
 
32  docs/topics/security.txt
@@ -76,9 +76,17 @@ POST to your Web site and have another logged in user unwittingly submit that
76 76
 form. The malicious user would have to know the nonce, which is user specific
77 77
 (using a cookie).
78 78
 
  79
+When deployed with :ref:`HTTPS <security-recommendation-ssl>`, 
  80
+``CsrfViewMiddleware`` will check that the HTTP referer header is set to a 
  81
+URL on the same origin (including subdomain and port). Because HTTPS
  82
+provides additional security, it is imperative to ensure connections use HTTPS
  83
+where it is available by forwarding insecure connection requests and using
  84
+HSTS for supported browsers.
  85
+
79 86
 Be very careful with marking views with the ``csrf_exempt`` decorator unless
80 87
 it is absolutely necessary.
81 88
 
  89
+
82 90
 SQL injection protection
83 91
 ========================
84 92
 
@@ -112,6 +120,8 @@ The middleware is strongly recommended for any site that does not need to have
112 120
 its pages wrapped in a frame by third party sites, or only needs to allow that
113 121
 for a small section of the site.
114 122
 
  123
+.. _security-recommendation-ssl:
  124
+
115 125
 SSL/HTTPS
116 126
 =========
117 127
 
@@ -147,7 +157,15 @@ server, there are some additional steps you may need:
147 157
   any POST data being accepted over HTTP (which will be fine if you are
148 158
   redirecting all HTTP traffic to HTTPS).
149 159
 
150  
-.. _additional-security-topics:
  160
+* Use HTTP Strict Transport Security (HSTS)
  161
+
  162
+  HSTS is an HTTP header that informs a browser that all future connections
  163
+  to a particular site should always use HTTPS. Combined with redirecting
  164
+  requests over HTTP to HTTPS, this will ensure that connections always enjoy
  165
+  the added security of SSL provided one successful connection has occurred.
  166
+  HSTS is usually configured on the web server.
  167
+
  168
+.. _host-headers-virtual-hosting:
151 169
 
152 170
 Host headers and virtual hosting
153 171
 ================================
@@ -158,15 +176,17 @@ Site Scripting attacks, they can be used for Cross-Site Request
158 176
 Forgery and cache poisoning attacks in some circumstances. We
159 177
 recommend you ensure your Web server is configured such that:
160 178
 
161  
-    * It always validates incoming HTTP ``Host`` headers against the expected
162  
-      host name.
163  
-    * Disallows requests with no ``Host`` header.
164  
-    * Is *not* configured with a catch-all virtual host that forwards requests
165  
-      to a Django application.
  179
+* It always validates incoming HTTP ``Host`` headers against the expected
  180
+  host name.
  181
+* Disallows requests with no ``Host`` header.
  182
+* Is *not* configured with a catch-all virtual host that forwards requests
  183
+  to a Django application.
166 184
 
167 185
 Additionally, as of 1.3.1, Django requires you to explicitly enable support for
168 186
 the ``X-Forwarded-Host`` header if your configuration requires it.
169 187
 
  188
+.. _additional-security-topics:
  189
+
170 190
 Additional security topics
171 191
 ==========================
172 192
 
28  tests/modeltests/basic/tests.py
@@ -5,7 +5,7 @@
5 5
 from django.core.exceptions import ObjectDoesNotExist
6 6
 from django.db.models.fields import Field, FieldDoesNotExist
7 7
 from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
8  
-from django.utils.six import PY3
  8
+from django.utils import six
9 9
 from django.utils.translation import ugettext_lazy
10 10
 
11 11
 from .models import Article
@@ -82,7 +82,7 @@ def test_lookup(self):
82 82
 
83 83
         # Django raises an Article.DoesNotExist exception for get() if the
84 84
         # parameters don't match any object.
85  
-        self.assertRaisesRegexp(
  85
+        six.assertRaisesRegex(self,
86 86
             ObjectDoesNotExist,
87 87
             "Article matching query does not exist. Lookup parameters were "
88 88
             "{'id__exact': 2000}",
@@ -91,14 +91,14 @@ def test_lookup(self):
91 91
         )
92 92
         # To avoid dict-ordering related errors check only one lookup
93 93
         # in single assert.
94  
-        self.assertRaisesRegexp(
  94
+        six.assertRaisesRegex(self,
95 95
             ObjectDoesNotExist,
96 96
             ".*'pub_date__year': 2005.*",
97 97
             Article.objects.get,
98 98
             pub_date__year=2005,
99 99
             pub_date__month=8,
100 100
         )
101  
-        self.assertRaisesRegexp(
  101
+        six.assertRaisesRegex(self,
102 102
             ObjectDoesNotExist,
103 103
             ".*'pub_date__month': 8.*",
104 104
             Article.objects.get,
@@ -106,7 +106,7 @@ def test_lookup(self):
106 106
             pub_date__month=8,
107 107
         )
108 108
 
109  
-        self.assertRaisesRegexp(
  109
+        six.assertRaisesRegex(self,
110 110
             ObjectDoesNotExist,
111 111
             "Article matching query does not exist. Lookup parameters were "
112 112
             "{'pub_date__week_day': 6}",
@@ -168,7 +168,7 @@ def test_object_creation(self):
168 168
         self.assertEqual(a4.headline, 'Fourth article')
169 169
 
170 170
         # Don't use invalid keyword arguments.
171  
-        self.assertRaisesRegexp(
  171
+        six.assertRaisesRegex(self,
172 172
             TypeError,
173 173
             "'foo' is an invalid keyword argument for this function",
174 174
             Article,
@@ -259,13 +259,13 @@ def test_object_creation(self):
259 259
              "datetime.datetime(2005, 7, 28, 0, 0)"])
260 260
 
261 261
         # dates() requires valid arguments.
262  
-        self.assertRaisesRegexp(
  262
+        six.assertRaisesRegex(self,
263 263
             TypeError,
264 264
             "dates\(\) takes at least 3 arguments \(1 given\)",
265 265
             Article.objects.dates,
266 266
         )
267 267
 
268  
-        self.assertRaisesRegexp(
  268
+        six.assertRaisesRegex(self,
269 269
             FieldDoesNotExist,
270 270
             "Article has no field named 'invalid_field'",
271 271
             Article.objects.dates,
@@ -273,7 +273,7 @@ def test_object_creation(self):
273 273
             "year",
274 274
         )
275 275
 
276  
-        self.assertRaisesRegexp(
  276
+        six.assertRaisesRegex(self,
277 277
             AssertionError,
278 278
             "'kind' must be one of 'year', 'month' or 'day'.",
279 279
             Article.objects.dates,
@@ -281,7 +281,7 @@ def test_object_creation(self):
281 281
             "bad_kind",
282 282
         )
283 283
 
284  
-        self.assertRaisesRegexp(
  284
+        six.assertRaisesRegex(self,
285 285
             AssertionError,
286 286
             "'order' must be either 'ASC' or 'DESC'.",
287 287
             Article.objects.dates,
@@ -323,7 +323,7 @@ def test_object_creation(self):
323 323
              "<Article: Third article>"])
324 324
 
325 325
         # Slicing works with longs (Python 2 only -- Python 3 doesn't have longs).
326  
-        if not PY3:
  326
+        if not six.PY3:
327 327
             self.assertEqual(Article.objects.all()[long(0)], a)
328 328
             self.assertQuerysetEqual(Article.objects.all()[long(1):long(3)],
329 329
                 ["<Article: Second article>", "<Article: Third article>"])
@@ -369,14 +369,14 @@ def test_object_creation(self):
369 369
              "<Article: Updated article 8>"])
370 370
 
371 371
         # Also, once you have sliced you can't filter, re-order or combine
372  
-        self.assertRaisesRegexp(
  372
+        six.assertRaisesRegex(self,
373 373
             AssertionError,
374 374
             "Cannot filter a query once a slice has been taken.",
375 375
             Article.objects.all()[0:5].filter,
376 376
             id=a.id,
377 377
         )
378 378
 
379  
-        self.assertRaisesRegexp(
  379
+        six.assertRaisesRegex(self,
380 380
             AssertionError,
381 381
             "Cannot reorder a query once a slice has been taken.",
382 382
             Article.objects.all()[0:5].order_by,
@@ -411,7 +411,7 @@ def test_object_creation(self):
411 411
 
412 412
         # An Article instance doesn't have access to the "objects" attribute.
413 413
         # That's only available on the class.
414  
-        self.assertRaisesRegexp(
  414
+        six.assertRaisesRegex(self,
415 415
             AttributeError,
416 416
             "Manager isn't accessible via Article instances",
417 417
             getattr,
7  tests/modeltests/empty/tests.py
... ...
@@ -1,10 +1,10 @@
1 1
 from __future__ import absolute_import
2 2
 
3  
-from django.conf import settings
4 3
 from django.core.exceptions import ImproperlyConfigured
5 4
 from django.db.models.loading import get_app
6 5
 from django.test import TestCase
7 6
 from django.test.utils import override_settings
  7
+from django.utils import six
8 8
 
9 9
 from .models import Empty
10 10
 
@@ -14,12 +14,13 @@ def test_empty(self):
14 14
         m = Empty()
15 15
         self.assertEqual(m.id, None)
16 16
         m.save()
17  
-        m2 = Empty.objects.create()
  17
+        Empty.objects.create()
18 18
         self.assertEqual(len(Empty.objects.all()), 2)
19 19
         self.assertTrue(m.id is not None)
20 20
         existing = Empty(m.id)
21 21
         existing.save()
22 22
 
  23
+
23 24
 class NoModelTests(TestCase):
24 25
     """
25 26
     Test for #7198 to ensure that the proper error message is raised
@@ -32,6 +33,6 @@ class NoModelTests(TestCase):
32 33
     """
33 34
     @override_settings(INSTALLED_APPS=("modeltests.empty.no_models",))
34 35
     def test_no_models(self):
35  
-        with self.assertRaisesRegexp(ImproperlyConfigured,
  36
+        with six.assertRaisesRegex(self, ImproperlyConfigured,
36 37
                     'App with label no_models is missing a models.py module.'):
37 38
             get_app('no_models')
34  tests/modeltests/fixtures/tests.py
@@ -4,7 +4,7 @@
4 4
 from django.core import management
5 5
 from django.db import connection, IntegrityError
6 6
 from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
7  
-from django.utils.six import StringIO
  7
+from django.utils import six
8 8
 
9 9
 from .models import Article, Book, Spy, Tag, Visa
10 10
 
@@ -21,16 +21,17 @@ def testClassFixtures(self):
21 21
             '<Article: Poker has no place on ESPN>',
22 22
         ])
23 23
 
  24
+
24 25
 class FixtureLoadingTests(TestCase):
25 26
 
26 27
     def _dumpdata_assert(self, args, output, format='json', natural_keys=False,
27 28
                          use_base_manager=False, exclude_list=[]):
28  
-        new_io = StringIO()
29  
-        management.call_command('dumpdata', *args, **{'format':format,
30  
-                                                      'stdout':new_io,
31  
-                                                      'stderr':new_io,
32  
-                                                      'use_natural_keys':natural_keys,
33  
-                                                      'use_base_manager':use_base_manager,
  29
+        new_io = six.StringIO()
  30
+        management.call_command('dumpdata', *args, **{'format': format,
  31
+                                                      'stdout': new_io,
  32
+                                                      'stderr': new_io,
  33
+                                                      'use_natural_keys': natural_keys,
  34
+                                                      'use_base_manager': use_base_manager,
34 35
                                                       'exclude': exclude_list})
35 36
         command_output = new_io.getvalue().strip()
36 37
         self.assertEqual(command_output, output)
@@ -42,8 +43,6 @@ def test_initial_data(self):
42 43
         ])
43 44
 
44 45
     def test_loading_and_dumping(self):
45  
-        new_io = StringIO()
46  
-
47 46
         Site.objects.all().delete()
48 47
         # Load fixture 1. Single JSON file, with two objects.
49 48
         management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False)
@@ -184,12 +183,12 @@ def test_dumpdata_with_excludes(self):
184 183
             exclude_list=['fixtures.Article', 'fixtures.Book', 'sites'])
185 184
 
186 185
         # Excluding a bogus app should throw an error
187  
-        with self.assertRaisesRegexp(management.CommandError,
  186
+        with six.assertRaisesRegex(self, management.CommandError,
188 187
                 "Unknown app in excludes: foo_app"):
189 188
             self._dumpdata_assert(['fixtures', 'sites'], '', exclude_list=['foo_app'])
190 189
 
191 190
         # Excluding a bogus model should throw an error
192  
-        with self.assertRaisesRegexp(management.CommandError,
  191
+        with six.assertRaisesRegex(self, management.CommandError,
193 192
                 "Unknown model in excludes: fixtures.FooModel"):
194 193
             self._dumpdata_assert(['fixtures', 'sites'], '', exclude_list=['fixtures.FooModel'])
195 194
 
@@ -199,7 +198,7 @@ def test_dumpdata_with_filtering_manager(self):
199 198
         self.assertQuerysetEqual(Spy.objects.all(),
200 199
                                  ['<Spy: Paul>'])
201 200
         # Use the default manager
202  
-        self._dumpdata_assert(['fixtures.Spy'],'[{"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": false}}]' % spy1.pk)
  201
+        self._dumpdata_assert(['fixtures.Spy'], '[{"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": false}}]' % spy1.pk)
203 202
         # Dump using Django's base manager. Should return all objects,
204 203
         # even those normally filtered by the manager
205 204
         self._dumpdata_assert(['fixtures.Spy'], '[{"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": true}}, {"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": false}}]' % (spy2.pk, spy1.pk), use_base_manager=True)
@@ -227,7 +226,7 @@ def test_compressed_loading(self):
227 226
 
228 227
     def test_ambiguous_compressed_fixture(self):
229 228
         # The name "fixture5" is ambigous, so loading it will raise an error
230  
-        with self.assertRaisesRegexp(management.CommandError,
  229
+        with six.assertRaisesRegex(self, management.CommandError,
231 230
                 "Multiple fixtures named 'fixture5'"):
232 231
             management.call_command('loaddata', 'fixture5', verbosity=0, commit=False)
233 232
 
@@ -251,7 +250,7 @@ def test_loaddata_error_message(self):
251 250
         # is closed at the end of each test.
252 251
         if connection.vendor == 'mysql':
253 252
             connection.cursor().execute("SET sql_mode = 'TRADITIONAL'")
254  
-        with self.assertRaisesRegexp(IntegrityError,
  253
+        with six.assertRaisesRegex(self, IntegrityError,
255 254
                 "Could not load fixtures.Article\(pk=1\): .*$"):
256 255
             management.call_command('loaddata', 'invalid.json', verbosity=0, commit=False)
257 256
 
@@ -290,10 +289,11 @@ def test_output_formats(self):
290 289
         self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?>
291 290
 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16T12:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16T13:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Prince</field></object><object pk="10" model="fixtures.book"><field type="CharField" name="name">Achieving self-awareness of Python programs</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"></field></object></django-objects>""", format='xml', natural_keys=True)
292 291
 
  292
+
293 293
 class FixtureTransactionTests(TransactionTestCase):
294 294
     def _dumpdata_assert(self, args, output, format='json'):
295  
-        new_io = StringIO()
296  
-        management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io})
  295
+        new_io = six.StringIO()
  296
+        management.call_command('dumpdata', *args, **{'format': format, 'stdout': new_io})
297 297
         command_output = new_io.getvalue().strip()
298 298
         self.assertEqual(command_output, output)
299 299
 
@@ -308,7 +308,7 @@ def test_format_discovery(self):
308 308
 
309 309
         # Try to load fixture 2 using format discovery; this will fail
310 310
         # because there are two fixture2's in the fixtures directory
311  
-        with self.assertRaisesRegexp(management.CommandError,
  311
+        with six.assertRaisesRegex(self, management.CommandError,
312 312
                 "Multiple fixtures named 'fixture2'"):
313 313
             management.call_command('loaddata', 'fixture2', verbosity=0)
314 314
 
3  tests/modeltests/many_to_many/tests.py
... ...
@@ -1,6 +1,7 @@
1 1
 from __future__ import absolute_import
2 2
 
3 3
 from django.test import TestCase
  4
+from django.utils import six
4 5
 
5 6
 from .models import Article, Publication
6 7
 
@@ -52,7 +53,7 @@ def test_add(self):
52 53
             ])
53 54
 
54 55
         # Adding an object of the wrong type raises TypeError
55  
-        with self.assertRaisesRegexp(TypeError, "'Publication' instance expected, got <Article.*"):
  56
+        with six.assertRaisesRegex(self, TypeError, "'Publication' instance expected, got <Article.*"):
56 57
             a6.publications.add(a5)
57 58
         # Add a Publication directly via publications.add by using keyword arguments.
58 59
         p4 = a6.publications.create(title='Highlights for Adults')
2  tests/modeltests/many_to_one/tests.py
@@ -70,7 +70,7 @@ def test_add(self):
70 70
         self.assertQuerysetEqual(self.r2.article_set.all(), ["<Article: Paul's story>"])
71 71
 
72 72
         # Adding an object of the wrong type raises TypeError.
73  
-        with self.assertRaisesRegexp(TypeError, "'Article' instance expected, got <Reporter.*"):
  73
+        with six.assertRaisesRegex(self, TypeError, "'Article' instance expected, got <Reporter.*"):
74 74
             self.r.article_set.add(self.r2)
75 75
         self.assertQuerysetEqual(self.r.article_set.all(),
76 76
             [
2  tests/modeltests/raw_query/tests.py
@@ -2,7 +2,7 @@
2 2
 
3 3
 from datetime import date
4 4
 
5  
-from django.db.models.sql.query import InvalidQuery
  5
+from django.db.models.query_utils import InvalidQuery
6 6
 from django.test import TestCase
7 7
 
8 8
 from .models import Author, Book, Coffee, Reviewer, FriendlyAuthor
3  tests/modeltests/update_only_fields/tests.py
... ...
@@ -1,7 +1,8 @@
1 1
 from __future__ import absolute_import
2 2
 
3  
-from django.test import TestCase
4 3
 from django.db.models.signals import pre_save, post_save
  4
+from django.test import TestCase
  5
+
5 6
 from .models import Person, Employee, ProxyEmployee, Profile, Account
6 7
 
7 8
 
3  tests/modeltests/validation/test_error_messages.py
@@ -3,6 +3,7 @@
3 3
 
4 4
 from django.core.exceptions import ValidationError
5 5
 from django.db import models
  6
+from django.utils import six
6 7
 from django.utils.unittest import TestCase
7 8
 
8 9
 
@@ -18,7 +19,7 @@ def test_autofield_field_raises_error_message(self):
18 19
         self._test_validation_messages(f, 'fõo',
19 20
             ["'fõo' value must be an integer."])
20 21
         # primary_key must be True. Refs #12467.
21  
-        with self.assertRaisesRegexp(AssertionError,
  22
+        with six.assertRaisesRegex(self, AssertionError,
22 23
                 "AutoFields must have primary_key=True."):
23 24
             models.AutoField(primary_key=False)
24 25
 
7  tests/regressiontests/admin_filters/tests.py
@@ -9,7 +9,7 @@
9 9
 from django.contrib.auth.models import User
10 10
 from django.core.exceptions import ImproperlyConfigured
11 11
 from django.test import TestCase, RequestFactory
12  
-from django.test.utils import override_settings
  12
+from django.test.utils import override_settings, six
13 13
 from django.utils.encoding import force_text
14 14
 
15 15
 from .models import Book, Department, Employee
@@ -18,6 +18,7 @@
18 18
 def select_by(dictlist, key, value):