Index: django/test/simple.py
===================================================================
--- django/test/simple.py	(revision 11723)
+++ django/test/simple.py	(working copy)
@@ -101,14 +101,6 @@
             raise ValueError("Test label '%s' does not refer to a test class" % label)
         return TestClass(parts[2])
 
-# Python 2.3 compatibility: TestSuites were made iterable in 2.4.
-# We need to iterate over them, so we add the missing method when
-# necessary.
-try:
-    getattr(unittest.TestSuite, '__iter__')
-except AttributeError:
-    setattr(unittest.TestSuite, '__iter__', lambda s: iter(s._tests))
-
 def partition_suite(suite, classes, bins):
     """
     Partitions a test suite by test type.
Index: django/db/models/options.py
===================================================================
--- django/db/models/options.py	(revision 11723)
+++ django/db/models/options.py	(working copy)
@@ -1,9 +1,5 @@
 import re
 from bisect import bisect
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
 
 from django.conf import settings
 from django.db.models.related import RelatedObject
Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 11723)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -3,10 +3,6 @@
 import os
 import re
 import time
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal    # for Python 2.3
 
 from django.db import connection
 from django.db.models import signals
Index: django/db/models/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revision 11723)
+++ django/db/models/fields/related.py	(working copy)
@@ -11,11 +11,6 @@
 from django.core import exceptions
 from django import forms
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
 
 pending_lookups = {}
Index: django/db/models/query_utils.py
===================================================================
--- django/db/models/query_utils.py	(revision 11723)
+++ django/db/models/query_utils.py	(working copy)
@@ -12,12 +12,6 @@
 from django.utils import tree
 from django.utils.datastructures import SortedDict
 
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted  # For Python 2.3.
-
-
 class CyclicDependency(Exception):
     """
     An error when dealing with a collection of objects that have a cyclic
Index: django/db/backends/sqlite3/base.py
===================================================================
--- django/db/backends/sqlite3/base.py	(revision 11723)
+++ django/db/backends/sqlite3/base.py	(working copy)
@@ -1,7 +1,7 @@
 """
 SQLite3 backend for django.
 
-Python 2.3 and 2.4 require pysqlite2 (http://pysqlite.org/).
+Python 2.4 requires pysqlite2 (http://pysqlite.org/).
 
 Python 2.5 and later can use a pysqlite2 module or the sqlite3 module in the
 standard library.
@@ -29,11 +29,6 @@
         module = 'either pysqlite2 or sqlite3 modules (tried in that order)'
     raise ImproperlyConfigured, "Error loading %s: %s" % (module, exc)
 
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal # for Python 2.3
-
 DatabaseError = Database.DatabaseError
 IntegrityError = Database.IntegrityError
 
Index: django/db/backends/util.py
===================================================================
--- django/db/backends/util.py	(revision 11723)
+++ django/db/backends/util.py	(working copy)
@@ -3,11 +3,6 @@
 
 from django.utils.hashcompat import md5_constructor
 
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal    # for Python 2.3
-
 class CursorDebugWrapper(object):
     def __init__(self, cursor, db):
         self.cursor = cursor
Index: django/db/backends/__init__.py
===================================================================
--- django/db/backends/__init__.py	(revision 11723)
+++ django/db/backends/__init__.py	(working copy)
@@ -4,18 +4,7 @@
 except ImportError:
     # Import copy of _thread_local.py from Python 2.4
     from django.utils._threading_local import local
-try:
-    set
-except NameError:
-    # Python 2.3 compat
-    from sets import Set as set
 
-try:
-    import decimal
-except ImportError:
-    # Python 2.3 fallback
-    from django.utils import _decimal as decimal
-
 from django.db.backends import util
 from django.utils import datetime_safe
 
Index: django/db/backends/creation.py
===================================================================
--- django/db/backends/creation.py	(revision 11723)
+++ django/db/backends/creation.py	(working copy)
@@ -1,10 +1,5 @@
 import sys
 import time
-try:
-    set
-except NameError:
-    # Python 2.3 compat
-    from sets import Set as set
 
 from django.conf import settings
 from django.core.management import call_command
Index: django/db/transaction.py
===================================================================
--- django/db/transaction.py	(revision 11723)
+++ django/db/transaction.py	(working copy)
@@ -19,7 +19,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 from django.db import connection
 from django.conf import settings
 
Index: django/forms/models.py
===================================================================
--- django/forms/models.py	(revision 11723)
+++ django/forms/models.py	(working copy)
@@ -15,11 +15,6 @@
 from widgets import media_property
 from formsets import BaseFormSet, formset_factory, DELETION_FIELD_NAME
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
-
 __all__ = (
     'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model',
     'save_instance', 'form_for_fields', 'ModelChoiceField',
Index: django/forms/fields.py
===================================================================
--- django/forms/fields.py	(revision 11723)
+++ django/forms/fields.py	(working copy)
@@ -13,16 +13,6 @@
 except ImportError:
     from StringIO import StringIO
 
-# Python 2.3 fallbacks
-try:
-    from decimal import Decimal, DecimalException
-except ImportError:
-    from django.utils._decimal import Decimal, DecimalException
-try:
-    set
-except NameError:
-    from sets import Set as set
-
 import django.core.exceptions
 from django.utils.translation import ugettext_lazy as _
 from django.utils.encoding import smart_unicode, smart_str
Index: django/forms/widgets.py
===================================================================
--- django/forms/widgets.py	(revision 11723)
+++ django/forms/widgets.py	(working copy)
@@ -2,11 +2,6 @@
 HTML Widget classes
 """
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 import copy
 from itertools import chain
 from django.conf import settings
