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 b546e7eb633022ee1962570387f22fb2bcea46ed 2 parents cd583d6 + cff911f
Andrew Godwin authored September 05, 2012

Showing 302 changed files with 4,384 additions and 1,955 deletions. Show diff stats Hide diff stats

  1. 2  AUTHORS
  2. 2  MANIFEST.in
  3. 10  django/bin/django-2to3.py
  4. 14  django/conf/__init__.py
  5. 9  django/conf/project_template/project_name/settings.py
  6. 4  django/contrib/admin/models.py
  7. 2  django/contrib/admin/templates/admin/change_form.html
  8. 2  django/contrib/admin/templatetags/log.py
  9. 4  django/contrib/admin/util.py
  10. 6  django/contrib/admin/views/main.py
  11. 4  django/contrib/admindocs/utils.py
  12. 5  django/contrib/auth/decorators.py
  13. 10  django/contrib/auth/forms.py
  14. 10  django/contrib/auth/hashers.py
  15. 18  django/contrib/auth/management/__init__.py
  16. 16  django/contrib/auth/models.py
  17. 44  django/contrib/auth/tests/basic.py
  18. 8  django/contrib/auth/tests/management.py
  19. 3  django/contrib/auth/tests/tokens.py
  20. 9  django/contrib/auth/views.py
  21. 7  django/contrib/comments/models.py
  22. 4  django/contrib/contenttypes/models.py
  23. 4  django/contrib/contenttypes/tests.py
  24. 19  django/contrib/databrowse/datastructures.py
  25. 10  django/contrib/databrowse/tests.py
  26. 4  django/contrib/flatpages/models.py
  27. 61  django/contrib/formtools/tests/__init__.py
  28. 1  django/contrib/formtools/tests/forms.py
  29. 17  django/contrib/formtools/tests/wizard/namedwizardtests/tests.py
  30. 15  django/contrib/formtools/tests/wizard/wizardtests/tests.py
  31. 2  django/contrib/formtools/utils.py
  32. 4  django/contrib/formtools/wizard/storage/base.py
  33. 4  django/contrib/gis/db/backends/base.py
  34. 4  django/contrib/gis/db/backends/oracle/models.py
  35. 4  django/contrib/gis/db/backends/postgis/models.py
  36. 1  django/contrib/gis/db/backends/spatialite/creation.py
  37. 4  django/contrib/gis/db/backends/spatialite/models.py
  38. 11  django/contrib/gis/db/backends/spatialite/operations.py
  39. 3  django/contrib/gis/db/models/query.py
  40. 3  django/contrib/gis/gdal/tests/__init__.py
  41. 7  django/contrib/gis/maps/google/overlays.py
  42. 3  django/contrib/gis/sitemaps/views.py
  43. 22  django/contrib/gis/tests/distapp/models.py
  44. 26  django/contrib/gis/tests/geo3d/models.py
  45. 4  django/contrib/gis/tests/geoadmin/models.py
  46. 16  django/contrib/gis/tests/geoapp/models.py
  47. 9  django/contrib/gis/tests/geoapp/tests.py
  48. 10  django/contrib/gis/tests/geogapp/models.py
  49. 14  django/contrib/gis/tests/relatedapp/models.py
  50. 2  django/contrib/gis/utils/ogrinspect.py
  51. 6  django/contrib/markup/templatetags/markup.py
  52. 7  django/contrib/messages/storage/base.py
  53. 6  django/contrib/redirects/models.py
  54. 11  django/contrib/sessions/backends/base.py
  55. 3  django/contrib/sessions/backends/db.py
  56. 2  django/contrib/sessions/backends/file.py
  57. 7  django/contrib/sitemaps/tests/generic.py
  58. 36  django/contrib/sitemaps/tests/http.py
  59. 22  django/contrib/sitemaps/tests/https.py
  60. 7  django/contrib/sites/models.py
  61. 2  django/contrib/staticfiles/management/commands/collectstatic.py
  62. 20  django/contrib/staticfiles/storage.py
  63. 2  django/contrib/syndication/views.py
  64. 6  django/core/cache/backends/base.py
  65. 7  django/core/cache/backends/db.py
  66. 3  django/core/cache/backends/filebased.py
  67. 5  django/core/cache/backends/memcached.py
  68. 11  django/core/context_processors.py
  69. 18  django/core/files/base.py
  70. 2  django/core/files/move.py
  71. 11  django/core/files/storage.py
  72. 4  django/core/files/uploadedfile.py
  73. 4  django/core/files/uploadhandler.py
  74. 25  django/core/handlers/base.py
  75. 4  django/core/handlers/wsgi.py
  76. 7  django/core/mail/message.py
  77. 7  django/core/management/__init__.py
  78. 4  django/core/management/base.py
  79. 116  django/core/management/commands/inspectdb.py
  80. 12  django/core/management/commands/loaddata.py
  81. 60  django/core/management/commands/makemessages.py
  82. 18  django/core/management/commands/shell.py
  83. 2  django/core/management/commands/syncdb.py
  84. 5  django/core/management/sql.py
  85. 6  django/core/management/templates.py
  86. 4  django/core/management/validation.py
  87. 6  django/core/serializers/base.py
  88. 8  django/core/serializers/json.py
  89. 1  django/core/serializers/pyyaml.py
  90. 10  django/core/servers/basehttp.py
  91. 47  django/core/signing.py
  92. 40  django/core/urlresolvers.py
  93. 15  django/core/validators.py
  94. 28  django/db/backends/__init__.py
  95. 8  django/db/backends/mysql/base.py
  96. 10  django/db/backends/mysql/compiler.py
  97. 22  django/db/backends/mysql/introspection.py
  98. 23  django/db/backends/oracle/base.py
  99. 9  django/db/backends/oracle/compiler.py
  100. 6  django/db/backends/postgresql_psycopg2/base.py
  101. 4  django/db/backends/postgresql_psycopg2/introspection.py
  102. 26  django/db/backends/sqlite3/base.py
  103. 18  django/db/backends/sqlite3/introspection.py
  104. 3  django/db/backends/util.py
  105. 30  django/db/models/base.py
  106. 6  django/db/models/expressions.py
  107. 5  django/db/models/fields/__init__.py
  108. 4  django/db/models/fields/files.py
  109. 5  django/db/models/fields/subclassing.py
  110. 10  django/db/models/options.py
  111. 8  django/db/models/query.py
  112. 14  django/db/models/sql/compiler.py
  113. 2  django/db/models/sql/constants.py
  114. 106  django/db/models/sql/query.py
  115. 6  django/dispatch/saferef.py
  116. 12  django/forms/forms.py
  117. 29  django/forms/formsets.py
  118. 16  django/forms/models.py
  119. 12  django/forms/util.py
  120. 24  django/forms/widgets.py
  121. 199  django/http/__init__.py
  122. 12  django/http/multipartparser.py
  123. 7  django/middleware/csrf.py
  124. 11  django/template/base.py
  125. 19  django/template/defaultfilters.py
  126. 4  django/template/defaulttags.py
  127. 13  django/template/loaders/eggs.py
  128. 14  django/template/response.py
  129. 6  django/templatetags/cache.py
  130. 50  django/test/client.py
  131. 7  django/test/html.py
  132. 9  django/test/signals.py
  133. 53  django/test/testcases.py
  134. 2  django/test/utils.py
  135. 0  django/utils/2to3_fixes/__init__.py
  136. 36  django/utils/2to3_fixes/fix_unicode.py
  137. 18  django/utils/archive.py
  138. 5  django/utils/autoreload.py
  139. 11  django/utils/cache.py
  140. 17  django/utils/crypto.py
  141. 18  django/utils/dateparse.py
  142. 49  django/utils/encoding.py
  143. 10  django/utils/formats.py
  144. 1  django/utils/functional.py
  145. 19  django/utils/html.py
  146. 188  django/utils/html_parser.py
  147. 18  django/utils/http.py
  148. 2  django/utils/ipv6.py
  149. 74  django/utils/safestring.py
  150. 52  django/utils/six.py
  151. 21  django/utils/text.py
  152. 6  django/utils/translation/__init__.py
  153. 19  django/utils/translation/trans_real.py
  154. 6  django/utils/tzinfo.py
  155. 4  django/views/debug.py
  156. 8  django/views/generic/base.py
  157. 17  django/views/generic/dates.py
  158. 2  django/views/static.py
  159. 12  docs/conf.py
  160. 2  docs/faq/general.txt
  161. 6  docs/howto/custom-template-tags.txt
  162. 2  docs/howto/deployment/wsgi/gunicorn.txt
  163. 9  docs/index.txt
  164. 4  docs/internals/committers.txt
  165. 2  docs/internals/contributing/bugs-and-features.txt
  166. 11  docs/intro/tutorial03.txt
  167. 35  docs/ref/class-based-views/base.txt
  168. 556  docs/ref/class-based-views/flattened-index.txt
  169. 27  docs/ref/class-based-views/generic-date-based.txt
  170. 10  docs/ref/class-based-views/generic-display.txt
  171. 27  docs/ref/class-based-views/generic-editing.txt
  172. 3  docs/ref/class-based-views/index.txt
  173. 18  docs/ref/class-based-views/mixins-date-based.txt
  174. 14  docs/ref/class-based-views/mixins-editing.txt
  175. 6  docs/ref/class-based-views/mixins-multiple-object.txt
  176. 22  docs/ref/class-based-views/mixins-simple.txt
  177. 6  docs/ref/class-based-views/mixins-single-object.txt
  178. 8  docs/ref/contrib/admin/index.txt
  179. 4  docs/ref/contrib/comments/index.txt
  180. 147  docs/ref/contrib/csrf.txt
  181. 43  docs/ref/contrib/flatpages.txt
  182. 6  docs/ref/contrib/formtools/form-wizard.txt
  183. 42  docs/ref/contrib/gis/install.txt
  184. 5  docs/ref/contrib/gis/testing.txt
  185. 11  docs/ref/contrib/gis/tutorial.txt
  186. 8  docs/ref/databases.txt
  187. 12  docs/ref/files/file.txt
  188. 92  docs/ref/models/fields.txt
  189. 12  docs/ref/models/instances.txt
  190. 16  docs/ref/models/querysets.txt
  191. 19  docs/ref/request-response.txt
  192. 41  docs/ref/settings.txt
  193. 10  docs/ref/templates/api.txt
  194. 92  docs/ref/utils.txt
  195. 14  docs/releases/1.3.2.txt
  196. 14  docs/releases/1.4.1.txt
  197. 14  docs/releases/1.4.2.txt
  198. 93  docs/releases/1.5.txt
  199. 3  docs/releases/index.txt
  200. 21  docs/topics/auth.txt
  201. 2  docs/topics/cache.txt
  202. 153  docs/topics/class-based-views/index.txt
  203. 150  docs/topics/class-based-views/mixins.txt
  204. 28  docs/topics/db/models.txt
  205. 2  docs/topics/db/multi-db.txt
  206. 4  docs/topics/db/queries.txt
  207. 60  docs/topics/forms/media.txt
  208. 4  docs/topics/forms/modelforms.txt
  209. 46  docs/topics/http/file-uploads.txt
  210. 12  docs/topics/http/urls.txt
  211. 4  docs/topics/http/views.txt
  212. 22  docs/topics/i18n/translation.txt
  213. 38  docs/topics/logging.txt
  214. 308  docs/topics/python3.txt
  215. 6  docs/topics/templates.txt
  216. 2  docs/topics/testing.txt
  217. 2  setup.cfg
  218. 13  tests/modeltests/aggregation/models.py
  219. 4  tests/modeltests/basic/models.py
  220. 4  tests/modeltests/choices/models.py
  221. 7  tests/modeltests/custom_columns/models.py
  222. 10  tests/modeltests/custom_managers/models.py
  223. 4  tests/modeltests/custom_methods/models.py
  224. 9  tests/modeltests/custom_pk/fields.py
  225. 10  tests/modeltests/custom_pk/models.py
  226. 4  tests/modeltests/defer/models.py
  227. 4  tests/modeltests/delete/models.py
  228. 13  tests/modeltests/distinct_on_fields/models.py
  229. 7  tests/modeltests/expressions/models.py
  230. 4  tests/modeltests/field_defaults/models.py
  231. 13  tests/modeltests/field_subclassing/fields.py
  232. 4  tests/modeltests/field_subclassing/models.py
  233. 14  tests/modeltests/files/tests.py
  234. 22  tests/modeltests/fixtures/models.py
  235. 4  tests/modeltests/fixtures_model_package/models/__init__.py
  236. 16  tests/modeltests/generic_relations/models.py
  237. 7  tests/modeltests/get_latest/models.py
  238. 7  tests/modeltests/get_object_or_404/models.py
  239. 4  tests/modeltests/get_or_create/models.py
  240. 4  tests/modeltests/invalid_models/tests.py
  241. 13  tests/modeltests/lookup/models.py
  242. 4  tests/modeltests/m2m_and_m2o/models.py
  243. 10  tests/modeltests/m2m_intermediary/models.py
  244. 7  tests/modeltests/m2m_multiple/models.py
  245. 4  tests/modeltests/m2m_recursive/models.py
  246. 10  tests/modeltests/m2m_signals/models.py
  247. 16  tests/modeltests/m2m_through/models.py
  248. 7  tests/modeltests/m2o_recursive/models.py
  249. 7  tests/modeltests/many_to_many/models.py
  250. 7  tests/modeltests/many_to_one/models.py
  251. 7  tests/modeltests/many_to_one_null/models.py
  252. 52  tests/modeltests/model_forms/models.py
  253. 69  tests/modeltests/model_forms/tests.py
  254. 55  tests/modeltests/model_formsets/models.py
  255. 28  tests/modeltests/model_inheritance/models.py
  256. 4  tests/modeltests/model_inheritance_same_model_name/models.py
  257. 13  tests/modeltests/one_to_one/models.py
  258. 4  tests/modeltests/or_lookups/models.py
  259. 7  tests/modeltests/order_with_respect_to/models.py
  260. 7  tests/modeltests/ordering/models.py
  261. 4  tests/modeltests/pagination/models.py
  262. 12  tests/modeltests/pagination/tests.py
  263. 22  tests/modeltests/prefetch_related/models.py
  264. 2  tests/modeltests/prefetch_related/tests.py
  265. 3  tests/modeltests/proxy_model_inheritance/tests.py
  266. 13  tests/modeltests/proxy_models/models.py
  267. 6  tests/modeltests/reserved_names/models.py
  268. 10  tests/modeltests/reverse_lookup/models.py
  269. 4  tests/modeltests/save_delete_hooks/models.py
  270. 27  tests/modeltests/select_related/models.py
  271. 29  tests/modeltests/serializers/models.py
  272. 18  tests/modeltests/serializers/tests.py
  273. 7  tests/modeltests/signals/models.py
  274. 6  tests/modeltests/str/models.py
  275. 17  tests/modeltests/str/tests.py
  276. 2  tests/modeltests/test_client/models.py
  277. 1  tests/modeltests/timezones/tests.py
  278. 4  tests/modeltests/transactions/models.py
  279. 19  tests/modeltests/unmanaged_models/models.py
  280. 7  tests/modeltests/update/models.py
  281. 8  tests/modeltests/update_only_fields/models.py
  282. 101  tests/modeltests/update_only_fields/tests.py
  283. 6  tests/modeltests/validation/models.py
  284. 6  tests/modeltests/validation/tests.py
  285. 7  tests/regressiontests/admin_changelist/models.py
  286. 4  tests/regressiontests/admin_changelist/tests.py
  287. 9  tests/regressiontests/admin_custom_urls/fixtures/actions.json
  288. 6  tests/regressiontests/admin_custom_urls/models.py
  289. 43  tests/regressiontests/admin_custom_urls/tests.py
  290. 10  tests/regressiontests/admin_filters/models.py
  291. 10  tests/regressiontests/admin_inlines/models.py
  292. 2  tests/regressiontests/admin_scripts/custom_templates/project_template/ticket-18091-non-ascii-template.txt
  293. 4  tests/regressiontests/admin_scripts/models.py
  294. 30  tests/regressiontests/admin_scripts/tests.py
  295. 4  tests/regressiontests/admin_util/models.py
  296. 2  tests/regressiontests/admin_util/tests.py
  297. 4  tests/regressiontests/admin_validation/models.py
  298. 91  tests/regressiontests/admin_views/models.py
  299. 349  tests/regressiontests/admin_views/tests.py
  300. 24  tests/regressiontests/admin_widgets/models.py
  301. 16  tests/regressiontests/aggregation_regress/models.py
