Ticket #15702: 24boilerplate.patch

File 24boilerplate.patch, 63.2 KB (added by Jonas H., 13 years ago)
  • django/contrib/admin/options.py

    commit 4f8cadfe507ff58f3326abf0d7e1abe9835910f5
    Author: Jonas Haag <jonas@lophus.org>
    Date:   Sun Mar 27 05:44:35 2011 -0700
    
        Drop some 2.4 compatibility boilerplate code
    
    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 43c5503..fbda8b7 100644
    a b  
     1from functools import update_wrapper, partial
    12from django import forms, template
    23from django.forms.formsets import all_valid
    34from django.forms.models import (modelform_factory, modelformset_factory,
    from django.http import Http404, HttpResponse, HttpResponseRedirect  
    1718from django.shortcuts import get_object_or_404, render_to_response
    1819from django.utils.decorators import method_decorator
    1920from django.utils.datastructures import SortedDict
    20 from django.utils.functional import update_wrapper
    2121from django.utils.html import escape, escapejs
    2222from django.utils.safestring import mark_safe
    23 from django.utils.functional import curry
    2423from django.utils.text import capfirst, get_text_list
    2524from django.utils.translation import ugettext as _
    2625from django.utils.translation import ungettext
    class ModelAdmin(BaseModelAdmin):  
    426425            "form": self.form,
    427426            "fields": fields,
    428427            "exclude": exclude,
    429             "formfield_callback": curry(self.formfield_for_dbfield, request=request),
     428            "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    430429        }
    431430        defaults.update(kwargs)
    432431        return modelform_factory(self.model, **defaults)
    class ModelAdmin(BaseModelAdmin):  
    457456        Returns a Form class for use in the Formset on the changelist page.
    458457        """
    459458        defaults = {
    460             "formfield_callback": curry(self.formfield_for_dbfield, request=request),
     459            "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    461460        }
    462461        defaults.update(kwargs)
    463462        return modelform_factory(self.model, **defaults)
    class ModelAdmin(BaseModelAdmin):  
    468467        is used.
    469468        """
    470469        defaults = {
    471             "formfield_callback": curry(self.formfield_for_dbfield, request=request),
     470            "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    472471        }
    473472        defaults.update(kwargs)
    474473        return modelformset_factory(self.model,
    class InlineModelAdmin(BaseModelAdmin):  
    13271326            "fk_name": self.fk_name,
    13281327            "fields": fields,
    13291328            "exclude": exclude,
    1330             "formfield_callback": curry(self.formfield_for_dbfield, request=request),
     1329            "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    13311330            "extra": self.extra,
    13321331            "max_num": self.max_num,
    13331332            "can_delete": self.can_delete,
  • django/contrib/admin/sites.py

    diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
    index b03bce4..1f98db8 100644
    a b  
    11import re
     2from functools import update_wrapper
    23from django import http, template
    34from django.contrib.admin import ModelAdmin, actions
    45from django.contrib.admin.forms import AdminAuthenticationForm
    from django.db.models.base import ModelBase  
    910from django.core.exceptions import ImproperlyConfigured
    1011from django.core.urlresolvers import reverse
    1112from django.shortcuts import render_to_response
    12 from django.utils.functional import update_wrapper
    1313from django.utils.safestring import mark_safe
    1414from django.utils.text import capfirst
    1515from django.utils.translation import ugettext as _
  • django/contrib/admin/views/decorators.py

    diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py
    index 9088eb0..34b54e0 100644
    a b  
    1 try:
    2     from functools import wraps
    3 except ImportError:
    4     from django.utils.functional import wraps  # Python 2.4 fallback.
     1from functools import wraps
    52
    63from django.utils.translation import ugettext as _
    74from django.contrib.admin.forms import AdminAuthenticationForm
  • django/contrib/admin/widgets.py

    diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
    index 1978b3e..5d3ef23 100644
    a b  
    22Form Widget classes specific to the Django admin site.
    33"""
    44
    5 import django.utils.copycompat as copy
     5import copy
    66
    77from django import forms
    88from django.forms.widgets import RadioFieldRenderer
  • django/contrib/auth/decorators.py

    diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py
    index 64b77a5..2e16c99 100644
    a b  
    11import urlparse
    2 try:
    3     from functools import wraps
    4 except ImportError:
    5     from django.utils.functional import wraps  # Python 2.4 fallback.
     2from functools import wraps
    63
    74from django.conf import settings
    85from django.contrib.auth import REDIRECT_FIELD_NAME
  • django/contrib/auth/models.py

    diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
    index 8fcbdef..c17291f 100644
    a b  
    11import datetime
    22import urllib
     3from hashlib import sha1, md5
    34
    45from django.contrib import auth
    56from django.contrib.auth.signals import user_logged_in
    from django.db import models  
    89from django.db.models.manager import EmptyManager
    910from django.contrib.contenttypes.models import ContentType
    1011from django.utils.encoding import smart_str
    11 from django.utils.hashcompat import md5_constructor, sha_constructor
    1212from django.utils.translation import ugettext_lazy as _
    1313from django.utils.crypto import constant_time_compare
    1414
    def get_hexdigest(algorithm, salt, raw_password):  
    2929        return crypt.crypt(raw_password, salt)
    3030
    3131    if algorithm == 'md5':
    32         return md5_constructor(salt + raw_password).hexdigest()
     32        return md5(salt + raw_password).hexdigest()
    3333    elif algorithm == 'sha1':
    34         return sha_constructor(salt + raw_password).hexdigest()
     34        return sha1(salt + raw_password).hexdigest()
    3535    raise ValueError("Got unknown password algorithm type in password.")
    3636
    3737def check_password(raw_password, enc_password):
  • django/contrib/auth/tests/tokens.py

    diff --git a/django/contrib/auth/tests/tokens.py b/django/contrib/auth/tests/tokens.py
    index 20b2ecb..e96ce59 100644
    a b class TokenGeneratorTest(TestCase):  
    5858        # Hard code in the Django 1.2 algorithm (not the result, as it is time
    5959        # dependent)
    6060        def _make_token(user):
    61             from django.utils.hashcompat import sha_constructor
     61            from hashlib import sha1
    6262            from django.utils.http import int_to_base36
    6363
    6464            timestamp = (date.today() - date(2001,1,1)).days
    6565            ts_b36 = int_to_base36(timestamp)
    66             hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
    67                                    user.password + user.last_login.strftime('%Y-%m-%d %H:%M:%S') +
    68                                    unicode(timestamp)).hexdigest()[::2]
     66            hash = sha1(settings.SECRET_KEY + unicode(user.id) +
     67                        user.password + user.last_login.strftime('%Y-%m-%d %H:%M:%S') +
     68                        unicode(timestamp)).hexdigest()[::2]
    6969            return "%s-%s" % (ts_b36, hash)
    7070
    7171        user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
  • django/contrib/auth/tokens.py

    diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py
    index f03ed0c..0150afc 100644
    a b  
    11from datetime import date
     2from hashlib import sha1
    23
    34from django.conf import settings
    4 from django.utils.hashcompat import sha_constructor
    55from django.utils.http import int_to_base36, base36_to_int
    66from django.utils.crypto import constant_time_compare, salted_hmac
    77
    class PasswordResetTokenGenerator(object):  
    6767    def _make_token_with_timestamp_old(self, user, timestamp):
    6868        # The Django 1.2 method
    6969        ts_b36 = int_to_base36(timestamp)
    70         hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
    71                                user.password + user.last_login.strftime('%Y-%m-%d %H:%M:%S') +
    72                                unicode(timestamp)).hexdigest()[::2]
     70        hash = sha1(settings.SECRET_KEY + unicode(user.id) +
     71                    user.password + user.last_login.strftime('%Y-%m-%d %H:%M:%S') +
     72                    unicode(timestamp)).hexdigest()[::2]
    7373        return "%s-%s" % (ts_b36, hash)
    7474
    7575    def _num_days(self, dt):
  • django/contrib/comments/forms.py

    diff --git a/django/contrib/comments/forms.py b/django/contrib/comments/forms.py
    index 4ecc4c4..6d2be4f 100644
    a b  
    11import time
    22import datetime
     3from hashlib import sha1
    34
    45from django import forms
    56from django.forms.util import ErrorDict
    from django.contrib.contenttypes.models import ContentType  
    89from models import Comment
    910from django.utils.crypto import salted_hmac, constant_time_compare
    1011from django.utils.encoding import force_unicode
    11 from django.utils.hashcompat import sha_constructor
    1212from django.utils.text import get_text_list
    1313from django.utils.translation import ungettext, ugettext_lazy as _
    1414
    class CommentSecurityForm(forms.Form):  
    100100        """Generate a (SHA1) security hash from the provided info."""
    101101        # Django 1.2 compatibility
    102102        info = (content_type, object_pk, timestamp, settings.SECRET_KEY)
    103         return sha_constructor("".join(info)).hexdigest()
     103        return sha1("".join(info)).hexdigest()
    104104
    105105class CommentDetailsForm(CommentSecurityForm):
    106106    """
  • django/contrib/contenttypes/generic.py

    diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py
    index 76f8eaf..62cf016 100644
    a b  
    22Classes allowing "generic" relations through ContentType and object-id fields.
    33"""
    44
     5from functools import partial
     6
    57from django.core.exceptions import ObjectDoesNotExist
    68from django.db import connection
    79from django.db.models import signals
    from django.forms import ModelForm  
    1214from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance
    1315from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets
    1416from django.utils.encoding import smart_unicode
    15 from django.utils.functional import curry
    1617
    1718from django.contrib.contenttypes.models import ContentType
    1819
    class GenericInlineModelAdmin(InlineModelAdmin):  
    414415            "ct_field": self.ct_field,
    415416            "fk_field": self.ct_fk_field,
    416417            "form": self.form,
    417             "formfield_callback": curry(self.formfield_for_dbfield, request=request),
     418            "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    418419            "formset": self.formset,
    419420            "extra": self.extra,
    420421            "can_delete": self.can_delete,
  • django/contrib/formtools/preview.py

    diff --git a/django/contrib/formtools/preview.py b/django/contrib/formtools/preview.py
    index 3fa61ba..3f0674c 100644
    a b  
    11"""
    22Formtools Preview application.
    33"""
    4 
    5 import cPickle as pickle
     4try:
     5    import cPickle as pickle
     6except ImportError:
     7    import pickle
    68
    79from django.conf import settings
    810from django.http import Http404
    911from django.shortcuts import render_to_response
    1012from django.template.context import RequestContext
    11 from django.utils.hashcompat import md5_constructor
    1213from django.utils.crypto import constant_time_compare
    1314from django.contrib.formtools.utils import security_hash
    1415
  • django/contrib/formtools/utils.py

    diff --git a/django/contrib/formtools/utils.py b/django/contrib/formtools/utils.py
    index 894178a..6374f39 100644
    a b  
     1from hashlib import md5
    12try:
    23    import cPickle as pickle
    34except ImportError:
    except ImportError:  
    67from django.conf import settings
    78from django.forms import BooleanField
    89from django.utils.crypto import salted_hmac
    9 from django.utils.hashcompat import md5_constructor
    1010
    1111
    1212def security_hash(request, form, *args):
    def security_hash(request, form, *args):  
    3939    # Python 2.3, but Django requires 2.4 anyway, so that's OK.
    4040    pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
    4141
    42     return md5_constructor(pickled).hexdigest()
     42    return md5(pickled).hexdigest()
    4343
    4444
    4545def form_hmac(form):
  • django/contrib/formtools/wizard.py

    diff --git a/django/contrib/formtools/wizard.py b/django/contrib/formtools/wizard.py
    index 6f3660d..9096250 100644
    a b FormWizard class -- implements a multi-page form, validating between each  
    33step and storing the form's state as HTML hidden fields so that no state is
    44stored on the server side.
    55"""
    6 
    7 import cPickle as pickle
     6try:
     7    import cPickle as pickle
     8except ImportError:
     9    import pickle
    810
    911from django import forms
    1012from django.conf import settings
    from django.http import Http404  
    1315from django.shortcuts import render_to_response
    1416from django.template.context import RequestContext
    1517from django.utils.crypto import constant_time_compare
    16 from django.utils.hashcompat import md5_constructor
    1718from django.utils.translation import ugettext_lazy as _
    1819from django.utils.decorators import method_decorator
    1920from django.views.decorators.csrf import csrf_protect
  • django/contrib/gis/geos/tests/test_geos.py

    diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py
    index 8342b58..4620a9f 100644
    a b class GEOSTest(unittest.TestCase, TestDataMixin):  
    820820
    821821    def test22_copy(self):
    822822        "Testing use with the Python `copy` module."
    823         import django.utils.copycompat as copy
     823        import copy
    824824        poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))')
    825825        cpy1 = copy.copy(poly)
    826826        cpy2 = copy.deepcopy(poly)
  • django/contrib/gis/geos/tests/test_geos_mutation.py

    diff --git a/django/contrib/gis/geos/tests/test_geos_mutation.py b/django/contrib/gis/geos/tests/test_geos_mutation.py
    index 266a12d..cf0c6bf 100644
    a b  
    22# Modified from original contribution by Aryeh Leib Taurog, which was
    33# released under the New BSD license.
    44
    5 import django.utils.copycompat as copy
     5import copy
    66
    77from django.contrib.gis.geos import *
    88from django.contrib.gis.geos.error import GEOSIndexError
  • django/contrib/gis/tests/layermap/tests.py

    diff --git a/django/contrib/gis/tests/layermap/tests.py b/django/contrib/gis/tests/layermap/tests.py
    index ad7a504..dd9ff5c 100644
    a b  
    11import os
     2import copy
    23from decimal import Decimal
    34
    4 from django.utils.copycompat import copy
    55from django.utils.unittest import TestCase
    66
    77from django.contrib.gis.gdal import DataSource, OGRException
  • django/contrib/sessions/backends/base.py

    diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
    index bb09cb6..6983a16 100644
    a b import os  
    33import random
    44import sys
    55import time
     6from hashlib import md5
    67from datetime import datetime, timedelta
    78try:
    89    import cPickle as pickle
    except ImportError:  
    1112
    1213from django.conf import settings
    1314from django.core.exceptions import SuspiciousOperation
    14 from django.utils.hashcompat import md5_constructor
    1515from django.utils.crypto import constant_time_compare, salted_hmac
    1616
    1717# Use the system (hardware-based) random number generator if it exists.
    class SessionBase(object):  
    119119    def _decode_old(self, session_data):
    120120        encoded_data = base64.decodestring(session_data)
    121121        pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
    122         if not constant_time_compare(md5_constructor(pickled + settings.SECRET_KEY).hexdigest(),
     122        if not constant_time_compare(md5(pickled + settings.SECRET_KEY).hexdigest(),
    123123                                     tamper_check):
    124124            raise SuspiciousOperation("User tampered with session cookie.")
    125125        return pickle.loads(pickled)
    class SessionBase(object):  
    161161            # No getpid() in Jython, for example
    162162            pid = 1
    163163        while 1:
    164             session_key = md5_constructor("%s%s%s%s"
     164            session_key = md5("%s%s%s%s"
    165165                    % (randrange(0, MAX_SESSION_KEY), pid, time.time(),
    166166                       settings.SECRET_KEY)).hexdigest()
    167167            if not self.exists(session_key):
  • django/contrib/sessions/tests.py

    diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
    index afdb761..5e5fa27 100644
    a b  
    11import base64
    2 from datetime import datetime, timedelta
    32import pickle
    43import shutil
    54import tempfile
     5from hashlib import md5
     6from datetime import datetime, timedelta
    67
    78from django.conf import settings
    89from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
    from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation  
    1516from django.http import HttpResponse
    1617from django.test import TestCase, RequestFactory
    1718from django.utils import unittest
    18 from django.utils.hashcompat import md5_constructor
    1919
    2020
    2121class SessionTestsMixin(object):
    class SessionTestsMixin(object):  
    257257        # Hard code the Django 1.2 method here:
    258258        def encode(session_dict):
    259259            pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
    260             pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
     260            pickled_md5 = md5(pickled + settings.SECRET_KEY).hexdigest()
    261261            return base64.encodestring(pickled + pickled_md5)
    262262
    263263        data = {'a test key': 'a test value'}
  • django/core/cache/backends/filebased.py

    diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
    index b75d636..3a0cde3 100644
    a b  
    33import os
    44import time
    55import shutil
     6from hashlib import md5
    67try:
    78    import cPickle as pickle
    89except ImportError:
    910    import pickle
    1011
    1112from django.core.cache.backends.base import BaseCache
    12 from django.utils.hashcompat import md5_constructor
    1313
    1414class FileBasedCache(BaseCache):
    1515    def __init__(self, dir, params):
    class FileBasedCache(BaseCache):  
    145145        Thus, a cache key of "foo" gets turnned into a file named
    146146        ``{cache-dir}ac/bd/18db4cc2f85cedef654fccc4a4d8``.
    147147        """
    148         path = md5_constructor(key).hexdigest()
     148        path = md5(key).hexdigest()
    149149        path = os.path.join(path[:2], path[2:4], path[4:])
    150150        return os.path.join(self._dir, path)
    151151
  • django/core/cache/backends/locmem.py

    diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py
    index ecec875..fa3b4b7 100644
    a b class LocMemCache(BaseCache):  
    7777        key = self.make_key(key, version=version)
    7878        self.validate_key(key)
    7979        self._lock.writer_enters()
    80         # Python 2.4 doesn't allow combined try-except-finally blocks.
    8180        try:
    82             try:
    83                 self._set(key, pickle.dumps(value), timeout)
    84             except pickle.PickleError:
    85                 pass
     81            self._set(key, pickle.dumps(value), timeout)
     82        except pickle.PickleError:
     83            pass
    8684        finally:
    8785            self._lock.writer_leaves()
    8886
  • django/core/mail/backends/console.py

    diff --git a/django/core/mail/backends/console.py b/django/core/mail/backends/console.py
    index fa71f38..7054975 100644
    a b class EmailBackend(BaseEmailBackend):  
    1818            return
    1919        self._lock.acquire()
    2020        try:
    21             # The try-except is nested to allow for
    22             # Python 2.4 support (Refs #12147)
    23             try:
    24                 stream_created = self.open()
    25                 for message in email_messages:
    26                     self.stream.write('%s\n' % message.message().as_string())
    27                     self.stream.write('-'*79)
    28                     self.stream.write('\n')
    29                     self.stream.flush()  # flush after each message
    30                 if stream_created:
    31                     self.close()
    32             except:
    33                 if not self.fail_silently:
    34                     raise
     21            stream_created = self.open()
     22            for message in email_messages:
     23                self.stream.write('%s\n' % message.message().as_string())
     24                self.stream.write('-'*79)
     25                self.stream.write('\n')
     26                self.stream.flush()  # flush after each message
     27            if stream_created:
     28                self.close()
     29        except:
     30            if not self.fail_silently:
     31                raise
    3532        finally:
    3633            self._lock.release()
    3734        return len(email_messages)
  • django/core/mail/message.py

    diff --git a/django/core/mail/message.py b/django/core/mail/message.py
    index 01bb1d6..bed4966 100644
    a b import os  
    33import random
    44import time
    55from email import Charset, Encoders
    6 try:
    7     from email.generator import Generator
    8 except ImportError:
    9     from email.Generator import Generator # TODO: Remove when remove Python 2.4 support
     6from email.generator import Generator
    107from email.MIMEText import MIMEText
    118from email.MIMEMultipart import MIMEMultipart
    129from email.MIMEBase import MIMEBase
  • django/core/management/validation.py

    diff --git a/django/core/management/validation.py b/django/core/management/validation.py
    index 2eb6340..bb4fa55 100644
    a b from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelati  
    44from django.core.management.color import color_style
    55from django.utils.itercompat import is_iterable
    66
    7 try:
    8     any
    9 except NameError:
    10     from django.utils.itercompat import any
    11 
    127class ModelErrorCollection:
    138    def __init__(self, outfile=sys.stdout):
    149        self.errors = []
  • django/db/__init__.py

    diff --git a/django/db/__init__.py b/django/db/__init__.py
    index 3f9645a..d39e7db 100644
    a b  
     1from functools import partial
     2
    13from django.conf import settings
    24from django.core import signals
    35from django.core.exceptions import ImproperlyConfigured
    46from django.db.utils import ConnectionHandler, ConnectionRouter, load_backend, DEFAULT_DB_ALIAS, \
    57                            DatabaseError, IntegrityError
    6 from django.utils.functional import curry
    78
    89__all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
    910    'IntegrityError', 'DEFAULT_DB_ALIAS')
  • django/db/backends/util.py

    diff --git a/django/db/backends/util.py b/django/db/backends/util.py
    index 2f92a30..bf62236 100644
    a b  
    11import datetime
    22import decimal
    33from time import time
     4from hashlib import md5
    45
    5 from django.utils.hashcompat import md5_constructor
    66from django.utils.log import getLogger
    77
    88
    def truncate_name(name, length=None, hash_len=4):  
    130130    if length is None or len(name) <= length:
    131131        return name
    132132
    133     hash = md5_constructor(name).hexdigest()[:hash_len]
     133    hash = md5(name).hexdigest()[:hash_len]
    134134
    135135    return '%s%s' % (name[:length-hash_len], hash)
    136136
  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index 286f9b0..8267031 100644
    a b  
    11import types
    22import sys
     3import copy
    34from itertools import izip
     5from functools import update_wrapper
    46
    57import django.db.models.manager     # Imported to register signal handler.
    68from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS
    from django.db import (connections, router, transaction, DatabaseError,  
    1719from django.db.models import signals
    1820from django.db.models.loading import register_models, get_model
    1921from django.utils.translation import ugettext_lazy as _
    20 import django.utils.copycompat as copy
    21 from django.utils.functional import curry, update_wrapper
     22from django.utils.functional import curry
    2223from django.utils.encoding import smart_str, force_unicode
    2324from django.utils.text import get_text_list, capfirst
    2425from django.conf import settings
  • django/db/models/deletion.py

    diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
    index 73960f5..a52fa24 100644
    a b  
     1from functools import wraps
    12from operator import attrgetter
    23
    34from django.db import connections, transaction, IntegrityError
    45from django.db.models import signals, sql
    56from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE
    67from django.utils.datastructures import SortedDict
    7 from django.utils.functional import wraps
    88
    99
    1010class ProtectedError(IntegrityError):
    1111    def __init__(self, msg, protected_objects):
    1212        self.protected_objects = protected_objects
    13         # TODO change this to use super() when we drop Python 2.4
    14         IntegrityError.__init__(self, msg, protected_objects)
     13        super(ProtectedError, self).__init__(msg, protected_objects)
    1514
    1615
    1716def CASCADE(collector, field, sub_objs, using):
  • django/db/models/expressions.py

    diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
    index 8b9c934..400b7c7 100644
    a b  
    11import datetime
     2from copy import deepcopy
    23
    34from django.utils import tree
    4 from django.utils.copycompat import deepcopy
    55
    66class ExpressionNode(tree.Node):
    77    """
  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index 8081cf3..da52911 100644
    a b import decimal  
    33import re
    44import time
    55import math
     6import copy
    67from itertools import tee
    78
    8 import django.utils.copycompat as copy
    9 
    109from django.db import connection
    1110from django.db.models.fields.subclassing import LegacyConnection
    1211from django.db.models.query_utils import QueryWrapper
  • django/db/models/fields/files.py

    diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
    index aaf1fbb..50dc236 100644
    a b  
    11import datetime
    22import os
    33
    4 import django.utils.copycompat as copy
    5 
    64from django.conf import settings
    75from django.db.models.fields import Field
    86from django.core.files.base import File, ContentFile
  • django/db/models/fields/related.py

    diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
    index 1318706..6b609e4 100644
    a b  
     1from django.utils import datetime_safe
    12from django.conf import settings
    23from django.db import connection, router, transaction
    34from django.db.backends import util
  • django/db/models/manager.py

    diff --git a/django/db/models/manager.py b/django/db/models/manager.py
    index 6a62c25..9528d66 100644
    a b  
    1 from django.utils import copycompat as copy
     1import copy
    22from django.conf import settings
    33from django.db import router
    44from django.db.models.query import QuerySet, EmptyQuerySet, insert_query, RawQuerySet
  • django/db/models/options.py

    diff --git a/django/db/models/options.py b/django/db/models/options.py
    index 10617dc..6d8ab6f 100644
    a b from django.utils.translation import activate, deactivate_all, get_language, str  
    1111from django.utils.encoding import force_unicode, smart_str
    1212from django.utils.datastructures import SortedDict
    1313
    14 try:
    15     all
    16 except NameError:
    17     from django.utils.itercompat import all
    18 
    1914# Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
    2015get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip()
    2116
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index 0fc48f8..c11c442 100644
    a b The main QuerySet implementation. This provides the public API for the ORM.  
    33"""
    44
    55from itertools import izip
     6from copy import deepcopy
    67
    78from django.db import connections, router, transaction, IntegrityError
    89from django.db.models.aggregates import Aggregate
    from django.db.models.query_utils import (Q, select_related_descend,  
    1112    deferred_class_factory, InvalidQuery)
    1213from django.db.models.deletion import Collector
    1314from django.db.models import signals, sql
    14 from django.utils.copycompat import deepcopy
    1515
    1616# Used to control how many objects are worked with at once in some cases (e.g.
    1717# when deleting objects).
  • django/db/models/query_utils.py

    diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
    index 80485e0..e3cf4ba 100644
    a b circular import difficulties.  
    77"""
    88
    99import weakref
    10 from django.utils.copycompat import deepcopy
     10from copy import deepcopy
    1111
    1212from django.db.backends import util
    1313from django.utils import tree
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index ea89771..889324e 100644
    a b databases). The abstraction barrier only works one way: this module has to know  
    77all about the internals of models in order to get the information it needs.
    88"""
    99
    10 from django.utils.copycompat import deepcopy
     10from copy import deepcopy
    1111from django.utils.tree import Node
    1212from django.utils.datastructures import SortedDict
    1313from django.utils.encoding import force_unicode
  • django/db/transaction.py

    diff --git a/django/db/transaction.py b/django/db/transaction.py
    index b5584dd..df903b0 100644
    a b Managed transactions don't do those commits, but will need some kind of manual  
    1212or implicit commits or rollbacks.
    1313"""
    1414import sys
    15 
    16 try:
    17     from functools import wraps
    18 except ImportError:
    19     from django.utils.functional import wraps  # Python 2.4 fallback.
     15from functools import wraps
    2016
    2117from django.conf import settings
    2218from django.db import connections, DEFAULT_DB_ALIAS
    class Transaction(object):  
    210206        @wraps(func)
    211207        def inner(*args, **kwargs):
    212208            # Once we drop support for Python 2.4 this block should become:
    213             # with self:
    214             #     func(*args, **kwargs)
    215             self.__enter__()
    216             try:
    217                 res = func(*args, **kwargs)
    218             except:
    219                 self.__exit__(*sys.exc_info())
    220                 raise
    221             else:
    222                 self.__exit__(None, None, None)
    223                 return res
     209            with self:
     210                return func(*args, **kwargs)
    224211        return inner
    225212
    226213def _transaction_func(entering, exiting, using):
  • django/dispatch/saferef.py

    diff --git a/django/dispatch/saferef.py b/django/dispatch/saferef.py
    index 8bcfd8a..f446447 100644
    a b class BoundNonDescriptorMethodWeakref(BoundMethodWeakref):  
    230230        if target is not None:
    231231            function = self.weakFunc()
    232232            if function is not None:
    233                 # Using curry() would be another option, but it erases the
     233                # Using partial() would be another option, but it erases the
    234234                # "signature" of the function. That is, after a function is
    235235                # curried, the inspect module can't be used to determine how
    236236                # many arguments the function expects, nor what keyword
  • django/forms/extras/widgets.py

    diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py
    index e8bacf2..d75e903 100644
    a b class SelectDateWidget(Widget):  
    6868                if settings.USE_L10N:
    6969                    try:
    7070                        input_format = get_format('DATE_INPUT_FORMATS')[0]
    71                         # Python 2.4 compatibility:
    72                         #     v = datetime.datetime.strptime(value, input_format)
    73                         # would be clearer, but datetime.strptime was added in
    74                         # Python 2.5
    75                         v = datetime.datetime(*(time.strptime(value, input_format)[0:6]))
     71                        v = datetime.datetime.strptime(value, input_format)
    7672                        year_val, month_val, day_val = v.year, v.month, v.day
    7773                    except ValueError:
    7874                        pass
  • django/forms/fields.py

    diff --git a/django/forms/fields.py b/django/forms/fields.py
    index 4d7728f..0235d28 100644
    a b Field classes.  
    55import datetime
    66import os
    77import re
     8import copy
    89import time
    910import urlparse
    1011import warnings
    except ImportError:  
    1617
    1718from django.core.exceptions import ValidationError
    1819from django.core import validators
    19 import django.utils.copycompat as copy
    2020from django.utils import formats
    2121from django.utils.translation import ugettext_lazy as _
    2222from django.utils.encoding import smart_unicode, smart_str
  • django/forms/forms.py

    diff --git a/django/forms/forms.py b/django/forms/forms.py
    index f776861..31b1bc2 100644
    a b  
    22Form classes
    33"""
    44
     5from copy import deepcopy
    56from django.core.exceptions import ValidationError
    6 from django.utils.copycompat import deepcopy
    77from django.utils.datastructures import SortedDict
    88from django.utils.html import conditional_escape
    99from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
  • django/forms/widgets.py

    diff --git a/django/forms/widgets.py b/django/forms/widgets.py
    index dd5868f..5122d4c 100644
    a b  
    22HTML Widget classes
    33"""
    44import datetime
    5 from itertools import chain
    65import time
     6import copy
     7from itertools import chain
    78from urlparse import urljoin
    89from util import flatatt
    910
    10 import django.utils.copycompat as copy
    1111from django.conf import settings
    1212from django.utils.datastructures import MultiValueDict, MergeDict
    1313from django.utils.html import escape, conditional_escape
  • django/http/__init__.py

    diff --git a/django/http/__init__.py b/django/http/__init__.py
    index 714d552..62e327d 100644
    a b class QueryDict(MultiValueDict):  
    364364        return result
    365365
    366366    def __deepcopy__(self, memo):
    367         import django.utils.copycompat as copy
     367        import copy
    368368        result = self.__class__('', mutable=True, encoding=self.encoding)
    369369        memo[id(self)] = result
    370370        for key, value in dict.items(self):
  • django/middleware/common.py

    diff --git a/django/middleware/common.py b/django/middleware/common.py
    index 2252c8f..68bf891 100644
    a b  
    11import re
     2from hashlib import md5
    23
    34from django.conf import settings
    45from django import http
    56from django.core.mail import mail_managers
    67from django.utils.http import urlquote
    78from django.core import urlresolvers
    8 from django.utils.hashcompat import md5_constructor
    99from django.utils.log import getLogger
    1010
    1111logger = getLogger('django.request')
    class CommonMiddleware(object):  
    113113            if response.has_header('ETag'):
    114114                etag = response['ETag']
    115115            else:
    116                 etag = '"%s"' % md5_constructor(response.content).hexdigest()
     116                etag = '"%s"' % md5(response.content).hexdigest()
    117117            if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag:
    118118                cookies = response.cookies
    119119                response = http.HttpResponseNotModified()
  • django/middleware/csrf.py

    diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py
    index b5a8579..a79e1e0 100644
    a b against request forgeries from other sites.  
    88import itertools
    99import re
    1010import random
     11from hashlib import md5
    1112
    1213from django.conf import settings
    1314from django.core.urlresolvers import get_callable
    1415from django.utils.cache import patch_vary_headers
    15 from django.utils.hashcompat import md5_constructor
    1616from django.utils.http import same_origin
    1717from django.utils.log import getLogger
    1818from django.utils.safestring import mark_safe
    def _get_failure_view():  
    4747
    4848
    4949def _get_new_csrf_key():
    50     return md5_constructor("%s%s"
    51                 % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
     50    return md5("%s%s" % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
    5251
    5352
    5453def _make_legacy_session_token(session_id):
    55     return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
     54    return md5(settings.SECRET_KEY + session_id).hexdigest()
    5655
    5756
    5857def get_token(request):
  • django/template/base.py

    diff --git a/django/template/base.py b/django/template/base.py
    index 49ef0b8..01f9752 100644
    a b  
    11import imp
    22import re
    33from inspect import getargspec
     4from functools import partial
    45
    56from django.conf import settings
    67from django.template.context import Context, RequestContext, ContextPopException
    78from django.utils.importlib import import_module
    89from django.utils.itercompat import is_iterable
    9 from django.utils.functional import curry, Promise
     10from django.utils.functional import Promise
    1011from django.utils.text import smart_split, unescape_string_literal, get_text_list
    1112from django.utils.encoding import smart_unicode, force_unicode, smart_str
    1213from django.utils.translation import ugettext_lazy
    class Library(object):  
    884885                        func_args = resolved_vars
    885886                    return func(*func_args)
    886887
    887             compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
     888            compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
    888889            compile_func.__doc__ = func.__doc__
    889890            self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
    890891            return func
    class Library(object):  
    936937                        new_context['csrf_token'] = csrf_token
    937938                    return self.nodelist.render(new_context)
    938939
    939             compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
     940            compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
    940941            compile_func.__doc__ = func.__doc__
    941942            self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
    942943            return func
  • django/template/defaultfilters.py

    diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
    index d923d8a..dec69fd 100644
    a b  
    33import re
    44from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
    55import random as random_module
    6 try:
    7     from functools import wraps
    8 except ImportError:
    9     from django.utils.functional import wraps  # Python 2.4 fallback.
     6from functools import wraps
    107
    118from django.template.base import Variable, Library
    129from django.conf import settings
  • django/template/loaders/cached.py

    diff --git a/django/template/loaders/cached.py b/django/template/loaders/cached.py
    index 715542a..c40a337 100644
    a b  
    22Wrapper class that takes a list of template loaders as an argument and attempts
    33to load templates from them in order, caching the result.
    44"""
     5from hashlib import sha1
    56
    67from django.core.exceptions import ImproperlyConfigured
    78from django.template.base import TemplateDoesNotExist
    89from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin
    9 from django.utils.hashcompat import sha_constructor
    1010from django.utils.importlib import import_module
    1111
    1212class Loader(BaseLoader):
    class Loader(BaseLoader):  
    3838        key = template_name
    3939        if template_dirs:
    4040            # If template directories were specified, use a hash to differentiate
    41             key = '-'.join([template_name, sha_constructor('|'.join(template_dirs)).hexdigest()])
     41            key = '-'.join([template_name, sha1('|'.join(template_dirs)).hexdigest()])
    4242
    4343        if key not in self.template_cache:
    4444            template, origin = self.find_template(template_name, template_dirs)
  • django/templatetags/cache.py

    diff --git a/django/templatetags/cache.py b/django/templatetags/cache.py
    index 4fe3c3b..44f8f77 100644
    a b  
     1from hashlib import md5
    12from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
    23from django.template import resolve_variable
    34from django.core.cache import cache
    45from django.utils.encoding import force_unicode
    56from django.utils.http import urlquote
    6 from django.utils.hashcompat import md5_constructor
    77
    88register = Library()
    99
    class CacheNode(Node):  
    2424        except (ValueError, TypeError):
    2525            raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
    2626        # Build a unicode key for this fragment and all vary-on's.
    27         args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
     27        args = md5(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
    2828        cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
    2929        value = cache.get(cache_key)
    3030        if value is None:
  • django/test/client.py

    diff --git a/django/test/client.py b/django/test/client.py
    index dd0d811..b5256fb 100644
    a b import re  
    66import mimetypes
    77import warnings
    88from copy import copy
     9from functools import partial
    910try:
    1011    from cStringIO import StringIO
    1112except ImportError:
  • django/test/simple.py

    diff --git a/django/test/simple.py b/django/test/simple.py
    index d0b9a70..41b2a42 100644
    a b from django.test.utils import setup_test_environment, teardown_test_environment  
    77from django.test.testcases import OutputChecker, DocTestRunner, TestCase
    88from django.utils import unittest
    99
    10 try:
    11     all
    12 except NameError:
    13     from django.utils.itercompat import all
    14 
    15 
    1610__all__ = ('DjangoTestRunner', 'DjangoTestSuiteRunner', 'run_tests')
    1711
    1812# The module name for tests outside models.py
  • django/test/testcases.py

    diff --git a/django/test/testcases.py b/django/test/testcases.py
    index 02cd00c..e5c8ad9 100644
    a b  
    11import re
    22import sys
     3from functools import wraps
    34from urlparse import urlsplit, urlunsplit
    45from xml.dom.minidom import parseString, Node
    56
    from django.test.client import Client  
    1617from django.test.utils import get_warnings_state, restore_warnings_state
    1718from django.utils import simplejson, unittest as ut2
    1819from django.utils.encoding import smart_str
    19 from django.utils.functional import wraps
    2020
    2121__all__ = ('DocTestRunner', 'OutputChecker', 'TestCase', 'TransactionTestCase',
    2222           'skipIfDBFeature', 'skipUnlessDBFeature')
    2323
    2424
    25 try:
    26     all
    27 except NameError:
    28     from django.utils.itercompat import all
    29 
    3025normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
    3126normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", lambda m: "Decimal(\"%s\")" % m.groups()[0], s)
    3227
    class TransactionTestCase(ut2.TestCase):  
    550545
    551546def connections_support_transactions():
    552547    """
    553     Returns True if all connections support transactions.  This is messy
    554     because 2.4 doesn't support any or all.
     548    Returns True if all connections support transactions.
    555549    """
    556550    return all(conn.features.supports_transactions
    557551        for conn in connections.all())
  • django/utils/cache.py

    diff --git a/django/utils/cache.py b/django/utils/cache.py
    index 63c4af3..55a1344 100644
    a b An example: i18n middleware would need to distinguish caches by the  
    1919
    2020import re
    2121import time
     22from hashlib import md5
    2223
    2324from django.conf import settings
    2425from django.core.cache import get_cache
    2526from django.utils.encoding import smart_str, iri_to_uri
    2627from django.utils.http import http_date
    27 from django.utils.hashcompat import md5_constructor
    2828from django.utils.translation import get_language
    2929from django.http import HttpRequest
    3030
    def patch_response_headers(response, cache_timeout=None):  
    102102    if cache_timeout < 0:
    103103        cache_timeout = 0 # Can't have max-age negative
    104104    if settings.USE_ETAGS and not response.has_header('ETag'):
    105         response['ETag'] = '"%s"' % md5_constructor(response.content).hexdigest()
     105        response['ETag'] = '"%s"' % md5(response.content).hexdigest()
    106106    if not response.has_header('Last-Modified'):
    107107        response['Last-Modified'] = http_date()
    108108    if not response.has_header('Expires'):
    def _i18n_cache_key_suffix(request, cache_key):  
    155155
    156156def _generate_cache_key(request, method, headerlist, key_prefix):
    157157    """Returns a cache key from the headers given in the header list."""
    158     ctx = md5_constructor()
     158    ctx = md5()
    159159    for header in headerlist:
    160160        value = request.META.get(header, None)
    161161        if value is not None:
    162162            ctx.update(value)
    163     path = md5_constructor(iri_to_uri(request.get_full_path()))
     163    path = md5(iri_to_uri(request.get_full_path()))
    164164    cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
    165165        key_prefix, request.method, path.hexdigest(), ctx.hexdigest())
    166166    return _i18n_cache_key_suffix(request, cache_key)
    167167
    168168def _generate_cache_header_key(key_prefix, request):
    169169    """Returns a cache key for the header cache."""
    170     path = md5_constructor(iri_to_uri(request.get_full_path()))
     170    path = md5(iri_to_uri(request.get_full_path()))
    171171    cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
    172172        key_prefix, path.hexdigest())
    173173    return _i18n_cache_key_suffix(request, cache_key)
  • deleted file django/utils/copycompat.py

    diff --git a/django/utils/copycompat.py b/django/utils/copycompat.py
    deleted file mode 100644
    index 22b3cfb..0000000
    + -  
    1 """
    2 Fixes Python 2.4's failure to deepcopy unbound functions.
    3 """
    4 
    5 import copy
    6 import types
    7 
    8 # Monkeypatch copy's deepcopy registry to handle functions correctly.
    9 if (hasattr(copy, '_deepcopy_dispatch') and types.FunctionType not in copy._deepcopy_dispatch):
    10     copy._deepcopy_dispatch[types.FunctionType] = copy._deepcopy_atomic
    11 
    12 # Pose as the copy module now.
    13 del copy, types
    14 from copy import *
  • django/utils/crypto.py

    diff --git a/django/utils/crypto.py b/django/utils/crypto.py
    index 87cd0b9..1650976 100644
    a b  
    22Django's standard crypto functions and utilities.
    33"""
    44import hmac
     5from hashlib import sha1
    56
    67from django.conf import settings
    7 from django.utils.hashcompat import sha_constructor, sha_hmac
    88
    99
    1010def salted_hmac(key_salt, value, secret=None):
    def salted_hmac(key_salt, value, secret=None):  
    2121    # passing the key_salt and our base key through a pseudo-random function and
    2222    # SHA1 works nicely.
    2323
    24     key = sha_constructor(key_salt + secret).digest()
     24    key = sha1(key_salt + secret).digest()
    2525
    2626    # If len(key_salt + secret) > sha_constructor().block_size, the above
    2727    # line is redundant and could be replaced by key = key_salt + secret, since
    2828    # the hmac module does the same thing for keys longer than the block size.
    2929    # However, we need to ensure that we *always* do this.
    3030
    31     return hmac.new(key, msg=value, digestmod=sha_hmac)
     31    return hmac.new(key, msg=value, digestmod=sha1)
    3232
    3333
    3434def constant_time_compare(val1, val2):
  • django/utils/datastructures.py

    diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
    index 7425ea2..a401ddd 100644
    a b  
    11from types import GeneratorType
    2 
    3 from django.utils.copycompat import copy, deepcopy
     2from copy import copy, deepcopy
    43
    54
    65class MergeDict(object):
    class MultiValueDict(dict):  
    269268        ])
    270269
    271270    def __deepcopy__(self, memo=None):
    272         import django.utils.copycompat as copy
    273271        if memo is None:
    274272            memo = {}
    275273        result = self.__class__()
    276274        memo[id(self)] = result
    277275        for key, value in dict.items(self):
    278             dict.__setitem__(result, copy.deepcopy(key, memo),
    279                              copy.deepcopy(value, memo))
     276            dict.__setitem__(result, deepcopy(key, memo),
     277                             deepcopy(value, memo))
    280278        return result
    281279
    282280    def __getstate__(self):
  • django/utils/decorators.py

    diff --git a/django/utils/decorators.py b/django/utils/decorators.py
    index 17f2ea3..6099f88 100644
    a b  
    11"Functions that help with dynamically creating decorators for views."
    22
    3 try:
    4     from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
    5 except ImportError:
    6     from django.utils.functional import wraps, update_wrapper, WRAPPER_ASSIGNMENTS  # Python 2.4 fallback.
     3from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
    74
    85class classonlymethod(classmethod):
    96    def __get__(self, instance, owner):
  • django/utils/functional.py

    diff --git a/django/utils/functional.py b/django/utils/functional.py
    index ccfbcb0..45382e3 100644
    a b  
    4949# agrees to be bound by the terms and conditions of this License
    5050# Agreement.
    5151
     52from functools import wraps
    5253
    5354def curry(_curried_func, *args, **kwargs):
    5455    def _curried(*moreargs, **morekwargs):
    5556        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
    5657    return _curried
    5758
    58 ### Begin from Python 2.5 functools.py ########################################
    59 
    60 # Summary of changes made to the Python 2.5 code below:
    61 #   * swapped ``partial`` for ``curry`` to maintain backwards-compatibility
    62 #     in Django.
    63 
    64 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation.
    65 # All Rights Reserved.
    66 
    67 ###############################################################################
    68 
    69 # update_wrapper() and wraps() are tools to help write
    70 # wrapper functions that can handle naive introspection
    71 
    72 WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
    73 WRAPPER_UPDATES = ('__dict__',)
    74 def update_wrapper(wrapper,
    75                    wrapped,
    76                    assigned = WRAPPER_ASSIGNMENTS,
    77                    updated = WRAPPER_UPDATES):
    78     """Update a wrapper function to look like the wrapped function
    79 
    80        wrapper is the function to be updated
    81        wrapped is the original function
    82        assigned is a tuple naming the attributes assigned directly
    83        from the wrapped function to the wrapper function (defaults to
    84        functools.WRAPPER_ASSIGNMENTS)
    85        updated is a tuple naming the attributes off the wrapper that
    86        are updated with the corresponding attribute from the wrapped
    87        function (defaults to functools.WRAPPER_UPDATES)
    88     """
    89     for attr in assigned:
    90         setattr(wrapper, attr, getattr(wrapped, attr))
    91     for attr in updated:
    92         getattr(wrapper, attr).update(getattr(wrapped, attr))
    93     # Return the wrapper so this can be used as a decorator via curry()
    94     return wrapper
    95 
    96 def wraps(wrapped,
    97           assigned = WRAPPER_ASSIGNMENTS,
    98           updated = WRAPPER_UPDATES):
    99     """Decorator factory to apply update_wrapper() to a wrapper function
    100 
    101        Returns a decorator that invokes update_wrapper() with the decorated
    102        function as the wrapper argument and the arguments to wraps() as the
    103        remaining arguments. Default arguments are as for update_wrapper().
    104        This is a convenience function to simplify applying curry() to
    105        update_wrapper().
    106     """
    107     return curry(update_wrapper, wrapped=wrapped,
    108                  assigned=assigned, updated=updated)
    109 
    110 ### End from Python 2.5 functools.py ##########################################
    111 
    11259def memoize(func, cache, num_args):
    11360    """
    11461    Wrap a function so that results for any argument tuple are stored in
    class SimpleLazyObject(LazyObject):  
    343290            memo[id(self)] = result
    344291            return result
    345292        else:
    346             # Changed to use deepcopy from copycompat, instead of copy
    347             # For Python 2.4.
    348             from django.utils.copycompat import deepcopy
     293            from copy import deepcopy
    349294            return deepcopy(self._wrapped, memo)
    350295
    351296    # Need to pretend to be the wrapped class, for the sake of objects that care
  • deleted file django/utils/hashcompat.py

    diff --git a/django/utils/hashcompat.py b/django/utils/hashcompat.py
    deleted file mode 100644
    index 4d9b76f..0000000
    + -  
    1 """
    2 The md5 and sha modules are deprecated since Python 2.5, replaced by the
    3 hashlib module containing both hash algorithms. Here, we provide a common
    4 interface to the md5 and sha constructors, depending on system version.
    5 """
    6 
    7 import sys
    8 if sys.version_info >= (2, 5):
    9     import hashlib
    10     md5_constructor = hashlib.md5
    11     md5_hmac = md5_constructor
    12     sha_constructor = hashlib.sha1
    13     sha_hmac = sha_constructor
    14 else:
    15     import md5
    16     md5_constructor = md5.new
    17     md5_hmac = md5
    18     import sha
    19     sha_constructor = sha.new
    20     sha_hmac = sha
  • django/utils/itercompat.py

    diff --git a/django/utils/itercompat.py b/django/utils/itercompat.py
    index d4ff250..b302e22 100644
    a b def is_iterable(x):  
    3131        return False
    3232    else:
    3333        return True
    34 
    35 def all(iterable):
    36     for item in iterable:
    37         if not item:
    38             return False
    39     return True
    40 
    41 def any(iterable):
    42     for item in iterable:
    43         if item:
    44             return True
    45     return False
  • django/utils/log.py

    diff --git a/django/utils/log.py b/django/utils/log.py
    index 4fb75b1..493f2ea 100644
    a b try:  
    1818except ImportError:
    1919    from django.utils.dictconfig import dictConfig
    2020
    21 if sys.version_info < (2, 5):
    22     class LoggerCompat(object):
    23         def __init__(self, logger):
    24             self._logger = logger
    25 
    26         def __getattr__(self, name):
    27             val = getattr(self._logger, name)
    28             if callable(val):
    29                 def _wrapper(*args, **kwargs):
    30                     # Python 2.4 logging module doesn't support 'extra' parameter to
    31                     # methods of Logger
    32                     kwargs.pop('extra', None)
    33                     return val(*args, **kwargs)
    34                 return _wrapper
    35             else:
    36                 return val
    37 
    38     def getLogger(name=None):
    39         return LoggerCompat(logging.getLogger(name=name))
    40 else:
    41     getLogger = logging.getLogger
     21getLogger = logging.getLogger
    4222
    4323# Ensure the creation of the Django logger
    4424# with a null handler. This ensures we don't get any
    if not logger.handlers:  
    4929
    5030class AdminEmailHandler(logging.Handler):
    5131    def __init__(self, include_html=False):
    52         logging.Handler.__init__(self)       
     32        logging.Handler.__init__(self)
    5333        self.include_html = include_html
    5434
    5535    """An exception log handler that e-mails log entries to site admins.
    class AdminEmailHandler(logging.Handler):  
    6343        from django.views.debug import ExceptionReporter
    6444
    6545        try:
    66             if sys.version_info < (2,5):
    67                 # A nasty workaround required because Python 2.4's logging
    68                 # module doesn't support passing in extra context.
    69                 # For this handler, the only extra data we need is the
    70                 # request, and that's in the top stack frame.
    71                 request = record.exc_info[2].tb_frame.f_locals['request']
    72             else:
    73                 request = record.request
    74 
     46            request = record.request
    7547            subject = '%s (%s IP): %s' % (
    7648                record.levelname,
    7749                (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'),
  • django/utils/tree.py

    diff --git a/django/utils/tree.py b/django/utils/tree.py
    index a6cfec2..a9028b8 100644
    a b A class for storing a tree graph. Primarily used for filter constructs in the  
    33ORM.
    44"""
    55
    6 from django.utils.copycompat import deepcopy
     6from copy import deepcopy
    77
    88class Node(object):
    99    """
  • django/utils/unittest/case.py

    diff --git a/django/utils/unittest/case.py b/django/utils/unittest/case.py
    index 78507c1..e8823fa 100644
    a b class _ExpectedFailure(Exception):  
    3636    """
    3737
    3838    def __init__(self, exc_info):
    39         # can't use super because Python 2.4 exceptions are old style
    40         Exception.__init__(self)
     39        super(_ExpectedFailure, self).__init__()
    4140        self.exc_info = exc_info
    4241
    4342class _UnexpectedSuccess(Exception):
  • django/utils/unittest/compatibility.py

    diff --git a/django/utils/unittest/compatibility.py b/django/utils/unittest/compatibility.py
    index a0dc499..11c6161 100644
    a b  
    11import os
    22import sys
    3 
    4 try:
    5     from functools import wraps
    6 except ImportError:
    7     # only needed for Python 2.4
    8     def wraps(_):
    9         def _wraps(func):
    10             return func
    11         return _wraps
     3from functools import wraps
    124
    135__unittest = True
    146
  • django/views/decorators/cache.py

    diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py
    index a836ac5..4db9a12 100644
    a b  
    1 try:
    2     from functools import wraps
    3 except ImportError:
    4     from django.utils.functional import wraps  # Python 2.4 fallback.
     1from functools import wraps
    52
    63from django.utils.decorators import decorator_from_middleware_with_args, available_attrs
    74from django.utils.cache import patch_cache_control, add_never_cache_headers
  • django/views/decorators/csrf.py

    diff --git a/django/views/decorators/csrf.py b/django/views/decorators/csrf.py
    index 578854a..330d1d3 100644
    a b  
     1from functools import wraps
     2
    13from django.middleware.csrf import CsrfViewMiddleware
    24from django.utils.decorators import decorator_from_middleware, available_attrs
    35
    4 try:
    5     from functools import wraps
    6 except ImportError:
    7     from django.utils.functional import wraps  # Python 2.4 fallback.
    8 
    96csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
    107csrf_protect.__name__ = "csrf_protect"
    118csrf_protect.__doc__ = """
  • django/views/decorators/http.py

    diff --git a/django/views/decorators/http.py b/django/views/decorators/http.py
    index fb3181e..aaf3503 100644
    a b  
    11"""
    22Decorators for views based on HTTP headers.
    33"""
    4 
    5 try:
    6     from functools import wraps
    7 except ImportError:
    8     from django.utils.functional import wraps  # Python 2.4 fallback.
     4from functools import wraps
    95
    106from calendar import timegm
    117from datetime import timedelta
  • django/views/decorators/vary.py

    diff --git a/django/views/decorators/vary.py b/django/views/decorators/vary.py
    index a10896c..f95534e 100644
    a b  
    1 try:
    2     from functools import wraps
    3 except ImportError:
    4     from django.utils.functional import wraps  # Python 2.4 fallback.
     1from functools import wraps
    52
    63from django.utils.cache import patch_vary_headers
    74from django.utils.decorators import available_attrs
  • django/views/generic/base.py

    diff --git a/django/views/generic/base.py b/django/views/generic/base.py
    index d732af5..f2c6d3f 100644
    a b  
     1from functools import update_wrapper
    12from django import http
    23from django.core.exceptions import ImproperlyConfigured
    34from django.template import RequestContext, loader
    45from django.template.response import TemplateResponse
    5 from django.utils.functional import update_wrapper
    66from django.utils.log import getLogger
    77from django.utils.decorators import classonlymethod
    88
  • tests/regressiontests/dispatch/tests/test_dispatcher.py

    diff --git a/tests/regressiontests/dispatch/tests/test_dispatcher.py b/tests/regressiontests/dispatch/tests/test_dispatcher.py
    index 2ad5b0c..bfb3b3d 100644
    a b  
    11import gc
    22import sys
     3import copy
    34
    45from django.dispatch import Signal
    56from django.utils import unittest
    6 import django.utils.copycompat as copy
    77
    88if sys.platform.startswith('java'):
    99    def garbage_collect():
  • tests/regressiontests/extra_regress/models.py

    diff --git a/tests/regressiontests/extra_regress/models.py b/tests/regressiontests/extra_regress/models.py
    index 073157a..4445a0f 100644
    a b  
    11import datetime
    2 
    3 import django.utils.copycompat as copy
     2import copy
    43
    54from django.contrib.auth.models import User
    65from django.db import models
  • tests/regressiontests/forms/tests/widgets.py

    diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
    index 4c5aeb0..894b0a6 100644
    a b  
    11# -*- coding: utf-8 -*-
    22import datetime
    3 from decimal import Decimal
    43import re
    54import time
     5import copy
     6from decimal import Decimal
     7
    68from django.conf import settings
    79from django.core.files.uploadedfile import SimpleUploadedFile
    810from django.forms import *
    911from django.forms.widgets import RadioFieldRenderer
    10 from django.utils import copycompat as copy
    1112from django.utils import formats
    1213from django.utils.safestring import mark_safe
    1314from django.utils.translation import activate, deactivate
  • tests/regressiontests/introspection/tests.py

    diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py
    index 90dea92..4809849 100644
    a b  
     1from functools import update_wrapper
     2
    13from django.conf import settings
    24from django.db import connection, DEFAULT_DB_ALIAS
    35from django.test import TestCase, skipUnlessDBFeature
    4 from django.utils import functional
    56
    67from models import Reporter, Article
    78
    def ignore_not_implemented(func):  
    2324            return func(*args, **kwargs)
    2425        except NotImplementedError:
    2526            return None
    26     functional.update_wrapper(_inner, func)
     27    update_wrapper(_inner, func)
    2728    return _inner
    2829
    2930class IgnoreNotimplementedError(type):
  • tests/regressiontests/utils/datastructures.py

    diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py
    index 3d01ab8..74d7d2d 100644
    a b Tests for stuff in django.utils.datastructures.  
    33"""
    44import pickle
    55import unittest
     6import copy
    67
    7 from django.utils.copycompat import copy
    88from django.utils.datastructures import *
    99
    1010
  • tests/regressiontests/utils/simplelazyobject.py

    diff --git a/tests/regressiontests/utils/simplelazyobject.py b/tests/regressiontests/utils/simplelazyobject.py
    index 9eea8b5..44fa783 100644
    a b  
    11import unittest
     2import copy
    23
    3 import django.utils.copycompat as copy
    44from django.utils.functional import SimpleLazyObject
    55
    66class _ComplexObject(object):
Back to Top