Index: django/core/serializers/json.py
===================================================================
--- django/core/serializers/json.py	(revision 11723)
+++ django/core/serializers/json.py	(working copy)
@@ -10,11 +10,6 @@
 from django.utils import datetime_safe
 from django.utils import simplejson
 
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal    # Python 2.3 fallback
-
 class Serializer(PythonSerializer):
     """
     Convert a queryset to JSON.
Index: django/core/serializers/pyyaml.py
===================================================================
--- django/core/serializers/pyyaml.py	(revision 11723)
+++ django/core/serializers/pyyaml.py	(working copy)
@@ -7,11 +7,6 @@
 from StringIO import StringIO
 import yaml
 
-try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal # Python 2.3 fallback
-
 from django.db import models
 from django.core.serializers.python import Serializer as PythonSerializer
 from django.core.serializers.python import Deserializer as PythonDeserializer
Index: django/core/urlresolvers.py
===================================================================
--- django/core/urlresolvers.py	(revision 11723)
+++ django/core/urlresolvers.py	(working copy)
@@ -18,12 +18,6 @@
 from django.utils.regex_helper import normalize
 from django.utils.thread_support import currentThread
 
-try:
-    reversed
-except NameError:
-    from django.utils.itercompat import reversed     # Python 2.3 fallback
-    from sets import Set as set
-
 _resolver_cache = {} # Maps URLconf modules to RegexURLResolver instances.
 _callable_cache = {} # Maps view and url pattern names to their view functions.
 
Index: django/core/cache/backends/locmem.py
===================================================================
--- django/core/cache/backends/locmem.py	(revision 11723)
+++ django/core/cache/backends/locmem.py	(working copy)
@@ -77,7 +77,7 @@
 
     def set(self, key, value, timeout=None):
         self._lock.writer_enters()
-        # Python 2.3 and 2.4 don't allow combined try-except-finally blocks.
+        # Python 2.4 doesn't allow combined try-except-finally blocks.
         try:
             try:
                 self._set(key, pickle.dumps(value), timeout)
Index: django/core/management/commands/makemessages.py
===================================================================
--- django/core/management/commands/makemessages.py	(revision 11723)
+++ django/core/management/commands/makemessages.py	(working copy)
@@ -8,11 +8,6 @@
 
 from django.core.management.base import CommandError, BaseCommand
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # For Python 2.3
-
 # Intentionally silence DeprecationWarnings about os.popen3 in Python 2.6. It's
 # still sensible for us to use it, since subprocess didn't exist in 2.3.
 warnings.filterwarnings('ignore', category=DeprecationWarning, message=r'os\.popen3')
Index: django/core/management/commands/loaddata.py
===================================================================
--- django/core/management/commands/loaddata.py	(revision 11723)
+++ django/core/management/commands/loaddata.py	(working copy)
@@ -8,11 +8,6 @@
 from django.core.management.color import no_style
 
 try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
-try:
     import bz2
     has_bz2 = True
 except ImportError:
Index: django/core/management/commands/compilemessages.py
===================================================================
--- django/core/management/commands/compilemessages.py	(revision 11723)
+++ django/core/management/commands/compilemessages.py	(working copy)
@@ -3,11 +3,6 @@
 from optparse import make_option
 from django.core.management.base import BaseCommand, CommandError
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # For Python 2.3
-
 def compile_messages(locale=None):
     basedirs = [os.path.join('conf', 'locale'), 'locale']
     if os.environ.get('DJANGO_SETTINGS_MODULE'):
Index: django/core/management/commands/syncdb.py
===================================================================
--- django/core/management/commands/syncdb.py	(revision 11723)
+++ django/core/management/commands/syncdb.py	(working copy)
@@ -4,11 +4,6 @@
 from optparse import make_option
 import sys
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 class Command(NoArgsCommand):
     option_list = NoArgsCommand.option_list + (
         make_option('--noinput', action='store_false', dest='interactive', default=True,
Index: django/core/management/base.py
===================================================================
--- django/core/management/base.py	(revision 11723)
+++ django/core/management/base.py	(working copy)
@@ -12,11 +12,6 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.core.management.color import color_style
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # For Python 2.3
-
 class CommandError(Exception):
     """
     Exception class indicating a problem while executing a management