2  AUTHORS
@@ -373,6 +373,7 @@ answer newbie questions, and generally made Django that much better:
373 373
     michael.mcewan@gmail.com
374 374
     Paul McLanahan <paul@mclanahan.net>
375 375
     Tobias McNulty <http://www.caktusgroup.com/blog>
  376
+    Andrews Medina <andrewsmedina@gmail.com>
376 377
     Zain Memon
377 378
     Christian Metts
378 379
     michal@plovarna.cz
@@ -467,6 +468,7 @@ answer newbie questions, and generally made Django that much better:
467 468
     Vinay Sajip <vinay_sajip@yahoo.co.uk>
468 469
     Bartolome Sanchez Salado <i42sasab@uco.es>
469 470
     Kadesarin Sanjek
  471
+    Tim Saylor <tim.saylor@gmail.com>
470 472
     Massimo Scamarcia <massimo.scamarcia@gmail.com>
471 473
     Paulo Scardine <paulo@scardine.com.br>
472 474
     David Schein
2  MANIFEST.in
... ...
@@ -1,4 +1,4 @@
1  
-include README
  1
+include README.rst
2 2
 include AUTHORS
3 3
 include INSTALL
4 4
 include LICENSE
10  django/bin/django-2to3.py
... ...
@@ -0,0 +1,10 @@
  1
+#!/usr/bin/env python
  2
+
  3
+# This works exactly like 2to3, except that it uses Django's fixers rather
  4
+# than 2to3's built-in fixers.
  5
+
  6
+import sys
  7
+from lib2to3.main import main
  8
+
  9
+sys.exit(main("django.utils.2to3_fixes"))
  10
+
14  django/conf/__init__.py
@@ -152,17 +152,25 @@ def __init__(self, default_settings):
152 152
         Requests for configuration variables not in this class are satisfied
153 153
         from the module specified in default_settings (if possible).
154 154
         """
  155
+        self.__dict__['_deleted'] = set()
155 156
         self.default_settings = default_settings
156 157
 
157 158
     def __getattr__(self, name):
  159
+        if name in self._deleted:
  160
+            raise AttributeError
158 161
         return getattr(self.default_settings, name)
159 162
 
  163
+    def __setattr__(self, name, value):
  164
+        self._deleted.discard(name)
  165
+        return super(UserSettingsHolder, self).__setattr__(name, value)
  166
+
  167
+    def __delattr__(self, name):
  168
+        self._deleted.add(name)
  169
+        return super(UserSettingsHolder, self).__delattr__(name)
  170
+
160 171
     def __dir__(self):
161 172
         return list(self.__dict__) + dir(self.default_settings)
162 173
 
163  
-    # For Python < 2.6:
164  
-    __members__ = property(lambda self: self.__dir__())
165  
-
166 174
 settings = LazySettings()
167 175
 
168 176
 
9  django/conf/project_template/project_name/settings.py
@@ -13,10 +13,11 @@
13 13
     'default': {
14 14
         'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
15 15
         'NAME': '',                      # Or path to database file if using sqlite3.
16  
-        'USER': '',                      # Not used with sqlite3.
17  
-        'PASSWORD': '',                  # Not used with sqlite3.
18  
-        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
19  
-        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
  16
+        # The following settings are not used with sqlite3:
  17
+        'USER': '',
  18
+        'PASSWORD': '',
  19
+        'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
  20
+        'PORT': '',                      # Set to empty string for default.
20 21
     }
21 22
 }
22 23
 
4  django/contrib/admin/models.py
@@ -6,6 +6,7 @@
6 6
 from django.contrib.admin.util import quote
7 7
 from django.utils.translation import ugettext_lazy as _
8 8
 from django.utils.encoding import smart_text
  9
+from django.utils.encoding import python_2_unicode_compatible
9 10
 
10 11
 ADDITION = 1
11 12
 CHANGE = 2
@@ -16,6 +17,7 @@ def log_action(self, user_id, content_type_id, object_id, object_repr, action_fl
16 17
         e = self.model(None, None, user_id, content_type_id, smart_text(object_id), object_repr[:200], action_flag, change_message)
17 18
         e.save()
18 19
 
  20
+@python_2_unicode_compatible
19 21
 class LogEntry(models.Model):
20 22
     action_time = models.DateTimeField(_('action time'), auto_now=True)
21 23
     user = models.ForeignKey(User)
@@ -36,7 +38,7 @@ class Meta:
36 38
     def __repr__(self):
37 39
         return smart_text(self.action_time)
38 40
 
39  
-    def __unicode__(self):
  41
+    def __str__(self):
40 42
         if self.action_flag == ADDITION:
41 43
             return _('Added "%(object)s".') % {'object': self.object_repr}
42 44
         elif self.action_flag == CHANGE:
2  django/contrib/admin/templates/admin/change_form.html
@@ -29,7 +29,7 @@
29 29
 {% if change %}{% if not is_popup %}
30 30
   <ul class="object-tools">
31 31
     {% block object-tools-items %}
32  
-    <li><a href="history/" class="historylink">{% trans "History" %}</a></li>
  32
+    <li><a href="{% url opts|admin_urlname:'history' original.pk %}" class="historylink">{% trans "History" %}</a></li>
33 33
     {% if has_absolute_url %}<li><a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
34 34
     {% endblock %}
35 35
   </ul>
2  django/contrib/admin/templatetags/log.py
@@ -17,7 +17,7 @@ def render(self, context):
17 17
             user_id = self.user
18 18
             if not user_id.isdigit():
19 19
                 user_id = context[self.user].id
20  
-            context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:self.limit]
  20
+            context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:int(self.limit)]
21 21
         return ''
22 22
 
23 23
 @register.tag
4  django/contrib/admin/util.py
@@ -12,7 +12,7 @@
12 12
 from django.utils.html import format_html
13 13
 from django.utils.text import capfirst
14 14
 from django.utils import timezone
15  
-from django.utils.encoding import force_text, smart_text, smart_bytes
  15
+from django.utils.encoding import force_str, force_text, smart_text
16 16
 from django.utils import six
17 17
 from django.utils.translation import ungettext
18 18
 from django.core.urlresolvers import reverse
@@ -277,7 +277,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
277 277
             label = force_text(model._meta.verbose_name)
278 278
             attr = six.text_type
279 279
         elif name == "__str__":
280  
-            label = smart_bytes(model._meta.verbose_name)
  280
+            label = force_str(model._meta.verbose_name)
281 281
             attr = bytes
282 282
         else:
283 283
             if callable(name):
6  django/contrib/admin/views/main.py
@@ -6,7 +6,7 @@
6 6
 from django.db import models
7 7
 from django.db.models.fields import FieldDoesNotExist
8 8
 from django.utils.datastructures import SortedDict
9  
-from django.utils.encoding import force_text, smart_bytes
  9
+from django.utils.encoding import force_str, force_text
10 10
 from django.utils.translation import ugettext, ugettext_lazy
11 11
 from django.utils.http import urlencode
12 12
 
@@ -94,7 +94,7 @@ def get_filters(self, request):
94 94
                 # 'key' will be used as a keyword argument later, so Python
95 95
                 # requires it to be a string.
96 96
                 del lookup_params[key]
97  
-                lookup_params[smart_bytes(key)] = value
  97
+                lookup_params[force_str(key)] = value
98 98
 
99 99
             if not self.model_admin.lookup_allowed(key, value):
100 100
                 raise SuspiciousOperation("Filtering by %s not allowed" % key)
@@ -148,7 +148,7 @@ def get_query_string(self, new_params=None, remove=None):
148 148
         if remove is None: remove = []
149 149
         p = self.params.copy()
150 150
         for r in remove:
151  
-            for k in p.keys():
  151
+            for k in list(p):
152 152
                 if k.startswith(r):
153 153
                     del p[k]
154 154
         for k, v in new_params.items():
4  django/contrib/admindocs/utils.py
@@ -6,7 +6,7 @@
6 6
 
7 7
 from django.utils.safestring import mark_safe
8 8
 from django.core.urlresolvers import reverse
9  
-from django.utils.encoding import smart_bytes
  9
+from django.utils.encoding import force_bytes
10 10
 try:
11 11
     import docutils.core
12 12
     import docutils.nodes
@@ -66,7 +66,7 @@ def parse_rst(text, default_reference_context, thing_being_parsed=None):
66 66
         "link_base" : reverse('django-admindocs-docroot').rstrip('/')
67 67
     }
68 68
     if thing_being_parsed:
69  
-        thing_being_parsed = smart_bytes("<%s>" % thing_being_parsed)
  69
+        thing_being_parsed = force_bytes("<%s>" % thing_being_parsed)
70 70
     parts = docutils.core.publish_parts(text, source_path=thing_being_parsed,
71 71
                 destination_path=None, writer_name='html',
72 72
                 settings_overrides=overrides)
5  django/contrib/auth/decorators.py
@@ -7,6 +7,7 @@
7 7
 from django.contrib.auth import REDIRECT_FIELD_NAME
8 8
 from django.core.exceptions import PermissionDenied
9 9
 from django.utils.decorators import available_attrs
  10
+from django.utils.encoding import force_str
10 11
 
11 12
 
12 13
 def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
@@ -22,9 +23,11 @@ def _wrapped_view(request, *args, **kwargs):
22 23
             if test_func(request.user):
23 24
                 return view_func(request, *args, **kwargs)
24 25
             path = request.build_absolute_uri()
  26
+            # urlparse chokes on lazy objects in Python 3
  27
+            login_url_as_str = force_str(login_url or settings.LOGIN_URL)
25 28
             # If the login url is the same scheme and net location then just
26 29
             # use the path as the "next" url.
27  
-            login_scheme, login_netloc = urlparse(login_url or settings.LOGIN_URL)[:2]
  30
+            login_scheme, login_netloc = urlparse(login_url_as_str)[:2]
28 31
             current_scheme, current_netloc = urlparse(path)[:2]
29 32
             if ((not login_scheme or login_scheme == current_scheme) and
30 33
                 (not login_netloc or login_netloc == current_netloc)):
10  django/contrib/auth/forms.py
@@ -63,16 +63,16 @@ class UserCreationForm(forms.ModelForm):
63 63
     }
64 64
     username = forms.RegexField(label=_("Username"), max_length=30,
65 65
         regex=r'^[\w.@+-]+$',
66  
-        help_text = _("Required. 30 characters or fewer. Letters, digits and "
  66
+        help_text=_("Required. 30 characters or fewer. Letters, digits and "
67 67
                       "@/./+/-/_ only."),
68  
-        error_messages = {
  68
+        error_messages={
69 69
             'invalid': _("This value may contain only letters, numbers and "
70 70
                          "@/./+/-/_ characters.")})
71 71
     password1 = forms.CharField(label=_("Password"),
72 72
         widget=forms.PasswordInput)
73 73
     password2 = forms.CharField(label=_("Password confirmation"),
74 74
         widget=forms.PasswordInput,
75  
-        help_text = _("Enter the same password as above, for verification."))
  75
+        help_text=_("Enter the same password as above, for verification."))
76 76
 
77 77
     class Meta:
78 78
         model = User
@@ -107,9 +107,9 @@ def save(self, commit=True):
107 107
 class UserChangeForm(forms.ModelForm):
108 108
     username = forms.RegexField(
109 109
         label=_("Username"), max_length=30, regex=r"^[\w.@+-]+$",
110  
-        help_text = _("Required. 30 characters or fewer. Letters, digits and "
  110
+        help_text=_("Required. 30 characters or fewer. Letters, digits and "
111 111
                       "@/./+/-/_ only."),
112  
-        error_messages = {
  112
+        error_messages={
113 113
             'invalid': _("This value may contain only letters, numbers and "
114 114
                          "@/./+/-/_ characters.")})
115 115
     password = ReadOnlyPasswordHashField(label=_("Password"),
10  django/contrib/auth/hashers.py
@@ -8,7 +8,7 @@
8 8
 from django.test.signals import setting_changed
9 9
 from django.utils import importlib
10 10
 from django.utils.datastructures import SortedDict
11  
-from django.utils.encoding import smart_bytes
  11
+from django.utils.encoding import force_bytes
12 12
 from django.core.exceptions import ImproperlyConfigured
13 13
 from django.utils.crypto import (
14 14
     pbkdf2, constant_time_compare, get_random_string)
@@ -219,7 +219,7 @@ def encode(self, password, salt, iterations=None):
219 219
         if not iterations:
220 220
             iterations = self.iterations
221 221
         hash = pbkdf2(password, salt, iterations, digest=self.digest)
222  
-        hash = base64.b64encode(hash).strip()
  222
+        hash = base64.b64encode(hash).decode('ascii').strip()
223 223
         return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
224 224
 
225 225
     def verify(self, password, encoded):
@@ -299,7 +299,7 @@ class SHA1PasswordHasher(BasePasswordHasher):
299 299
     def encode(self, password, salt):
300 300
         assert password
301 301
         assert salt and '$' not in salt
302  
-        hash = hashlib.sha1(smart_bytes(salt + password)).hexdigest()
  302
+        hash = hashlib.sha1(force_bytes(salt + password)).hexdigest()
303 303
         return "%s$%s$%s" % (self.algorithm, salt, hash)
304 304
 
305 305
     def verify(self, password, encoded):
@@ -327,7 +327,7 @@ class MD5PasswordHasher(BasePasswordHasher):
327 327
     def encode(self, password, salt):
328 328
         assert password
329 329
         assert salt and '$' not in salt
330  
-        hash = hashlib.md5(smart_bytes(salt + password)).hexdigest()
  330
+        hash = hashlib.md5(force_bytes(salt + password)).hexdigest()
331 331
         return "%s$%s$%s" % (self.algorithm, salt, hash)
332 332
 
333 333
     def verify(self, password, encoded):
@@ -361,7 +361,7 @@ def salt(self):
361 361
         return ''
362 362
 
363 363
     def encode(self, password, salt):
364  
-        return hashlib.md5(smart_bytes(password)).hexdigest()
  364
+        return hashlib.md5(force_bytes(password)).hexdigest()
365 365
 
366 366
     def verify(self, password, encoded):
367 367
         encoded_2 = self.encode(password, '')
18  django/contrib/auth/management/__init__.py
@@ -9,6 +9,7 @@
9 9
 from django.contrib.auth import models as auth_app
10 10
 from django.db.models import get_models, signals
11 11
 from django.contrib.auth.models import User
  12
+from django.utils import six
12 13
 from django.utils.six.moves import input
13 14
 
14 15
 
@@ -85,13 +86,22 @@ def get_system_username():
85 86
         username could not be determined.
86 87
     """