Index: django/core/management/sql.py
===================================================================
--- django/core/management/sql.py	(revision 11723)
+++ django/core/management/sql.py	(working copy)
@@ -2,11 +2,6 @@
 import os
 import re
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 def sql_create(app, style):
     "Returns a list of the CREATE TABLE SQL statements for the given app."
     from django.db import connection, models
Index: django/views/decorators/csrf.py
===================================================================
--- django/views/decorators/csrf.py	(revision 11723)
+++ django/views/decorators/csrf.py	(working copy)
@@ -3,7 +3,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
 csrf_protect.__name__ = "csrf_protect"
Index: django/views/decorators/http.py
===================================================================
--- django/views/decorators/http.py	(revision 11723)
+++ django/views/decorators/http.py	(working copy)
@@ -5,7 +5,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from calendar import timegm
 from datetime import timedelta
Index: django/views/decorators/vary.py
===================================================================
--- django/views/decorators/vary.py	(revision 11723)
+++ django/views/decorators/vary.py	(working copy)
@@ -1,7 +1,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from django.utils.cache import patch_vary_headers
 
Index: django/views/decorators/cache.py
===================================================================
--- django/views/decorators/cache.py	(revision 11723)
+++ django/views/decorators/cache.py	(working copy)
@@ -14,7 +14,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from django.utils.decorators import decorator_from_middleware_with_args, auto_adapt_to_methods
 from django.utils.cache import patch_cache_control, add_never_cache_headers
Index: django/dispatch/dispatcher.py
===================================================================
--- django/dispatch/dispatcher.py	(revision 11723)
+++ django/dispatch/dispatcher.py	(working copy)
@@ -1,8 +1,4 @@
 import weakref