87 88
     try:
88  
-        return getpass.getuser().decode(locale.getdefaultlocale()[1])
89  
-    except (ImportError, KeyError, UnicodeDecodeError):
  89
+        result = getpass.getuser()
  90
+    except (ImportError, KeyError):
90 91
         # KeyError will be raised by os.getpwuid() (called by getuser())
91 92
         # if there is no corresponding entry in the /etc/passwd file
92 93
         # (a very restricted chroot environment, for example).
93  
-        # UnicodeDecodeError - preventive treatment for non-latin Windows.
94 94
         return ''
  95
+    if not six.PY3:
  96
+        default_locale = locale.getdefaultlocale()[1]
  97
+        if not default_locale:
  98
+            return ''
  99
+        try:
  100
+            result = result.decode(default_locale)
  101
+        except UnicodeDecodeError:
  102
+            # UnicodeDecodeError - preventive treatment for non-latin Windows.
  103
+            return ''
  104
+    return result
95 105
 
96 106
 
97 107
 def get_default_username(check_db=True):
@@ -108,7 +118,7 @@ def get_default_username(check_db=True):
108 118
     default_username = get_system_username()
109 119
     try:
110 120
         default_username = unicodedata.normalize('NFKD', default_username)\
111  
-            .encode('ascii', 'ignore').replace(' ', '').lower()
  121
+            .encode('ascii', 'ignore').decode('ascii').replace(' ', '').lower()
112 122
     except UnicodeDecodeError:
113 123
         return ''
114 124
     if not RE_VALID_USERNAME.match(default_username):
16  django/contrib/auth/models.py
@@ -16,6 +16,7 @@
16 16
     check_password, make_password, is_password_usable, UNUSABLE_PASSWORD)
17 17
 from django.contrib.auth.signals import user_logged_in
18 18
 from django.contrib.contenttypes.models import ContentType
  19
+from django.utils.encoding import python_2_unicode_compatible
19 20
 
20 21
 
21 22
 def update_last_login(sender, user, **kwargs):
@@ -41,6 +42,7 @@ def get_by_natural_key(self, codename, app_label, model):
41 42
         )
42 43
 
43 44
 
  45
+@python_2_unicode_compatible
44 46
 class Permission(models.Model):
45 47
     """
46 48
     The permissions system provides a way to assign permissions to specific
@@ -76,7 +78,7 @@ class Meta:
76 78
         ordering = ('content_type__app_label', 'content_type__model',
77 79
                     'codename')
78 80
 
79  
-    def __unicode__(self):
  81
+    def __str__(self):
80 82
         return "%s | %s | %s" % (
81 83
             six.text_type(self.content_type.app_label),
82 84
             six.text_type(self.content_type),
@@ -94,6 +96,7 @@ class GroupManager(models.Manager):
94 96
     def get_by_natural_key(self, name):
95 97
         return self.get(name=name)
96 98
 
  99
+@python_2_unicode_compatible
97 100
 class Group(models.Model):
98 101
     """
99 102
     Groups are a generic way of categorizing users to apply permissions, or
@@ -121,7 +124,7 @@ class Meta:
121 124
         verbose_name = _('group')
122 125
         verbose_name_plural = _('groups')
123 126
 
124  
-    def __unicode__(self):
  127
+    def __str__(self):
125 128
         return self.name
126 129
 
127 130
     def natural_key(self):
@@ -221,6 +224,7 @@ def _user_has_module_perms(user, app_label):
221 224
     return False
222 225
 
223 226
 
  227
+@python_2_unicode_compatible
224 228
 class User(models.Model):
225 229
     """
226 230
     Users within the Django authentication system are represented by this
@@ -259,7 +263,7 @@ class Meta:
259 263
         verbose_name = _('user')
260 264
         verbose_name_plural = _('users')
261 265
 
262  
-    def __unicode__(self):
  266
+    def __str__(self):
263 267
         return self.username
264 268
 
265 269
     def natural_key(self):
@@ -403,6 +407,7 @@ def get_profile(self):
403 407
         return self._profile_cache
404 408
 
405 409
 
  410
+@python_2_unicode_compatible
406 411
 class AnonymousUser(object):
407 412
     id = None
408 413
     pk = None
@@ -416,11 +421,8 @@ class AnonymousUser(object):
416 421
     def __init__(self):
417 422
         pass
418 423
 
419  
-    def __unicode__(self):
420  
-        return 'AnonymousUser'
421  
-
422 424
     def __str__(self):
423  
-        return six.text_type(self).encode('utf-8')
  425
+        return 'AnonymousUser'
424 426
 
425 427
     def __eq__(self, other):
426 428
         return isinstance(other, self.__class__)
44  django/contrib/auth/tests/basic.py
... ...
@@ -1,13 +1,11 @@
  1
+import locale
  2
+import traceback
  3
+
  4
+from django.contrib.auth.management.commands import createsuperuser
1 5
 from django.contrib.auth.models import User, AnonymousUser
2 6
 from django.core.management import call_command
3 7
 from django.test import TestCase
4 8
 from django.utils.six import StringIO
5  
-from django.utils.unittest import skipUnless
6  
-
7  
-try:
8  
-    import crypt as crypt_module
9  
-except ImportError:
10  
-    crypt_module = None
11 9
 
12 10
 
13 11
 class BasicTestCase(TestCase):
@@ -111,3 +109,37 @@ def test_createsuperuser_management_command(self):
111 109
         u = User.objects.get(username="joe+admin@somewhere.org")
112 110
         self.assertEqual(u.email, 'joe@somewhere.org')
113 111
         self.assertFalse(u.has_usable_password())
  112
+
  113
+    def test_createsuperuser_nolocale(self):
  114
+        """
  115
+        Check that createsuperuser does not break when no locale is set. See
  116