-try:
-    set
-except NameError:
-    from sets import Set as set # Python 2.3 fallback
 
 from django.dispatch import saferef
 
Index: django/utils/translation/trans_real.py
===================================================================
--- django/utils/translation/trans_real.py	(revision 11723)
+++ django/utils/translation/trans_real.py	(working copy)
@@ -56,7 +56,7 @@
     """
     This class sets up the GNUTranslations context with regard to output
     charset. Django uses a defined DEFAULT_CHARSET as the output charset on
-    Python 2.4. With Python 2.3, use DjangoTranslation23.
+    Python 2.4.
     """
     def __init__(self, *args, **kw):
         from django.conf import settings
@@ -83,23 +83,6 @@
     def __repr__(self):
         return "<DjangoTranslation lang:%s>" % self.__language
 
-class DjangoTranslation23(DjangoTranslation):
-    """
-    Compatibility class that is only used with Python 2.3.
-    Python 2.3 doesn't support set_output_charset on translation objects and
-    needs this wrapper class to make sure input charsets from translation files
-    are correctly translated to output charsets.
-
-    With a full switch to Python 2.4, this can be removed from the source.
-    """
-    def gettext(self, msgid):
-        res = self.ugettext(msgid)
-        return res.encode(self.django_output_charset)
-
-    def ngettext(self, msgid1, msgid2, n):
-        res = self.ungettext(msgid1, msgid2, n)
-        return res.encode(self.django_output_charset)
-
 def translation(language):
     """
     Returns a translation object.
@@ -119,8 +102,6 @@
 
     # set up the right translation class
     klass = DjangoTranslation
-    if sys.version_info < (2, 4):
-        klass = DjangoTranslation23
 
     globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
 
Index: django/utils/functional.py
===================================================================
--- django/utils/functional.py	(revision 11723)
+++ django/utils/functional.py	(working copy)
@@ -60,9 +60,6 @@
 # Summary of changes made to the Python 2.5 code below:
 #   * swapped ``partial`` for ``curry`` to maintain backwards-compatibility
 #     in Django.
-#   * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except
-#     block to make it compatible with Python 2.3, which doesn't allow
-#     assigning to ``__name__``.
 
 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation.
 # All Rights Reserved.
@@ -90,10 +87,7 @@
        function (defaults to functools.WRAPPER_UPDATES)
     """
     for attr in assigned:
-        try:
-            setattr(wrapper, attr, getattr(wrapped, attr))
-        except TypeError: # Python 2.3 doesn't allow assigning to __name__.
-            pass
+        setattr(wrapper, attr, getattr(wrapped, attr))
     for attr in updated:
         getattr(wrapper, attr).update(getattr(wrapped, attr))
     # Return the wrapper so this can be used as a decorator via curry()
Index: django/utils/cache.py
===================================================================
--- django/utils/cache.py	(revision 11723)
+++ django/utils/cache.py	(working copy)
@@ -19,10 +19,6 @@
 
 import re
 import time
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
 
 from django.conf import settings
 from django.core.cache import cache
Index: django/utils/decorators.py
===================================================================
--- django/utils/decorators.py	(revision 11723)
+++ django/utils/decorators.py	(working copy)
@@ -4,7 +4,7 @@
 try:
     from functools import wraps, update_wrapper
 except ImportError:
-    from django.utils.functional import wraps, update_wrapper  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps, update_wrapper  # Python 2.4 fallback.
 
 
 # Licence for MethodDecoratorAdaptor and auto_adapt_to_methods
Index: django/utils/encoding.py
===================================================================
--- django/utils/encoding.py	(revision 11723)
+++ django/utils/encoding.py	(working copy)
@@ -6,12 +6,6 @@
 
 from django.utils.functional import Promise
 
-try:
-    from decimal import Decimal
-except ImportError:
-    from django.utils._decimal import Decimal # Python 2.3 fallback
-
-
 class DjangoUnicodeDecodeError(UnicodeDecodeError):
     def __init__(self, obj, *args):
         self.obj = obj
Index: django/contrib/formtools/utils.py
===================================================================
--- django/contrib/formtools/utils.py	(revision 11723)
+++ django/contrib/formtools/utils.py	(working copy)
@@ -32,7 +32,7 @@
     data.append(settings.SECRET_KEY)
 
     # Use HIGHEST_PROTOCOL because it's the most efficient. It requires
-    # Python 2.3, but Django requires 2.3 anyway, so that's OK.
+    # Python 2.3, but Django requires 2.4 anyway, so that's OK.
     pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
 
     return md5_constructor(pickled).hexdigest()
Index: django/contrib/admin/validation.py
===================================================================
--- django/contrib/admin/validation.py	(revision 11723)
+++ django/contrib/admin/validation.py	(working copy)
@@ -1,8 +1,3 @@
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
 from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model, _get_foreign_key
Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 11723)
+++ django/contrib/admin/options.py	(working copy)
@@ -21,10 +21,6 @@
 from django.utils.translation import ugettext as _
 from django.utils.translation import ungettext, ugettext_lazy
 from django.utils.encoding import force_unicode
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
 
 HORIZONTAL, VERTICAL = 1, 2
 # returns the <ul> class for a given radio_admin field
Index: django/contrib/admin/actions.py
===================================================================
--- django/contrib/admin/actions.py	(revision 11723)
+++ django/contrib/admin/actions.py	(working copy)
@@ -12,10 +12,6 @@
 from django.utils.safestring import mark_safe
 from django.utils.text import capfirst
 from django.utils.translation import ugettext_lazy, ugettext as _
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
 
 def delete_selected(modeladmin, request, queryset):
     """
Index: django/contrib/admin/views/main.py
===================================================================
--- django/contrib/admin/views/main.py	(revision 11723)
+++ django/contrib/admin/views/main.py	(working copy)
@@ -9,11 +9,6 @@
 from django.utils.http import urlencode
 import operator
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 # The system will display a "Show all" link on the change list only if the
 # total result count is less than or equal to this setting.
 MAX_SHOW_ALL_ALLOWED = 200
Index: django/contrib/admin/views/decorators.py
===================================================================
--- django/contrib/admin/views/decorators.py	(revision 11723)
+++ django/contrib/admin/views/decorators.py	(working copy)
@@ -2,7 +2,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from django import http, template
 from django.conf import settings
Index: django/contrib/admin/sites.py
===================================================================
--- django/contrib/admin/sites.py	(revision 11723)
+++ django/contrib/admin/sites.py	(working copy)
@@ -14,10 +14,6 @@
 from django.utils.translation import ugettext_lazy, ugettext as _
 from django.views.decorators.cache import never_cache
 from django.conf import settings
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
 
 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
 LOGIN_FORM_KEY = 'this_is_the_login_form'
Index: django/contrib/auth/decorators.py
===================================================================
--- django/contrib/auth/decorators.py	(revision 11723)
+++ django/contrib/auth/decorators.py	(working copy)
@@ -1,7 +1,7 @@
 try:
     from functools import update_wrapper, wraps
 except ImportError:
-    from django.utils.functional import update_wrapper, wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import update_wrapper, wraps  # Python 2.4 fallback.
 
 from django.contrib.auth import REDIRECT_FIELD_NAME
 from django.http import HttpResponseRedirect
Index: django/contrib/auth/backends.py
===================================================================
--- django/contrib/auth/backends.py	(revision 11723)
+++ django/contrib/auth/backends.py	(working copy)
@@ -1,12 +1,6 @@
-try:
-    set
-except NameError:
-    from sets import Set as set # Python 2.3 fallback
-
 from django.db import connection
 from django.contrib.auth.models import User
 
-
 class ModelBackend(object):
     """
     Authenticates against django.contrib.auth.models.User.