+        ticket #16017.
  117
+        """
  118
+
  119
+        old_getdefaultlocale = locale.getdefaultlocale
  120
+        old_getpass = createsuperuser.getpass
  121
+        try:
  122
+            # Temporarily remove locale information
  123
+            locale.getdefaultlocale = lambda: (None, None)
  124
+
  125
+            # Temporarily replace getpass to allow interactive code to be used
  126
+            # non-interactively
  127
+            class mock_getpass: pass
  128
+            mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
  129
+            createsuperuser.getpass = mock_getpass
  130
+
  131
+            # Call the command in this new environment
  132
+            new_io = StringIO()
  133
+            call_command("createsuperuser", interactive=True, username="nolocale@somewhere.org", email="nolocale@somewhere.org", stdout=new_io)
  134
+
  135
+        except TypeError as e:
  136
+            self.fail("createsuperuser fails if the OS provides no information about the current locale")
  137
+
  138
+        finally:
  139
+            # Re-apply locale and getpass information
  140
+            createsuperuser.getpass = old_getpass
  141
+            locale.getdefaultlocale = old_getdefaultlocale
  142
+
  143
+        # If we were successful, a user should have been created
  144
+        u = User.objects.get(username="nolocale@somewhere.org")
  145
+        self.assertEqual(u.email, 'nolocale@somewhere.org')
8  django/contrib/auth/tests/management.py
@@ -4,16 +4,20 @@
4 4
 from django.contrib.auth.management.commands import changepassword
5 5
 from django.core.management.base import CommandError
6 6
 from django.test import TestCase
  7
+from django.utils import six
7 8
 from django.utils.six import StringIO
8 9
 
9 10
 
10 11
 class GetDefaultUsernameTestCase(TestCase):
11 12
 
12 13
     def setUp(self):
13  
-        self._getpass_getuser = management.get_system_username
  14
+        self.old_get_system_username = management.get_system_username
14 15
 
15 16
     def tearDown(self):
16  
-        management.get_system_username = self._getpass_getuser
  17
+        management.get_system_username = self.old_get_system_username
  18
+
  19
+    def test_actual_implementation(self):
  20
+        self.assertIsInstance(management.get_system_username(), six.text_type)
17 21
 
18 22
     def test_simple(self):
19 23
         management.get_system_username = lambda: 'joe'
3  django/contrib/auth/tests/tokens.py
... ...
@@ -1,9 +1,11 @@
  1
+import sys
1 2
 from datetime import date, timedelta
2 3
 
3 4
 from django.conf import settings
4 5
 from django.contrib.auth.models import User
5 6
 from django.contrib.auth.tokens import PasswordResetTokenGenerator
6 7
 from django.test import TestCase
  8
+from django.utils import unittest
7 9
 
8 10
 
9 11
 class TokenGeneratorTest(TestCase):
@@ -51,6 +53,7 @@ def _today(self):
51 53
         p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
52 54
         self.assertFalse(p2.check_token(user, tk1))
53 55
 
  56
+    @unittest.skipIf(sys.version_info[:2] >= (3, 0), "Unnecessary test with Python 3")
54 57
     def test_date_length(self):
55 58
         """
56 59
         Make sure we don't allow overly long dates, causing a potential DoS.
9  django/contrib/auth/views.py
@@ -7,6 +7,7 @@
7 7
 from django.core.urlresolvers import reverse
8 8
 from django.http import HttpResponseRedirect, QueryDict
9 9
 from django.template.response import TemplateResponse
  10
+from django.utils.encoding import force_str
10 11
 from django.utils.http import base36_to_int
11 12
 from django.utils.translation import ugettext as _
12 13
 from django.views.decorators.debug import sensitive_post_parameters