Index: django/contrib/auth/models.py
===================================================================
--- django/contrib/auth/models.py	(revision 11723)
+++ django/contrib/auth/models.py	(working copy)
@@ -12,11 +12,6 @@
 
 UNUSABLE_PASSWORD = '!' # This will never be a valid hash
 
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
-
 def get_hexdigest(algorithm, salt, raw_password):
     """
     Returns a string of the hexdigest of the given plaintext password and salt
Index: django/contrib/localflavor/br/forms.py
===================================================================
--- django/contrib/localflavor/br/forms.py	(revision 11723)
+++ django/contrib/localflavor/br/forms.py	(working copy)
@@ -9,11 +9,6 @@
 from django.utils.translation import ugettext_lazy as _
 import re
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # For Python 2.3
-
 phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
 
 class BRZipCodeField(RegexField):
Index: django/template/defaultfilters.py
===================================================================
--- django/template/defaultfilters.py	(revision 11723)
+++ django/template/defaultfilters.py	(working copy)
@@ -11,7 +11,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from django.template import Variable, Library
 from django.conf import settings
Index: django/template/defaulttags.py
===================================================================
--- django/template/defaulttags.py	(revision 11723)
+++ django/template/defaulttags.py	(working copy)
@@ -3,10 +3,6 @@
 import sys
 import re
 from itertools import cycle as itertools_cycle
-try:
-    reversed
-except NameError:
-    from django.utils.itercompat import reversed     # Python 2.3 fallback
 
 from django.template import Node, NodeList, Template, Context, Variable
 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
Index: tests/modeltests/basic/models.py
===================================================================
--- tests/modeltests/basic/models.py	(revision 11723)
+++ tests/modeltests/basic/models.py	(working copy)
@@ -4,18 +4,7 @@
 
 This is a basic model with only two non-primary-key fields.
 """
-# Python 2.3 doesn't have set as a builtin
-try:
-    set
-except NameError:
-    from sets import Set as set
 
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
-
 from django.db import models
 
 class Article(models.Model):
Index: tests/modeltests/or_lookups/models.py
===================================================================
--- tests/modeltests/or_lookups/models.py	(revision 11723)
+++ tests/modeltests/or_lookups/models.py	(working copy)
@@ -8,11 +8,6 @@
 clauses using the variable ``django.db.models.Q`` (or any object with an
 ``add_to_query`` method).
 """
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
 
 from django.db import models
 
Index: tests/modeltests/aggregation/models.py
===================================================================
--- tests/modeltests/aggregation/models.py	(revision 11723)
+++ tests/modeltests/aggregation/models.py	(working copy)
@@ -1,11 +1,6 @@
 # coding: utf-8
 from django.db import models
 
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted      # For Python 2.3
-
 class Author(models.Model):
     name = models.CharField(max_length=100)
     age = models.IntegerField()
Index: tests/modeltests/serializers/models.py
===================================================================
--- tests/modeltests/serializers/models.py	(revision 11723)
+++ tests/modeltests/serializers/models.py	(working copy)
@@ -6,11 +6,6 @@
 ``QuerySet`` objects to and from "flat" data (i.e. strings).
 """
 
-try:
-    from decimal import Decimal
-except ImportError:
-    from django.utils._decimal import Decimal # Python 2.3 fallback
-
 from django.db import models
 
 class Category(models.Model):
Index: tests/modeltests/model_forms/models.py
===================================================================
--- tests/modeltests/model_forms/models.py	(revision 11723)
+++ tests/modeltests/model_forms/models.py	(working copy)
@@ -13,12 +13,6 @@
 from django.db import models
 from django.core.files.storage import FileSystemStorage
 
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
-
 temp_storage_dir = tempfile.mkdtemp()
 temp_storage = FileSystemStorage(temp_storage_dir)
 