@@ -116,10 +117,10 @@ def redirect_to_login(next, login_url=None,
116 117
     """
117 118
     Redirects the user to the login page, passing the given 'next' page
118 119
     """
119  
-    if not login_url:
120  
-        login_url = settings.LOGIN_URL
  120
+    # urlparse chokes on lazy objects in Python 3
  121
+    login_url_as_str = force_str(login_url or settings.LOGIN_URL)
121 122
 
122  
-    login_url_parts = list(urlparse(login_url))
  123
+    login_url_parts = list(urlparse(login_url_as_str))
123 124
     if redirect_field_name:
124 125
         querystring = QueryDict(login_url_parts[4], mutable=True)
125 126
         querystring[redirect_field_name] = next
@@ -200,7 +201,7 @@ def password_reset_confirm(request, uidb36=None, token=None,
200 201
     try:
201 202
         uid_int = base36_to_int(uidb36)
202 203
         user = User.objects.get(id=uid_int)
203  
-    except (ValueError, User.DoesNotExist):
  204
+    except (ValueError, OverflowError, User.DoesNotExist):
204 205
         user = None
205 206
 
206 207
     if user is not None and token_generator.check_token(user, token):
7  django/contrib/comments/models.py
@@ -8,6 +8,7 @@
8 8
 from django.utils.translation import ugettext_lazy as _
9 9
 from django.utils import timezone
10 10
 from django.conf import settings
  11
+from django.utils.encoding import python_2_unicode_compatible
11 12
 
12 13
 COMMENT_MAX_LENGTH = getattr(settings,'COMMENT_MAX_LENGTH',3000)
13 14
 
@@ -39,6 +40,7 @@ def get_content_object_url(self):
39 40
             args=(self.content_type_id, self.object_pk)
40 41
         )
41 42
 
  43
+@python_2_unicode_compatible
42 44
 class Comment(BaseCommentAbstractModel):
43 45
     """
44 46
     A user comment about some object.
@@ -76,7 +78,7 @@ class Meta:
76 78
         verbose_name = _('comment')
77 79
         verbose_name_plural = _('comments')
78 80
 
79  
-    def __unicode__(self):
  81
+    def __str__(self):
80 82
         return "%s: %s..." % (self.name, self.comment[:50])
81 83
 
82 84
     def save(self, *args, **kwargs):
@@ -153,6 +155,7 @@ def get_as_text(self):
153 155
         }
154 156
         return _('Posted by %(user)s at %(date)s\n\n%(comment)s\n\nhttp://%(domain)s%(url)s') % d
155 157
 
  158
+@python_2_unicode_compatible
156 159
 class CommentFlag(models.Model):
157 160
     """
158 161
     Records a flag on a comment. This is intentionally flexible; right now, a
@@ -182,7 +185,7 @@ class Meta:
182 185
         verbose_name = _('comment flag')
183 186
         verbose_name_plural = _('comment flags')
184 187
 
185  
-    def __unicode__(self):
  188
+    def __str__(self):
186 189
         return "%s flag of comment ID %s by %s" % \
187 190
             (self.flag, self.comment_id, self.user.username)
188 191
 
4  django/contrib/contenttypes/models.py
... ...
@@ -1,6 +1,7 @@
1 1
 from django.db import models
2 2
 from django.utils.translation import ugettext_lazy as _
3 3
 from django.utils.encoding import smart_text, force_text
  4
+from django.utils.encoding import python_2_unicode_compatible
4 5
 
5 6
 class ContentTypeManager(models.Manager):
6 7
 
@@ -122,6 +123,7 @@ def _add_to_cache(self, using, ct):
122 123
         self.__class__._cache.setdefault(using, {})[key] = ct
123 124
         self.__class__._cache.setdefault(using, {})[ct.id] = ct
124 125
 
  126
+@python_2_unicode_compatible
125 127
 class ContentType(models.Model):
126 128
     name = models.CharField(max_length=100)
127 129
     app_label = models.CharField(max_length=100)
@@ -135,7 +137,7 @@ class Meta:
135 137
         ordering = ('name',)
136 138
         unique_together = (('app_label', 'model'),)
137 139
 
138  
-    def __unicode__(self):
  140
+    def __str__(self):
139 141
         # self.name is deprecated in favor of using model's verbose_name, which
140 142
         # can be translated. Formal deprecation is delayed until we have DB
141 143
         # migration to be able to remove the field from the database along with
4  django/contrib/contenttypes/tests.py
@@ -8,6 +8,7 @@
8 8
 from django.test import TestCase
9 9
 from django.utils.http import urlquote
10 10
 from django.utils import six
  11
+from django.utils.encoding import python_2_unicode_compatible
11 12
 
12 13
 
13 14
 class ConcreteModel(models.Model):
@@ -17,13 +18,14 @@ class ProxyModel(ConcreteModel):
17 18
     class Meta:
18 19
         proxy = True
19 20
 
  21
+@python_2_unicode_compatible
20 22
 class FooWithoutUrl(models.Model):
21 23
     """
22 24
     Fake model not defining ``get_absolute_url`` for
23 25
     :meth:`ContentTypesTests.test_shortcut_view_without_get_absolute_url`"""
24 26
     name = models.CharField(max_length=30, unique=True)
25 27
 
26  
-    def __unicode__(self):
  28
+    def __str__(self):
27 29
         return self.name
28 30
 
29 31
 
19  django/contrib/databrowse/datastructures.py
@@ -7,8 +7,9 @@
7 7
 from django.db import models
8 8
 from django.utils import formats
9 9
 from django.utils.text import capfirst
10  
-from django.utils.encoding import smart_text, smart_bytes, iri_to_uri
  10
+from django.utils.encoding import smart_text, force_str, iri_to_uri
11 11
 from django.db.models.query import QuerySet
  12
+from django.utils.encoding import python_2_unicode_compatible
12 13
 
13 14
 EMPTY_VALUE = '(None)'
14 15
 DISPLAY_SIZE = 100
@@ -22,7 +23,7 @@ def __init__(self, site, model):
22 23
         self.verbose_name_plural = model._meta.verbose_name_plural
23 24
 
24 25
     def __repr__(self):
25  
-        return '<EasyModel for %s>' % smart_bytes(self.model._meta.object_name)
  26
+        return force_str('<EasyModel for %s>' % self.model._meta.object_name)
26 27
 
27 28
     def model_databrowse(self):
28 29
         "Returns the ModelDatabrowse class for this model."
@@ -61,7 +62,7 @@ def __init__(self, easy_model, field):
61 62
         self.model, self.field = easy_model, field
62 63
 
63 64
     def __repr__(self):
64  
-        return smart_bytes('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
  65
+        return force_str('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
65 66
 
66 67
     def choices(self):
67 68
         for value, label in self.field.choices:
@@ -79,27 +80,25 @@ def __init__(self, easy_model, field, value, label):
79 80
         self.value, self.label = value, label
80 81
 
81 82
     def __repr__(self):
82  
-        return smart_bytes('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
  83
+        return force_str('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
83 84
 
84 85
     def url(self):
85 86
         return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))
86 87
 
  88
+@python_2_unicode_compatible
87 89
 class EasyInstance(object):
88 90
     def __init__(self, easy_model, instance):
89 91
         self.model, self.instance = easy_model, instance
90 92
 
91 93
     def __repr__(self):
92  
-        return smart_bytes('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
  94
+        return force_str('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val()))
93 95
 
94  
-    def __unicode__(self):
  96
+    def __str__(self):
95 97
         val = smart_text(self.instance)
96 98
         if len(val) > DISPLAY_SIZE:
97 99
             return val[:DISPLAY_SIZE] + '...'
98 100
         return val
99 101
 
100  
-    def __str__(self):
101  
-        return self.__unicode__().encode('utf-8')
102  
-
103 102
     def pk(self):
104 103
         return self.instance._get_pk_val()
105 104
 
@@ -136,7 +135,7 @@ def __init__(self, easy_model, instance, field):
136 135
         self.raw_value = getattr(instance.instance, field.name)
137 136
 
138 137
     def __repr__(self):
139  
-        return smart_bytes('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
  138
+        return force_str('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
140 139
 
141 140
     def values(self):
142 141
         """
10  django/contrib/databrowse/tests.py
... ...
@@ -1,26 +1,30 @@
1 1
 from django.contrib import databrowse
2 2
 from django.db import models
3 3
 from django.test import TestCase
  4
+from django.utils.encoding import python_2_unicode_compatible
4 5
 
5 6
 
  7
+@python_2_unicode_compatible
6 8
 class SomeModel(models.Model):
7 9
     some_field = models.CharField(max_length=50)
8 10
 
9  
-    def __unicode__(self):
  11
+    def __str__(self):
10 12
         return self.some_field
11 13
 
12 14
 
  15
+@python_2_unicode_compatible
13 16
 class SomeOtherModel(models.Model):
14 17
     some_other_field = models.CharField(max_length=50)
15 18
 
16  
-    def __unicode__(self):
  19
+    def __str__(self):
17 20
         return self.some_other_field
18 21
 
19 22
 
  23
+@python_2_unicode_compatible
20 24
 class YetAnotherModel(models.Model):
21 25
     yet_another_field = models.CharField(max_length=50)
22 26
 
23  
-    def __unicode__(self):
  27
+    def __str__(self):
24 28
         return self.yet_another_field
25 29
 
26 30
 
4  django/contrib/flatpages/models.py
@@ -3,8 +3,10 @@
3 3
 from django.db import models
4 4
 from django.contrib.sites.models import Site
5 5
 from django.utils.translation import ugettext_lazy as _
  6
+from django.utils.encoding import python_2_unicode_compatible
6 7
 
7 8
 
  9
+@python_2_unicode_compatible
8 10
 class FlatPage(models.Model):
9 11
     url = models.CharField(_('URL'), max_length=100, db_index=True)
10 12
     title = models.CharField(_('title'), max_length=200)
@@ -21,7 +23,7 @@ class Meta:
21 23
         verbose_name_plural = _('flat pages')
22 24
         ordering = ('url',)
23 25
 
24  
-    def __unicode__(self):
  26
+    def __str__(self):
25 27
         return "%s -- %s" % (self.url, self.title)
26 28
 
27 29
     def get_absolute_url(self):
61  django/contrib/formtools/tests/__init__.py
... ...
@@ -1,6 +1,9 @@
  1
+# -*- coding: utf-8 -*-
1 2
 from __future__ import unicode_literals
2 3
 
  4
+import datetime
3 5
 import os
  6
+import pickle
4 7
 import re
5 8
 import warnings
6 9
 
@@ -16,6 +19,7 @@
16 19
 from django.contrib.formtools.tests.forms import *
17 20
 
18 21
 success_string = "Done was called!"
  22
+success_string_encoded = success_string.encode()
19 23
 
20 24
 class TestFormPreview(preview.FormPreview):
21 25
     def get_context(self, request, form):
@@ -78,7 +82,7 @@ def test_form_preview(self):
78 82
         """
79 83
         # Pass strings for form submittal and add stage variable to
80 84
         # show we previously saw first stage of the form.
81  
-        self.test_data.update({'stage': 1})
  85
+        self.test_data.update({'stage': 1, 'date1': datetime.date(2006, 10, 25)})
82 86
         response = self.client.post('/preview/', self.test_data)
83 87
         # Check to confirm stage is set to 2 in output form.
84 88
         stage = self.input % 2
@@ -96,13 +100,13 @@ def test_form_submit(self):
96 100
         """
97 101
         # Pass strings for form submittal and add stage variable to
98 102
         # show we previously saw first stage of the form.
99  
-        self.test_data.update({'stage':2})
  103
+        self.test_data.update({'stage': 2, 'date1': datetime.date(2006, 10, 25)})
100 104
         response = self.client.post('/preview/', self.test_data)
101  
-        self.assertNotEqual(response.content, success_string)
  105
+        self.assertNotEqual(response.content, success_string_encoded)
102 106
         hash = self.preview.security_hash(None, TestForm(self.test_data))
103 107
         self.test_data.update({'hash': hash})
104 108
         response = self.client.post('/preview/', self.test_data)
105  
-        self.assertEqual(response.content, success_string)
  109
+        self.assertEqual(response.content, success_string_encoded)
106 110
 
107 111
     def test_bool_submit(self):
108 112
         """
@@ -122,7 +126,7 @@ def test_bool_submit(self):
122 126
         self.test_data.update({'hash': hash, 'bool1': 'False'})
123 127
         with warnings.catch_warnings(record=True):
124 128
             response = self.client.post('/preview/', self.test_data)
125  
-            self.assertEqual(response.content, success_string)
  129
+            self.assertEqual(response.content, success_string_encoded)
126 130
 
127 131
     def test_form_submit_good_hash(self):
128 132
         """
@@ -133,11 +137,11 @@ def test_form_submit_good_hash(self):
133 137
         # show we previously saw first stage of the form.
134 138
         self.test_data.update({'stage':2})
135 139
         response = self.client.post('/preview/', self.test_data)
136  
-        self.assertNotEqual(response.content, success_string)
  140
+        self.assertNotEqual(response.content, success_string_encoded)
137 141
         hash = utils.form_hmac(TestForm(self.test_data))
138 142
         self.test_data.update({'hash': hash})
139 143
         response = self.client.post('/preview/', self.test_data)
140  
-        self.assertEqual(response.content, success_string)
  144
+        self.assertEqual(response.content, success_string_encoded)
141 145
 
142 146
 
143 147
     def test_form_submit_bad_hash(self):
@@ -150,11 +154,11 @@ def test_form_submit_bad_hash(self):
150 154
         self.test_data.update({'stage':2})
151 155
         response = self.client.post('/preview/', self.test_data)
152 156
         self.assertEqual(response.status_code, 200)
153  
-        self.assertNotEqual(response.content, success_string)
  157
+        self.assertNotEqual(response.content, success_string_encoded)
154 158
         hash = utils.form_hmac(TestForm(self.test_data)) + "bad"
155 159
         self.test_data.update({'hash': hash})
156 160
         response = self.client.post('/previewpreview/', self.test_data)
157  
-        self.assertNotEqual(response.content, success_string)
  161
+        self.assertNotEqual(response.content, success_string_encoded)
158 162
 
159 163
 
160 164
 class FormHmacTests(unittest.TestCase):
@@ -165,8 +169,8 @@ def test_textfield_hash(self):
165 169
         leading/trailing whitespace so as to be friendly to broken browsers that
166 170
         submit it (usually in textareas).
167 171
         """
168  
-        f1 = HashTestForm({'name': 'joe', 'bio': 'Nothing notable.'})
169  
-        f2 = HashTestForm({'name': '  joe', 'bio': 'Nothing notable.  '})
  172
+        f1 = HashTestForm({'name': 'joe', 'bio': 'Speaking español.'})
  173
+        f2 = HashTestForm({'name': '  joe', 'bio': 'Speaking español.  '})
170 174
         hash1 = utils.form_hmac(f1)
171 175
         hash2 = utils.form_hmac(f2)
172 176
         self.assertEqual(hash1, hash2)
@@ -270,7 +274,10 @@ def test_good_hash(self):
270 274
         """
271 275
         data = {"0-field": "test",
272 276
                 "1-field": "test2",
273  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  277
+                "hash_0": {
  278
+                    2: "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  279
+                    3: "9355d5dff22d49dbad58e46189982cec649f9f5b",
  280
+                }[pickle.HIGHEST_PROTOCOL],
274 281
                 "wizard_step": "1"}
275 282
         response = self.client.post('/wizard1/', data)
276 283
         self.assertEqual(2, response.context['step0'])
@@ -295,15 +302,24 @@ def process_step(self, request, form, step):
295 302
         wizard = WizardWithProcessStep([WizardPageOneForm])
296 303
         data = {"0-field": "test",
297 304
                 "1-field": "test2",
298  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  305
+                "hash_0": {
  306
+                    2: "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  307
+                    3: "9355d5dff22d49dbad58e46189982cec649f9f5b",
  308
+                }[pickle.HIGHEST_PROTOCOL],
299 309
                 "wizard_step": "1"}
300 310
         wizard(DummyRequest(POST=data))
301 311
         self.assertTrue(reached[0])
302 312
 
303 313
         data = {"0-field": "test",
304 314
                 "1-field": "test2",
305  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
306  
-                "hash_1": "1e6f6315da42e62f33a30640ec7e007ad3fbf1a1",
  315
+                "hash_0": {
  316
+                    2: "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  317
+                    3: "9355d5dff22d49dbad58e46189982cec649f9f5b",
  318
+                }[pickle.HIGHEST_PROTOCOL],
  319
+                "hash_1": {
  320
+                    2: "1e6f6315da42e62f33a30640ec7e007ad3fbf1a1",
  321
+                    3: "c33142ef9d01b1beae238adf22c3c6c57328f51a",
  322
+                }[pickle.HIGHEST_PROTOCOL],
307 323
                 "wizard_step": "2"}
308 324
         self.assertRaises(http.Http404, wizard, DummyRequest(POST=data))
309 325
 
@@ -325,7 +341,10 @@ def process_step(self, request, form, step):
325 341
                                         WizardPageThreeForm])
326 342
         data = {"0-field": "test",
327 343
                 "1-field": "test2",
328  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  344
+                "hash_0": {
  345
+                    2: "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  346
+                    3: "9355d5dff22d49dbad58e46189982cec649f9f5b",
  347
+                }[pickle.HIGHEST_PROTOCOL],
329 348
                 "wizard_step": "1"}
330 349
         wizard(DummyRequest(POST=data))
331 350
         self.assertTrue(reached[0])
@@ -349,7 +368,10 @@ def done(self, request, form_list):
349 368
 
350 369
         data = {"0-field": "test",
351 370
                 "1-field": "test2",
352  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  371
+                "hash_0": {
  372
+                    2: "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  373
+                    3: "9355d5dff22d49dbad58e46189982cec649f9f5b",
  374
+                }[pickle.HIGHEST_PROTOCOL],
353 375
                 "wizard_step": "1"}
354 376
         wizard(DummyRequest(POST=data))
355 377
         self.assertTrue(reached[0])
@@ -375,7 +397,10 @@ def process_step(self, request, form, step):
375 397
                                         WizardPageThreeForm])
376 398
         data = {"0-field": "test",
377 399
                 "1-field": "test2",
378  
-                "hash_0": "cd13b1db3e8f55174bc5745a1b1a53408d4fd1ca",
  400
+                &qu