Index: tests/regressiontests/model_inheritance_regress/models.py
===================================================================
--- tests/regressiontests/model_inheritance_regress/models.py	(revision 11723)
+++ tests/regressiontests/model_inheritance_regress/models.py	(working copy)
@@ -6,12 +6,6 @@
 
 from django.db import models
 
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
-
 class Place(models.Model):
     name = models.CharField(max_length=50)
     address = models.CharField(max_length=80)
Index: tests/regressiontests/defaultfilters/tests.py
===================================================================
--- tests/regressiontests/defaultfilters/tests.py	(revision 11723)
+++ tests/regressiontests/defaultfilters/tests.py	(working copy)
@@ -571,12 +571,6 @@
 from django.template.defaultfilters import *
 import datetime
 
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
-
 if __name__ == '__main__':
     import doctest
     doctest.testmod()
Index: tests/regressiontests/aggregation_regress/models.py
===================================================================
--- tests/regressiontests/aggregation_regress/models.py	(revision 11723)
+++ tests/regressiontests/aggregation_regress/models.py	(working copy)
@@ -4,11 +4,6 @@
 from django.db import connection, models
 from django.conf import settings
 
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted      # For Python 2.3
-
 class Author(models.Model):
     name = models.CharField(max_length=100)
     age = models.IntegerField()
Index: tests/regressiontests/decorators/tests.py
===================================================================
--- tests/regressiontests/decorators/tests.py	(revision 11723)
+++ tests/regressiontests/decorators/tests.py	(working copy)
@@ -3,7 +3,7 @@
 try:
     from functools import wraps
 except ImportError:
-    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import wraps  # Python 2.4 fallback.
 
 from django.http import HttpResponse, HttpRequest
 from django.utils.functional import allow_lazy, lazy, memoize
Index: tests/regressiontests/i18n/misc.py
===================================================================
--- tests/regressiontests/i18n/misc.py	(revision 11723)
+++ tests/regressiontests/i18n/misc.py	(working copy)
@@ -87,7 +87,7 @@
 'es-ar'
 """
 
-# Python 2.3 and 2.4 return slightly different results for completely bogus
+# Python 2.4 returns slightly different results for completely bogus
 # locales, so we omit this test for that anything below 2.4. It's relatively
 # harmless in any cases (GIGO). This also means this won't be executed on
 # Jython currently, but life's like that sometimes. (On those platforms,
Index: tests/regressiontests/model_fields/models.py
===================================================================
--- tests/regressiontests/model_fields/models.py	(revision 11723)
+++ tests/regressiontests/model_fields/models.py	(working copy)
@@ -2,11 +2,6 @@
 import tempfile
 
 try:
-    import decimal
-except ImportError:
-    from django.utils import _decimal as decimal    # Python 2.3 fallback
-
-try:
     # Checking for the existence of Image is enough for CPython, but for PyPy,
     # you need to check for the underlying modules.
     from PIL import Image, _imaging
Index: tests/regressiontests/auth_backends/tests.py
===================================================================
--- tests/regressiontests/auth_backends/tests.py	(revision 11723)
+++ tests/regressiontests/auth_backends/tests.py	(working copy)
@@ -1,8 +1,3 @@
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
-
 __test__ = {'API_TESTS': """
 >>> from django.contrib.auth.models import User, Group, Permission, AnonymousUser
 >>> from django.contrib.contenttypes.models import ContentType
Index: tests/regressiontests/admin_scripts/management/commands/base_command.py
===================================================================
--- tests/regressiontests/admin_scripts/management/commands/base_command.py	(revision 11723)
+++ tests/regressiontests/admin_scripts/management/commands/base_command.py	(working copy)
@@ -1,10 +1,5 @@
 from django.core.management.base import BaseCommand
 from optparse import make_option
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
 
 class Command(BaseCommand):
     option_list = BaseCommand.option_list + (
Index: tests/regressiontests/admin_scripts/management/commands/label_command.py
===================================================================
--- tests/regressiontests/admin_scripts/management/commands/label_command.py	(revision 11723)
+++ tests/regressiontests/admin_scripts/management/commands/label_command.py	(working copy)
@@ -1,9 +1,4 @@
 from django.core.management.base import LabelCommand
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
 
 class Command(LabelCommand):
     help = "Test Label-based commands"
Index: tests/regressiontests/admin_scripts/management/commands/app_command.py
===================================================================
--- tests/regressiontests/admin_scripts/management/commands/app_command.py	(revision 11723)
+++ tests/regressiontests/admin_scripts/management/commands/app_command.py	(working copy)
@@ -1,9 +1,4 @@
 from django.core.management.base import AppCommand
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
 
 class Command(AppCommand):
     help = 'Test Application-based commands'
Index: tests/regressiontests/admin_scripts/management/commands/noargs_command.py
===================================================================
--- tests/regressiontests/admin_scripts/management/commands/noargs_command.py	(revision 11723)
+++ tests/regressiontests/admin_scripts/management/commands/noargs_command.py	(working copy)
@@ -1,9 +1,4 @@
 from django.core.management.base import NoArgsCommand
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
 
 class Command(NoArgsCommand):
     help = "Test No-args commands"
Index: tests/regressiontests/utils/tests.py
===================================================================
--- tests/regressiontests/utils/tests.py	(revision 11723)
+++ tests/regressiontests/utils/tests.py	(working copy)
@@ -13,13 +13,6 @@
 import itercompat
 from decorators import DecoratorFromMiddlewareTests
 
-# We need this because "datastructures" uses sorted() and the tests are run in
-# the scope of this module.
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted  # For Python 2.3
-
 # Extra tests
 __test__ = {
     'timesince': timesince,
Index: tests/regressiontests/introspection/tests.py
===================================================================
--- tests/regressiontests/introspection/tests.py	(revision 11723)
+++ tests/regressiontests/introspection/tests.py	(working copy)
@@ -5,11 +5,6 @@
 
 from models import Reporter, Article
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # Python 2.3 fallback
-
 #
 # The introspection module is optional, so methods tested here might raise
 # NotImplementedError. This is perfectly acceptable behavior for the backend
Index: tests/regressiontests/queries/models.py
===================================================================
--- tests/regressiontests/queries/models.py	(revision 11723)
+++ tests/regressiontests/queries/models.py	(working copy)
@@ -10,12 +10,6 @@
 from django.db import models
 from django.db.models.query import Q, ITER_CHUNK_SIZE
 
-# Python 2.3 doesn't have sorted()
-try:
-    sorted
-except NameError:
-    from django.utils.itercompat import sorted
-
 class DumbCategory(models.Model):
     pass
 
@@ -1178,12 +1172,12 @@
 
 """}
 
-# In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__
+# In Python 2.6 beta releases, exceptions raised in __len__
 # are swallowed (Python issue 1242657), so these cases return an empty list,
 # rather than raising an exception. Not a lot we can do about that,
 # unfortunately, due to the way Python handles list() calls internally. Thus,
-# we skip the tests for Python 2.3 and 2.6.
-if (2, 4) <= sys.version_info < (2, 6):
+# we skip the tests for Python 2.6.
+if sys.version_info < (2, 6):
     __test__["API_TESTS"] += """
 # If you're not careful, it's possible to introduce infinite loops via default
 # ordering on foreign keys in a cycle. We detect that.
Index: tests/runtests.py
===================================================================
--- tests/runtests.py	(revision 11723)
+++ tests/runtests.py	(working copy)
@@ -5,12 +5,6 @@
 
 import django.contrib as contrib
 
-try:
-    set
-except NameError:
-    from sets import Set as set     # For Python 2.3
-
-
 CONTRIB_DIR_NAME = 'django.contrib'
 MODEL_TESTS_DIR_NAME = 'modeltests'
 REGRESSION_TESTS_DIR_NAME = 'regressiontests'
