Removed a bunch more Python 2.4 workarounds now that we don't support that version. Refs #15702 -- thanks to jonash for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15927 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2011-03-28 02:11:19 +00:00
parent a87be3554f
commit 13864703bc
56 changed files with 113 additions and 326 deletions

View File

@ -18,20 +18,17 @@ class EmailBackend(BaseEmailBackend):
return
self._lock.acquire()
try:
# The try-except is nested to allow for
# Python 2.4 support (Refs #12147)
try:
stream_created = self.open()
for message in email_messages:
self.stream.write('%s\n' % message.message().as_string())
self.stream.write('-'*79)
self.stream.write('\n')
self.stream.flush() # flush after each message
if stream_created:
self.close()
except:
if not self.fail_silently:
raise
stream_created = self.open()
for message in email_messages:
self.stream.write('%s\n' % message.message().as_string())
self.stream.write('-'*79)
self.stream.write('\n')
self.stream.flush() # flush after each message
if stream_created:
self.close()
except:
if not self.fail_silently:
raise
finally:
self._lock.release()
return len(email_messages)

View File

@ -3,10 +3,7 @@ import os
import random
import time
from email import Charset, Encoders
try:
from email.generator import Generator
except ImportError:
from email.Generator import Generator # TODO: Remove when remove Python 2.4 support
from email.generator import Generator
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase

View File

@ -4,11 +4,6 @@ from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelati
from django.core.management.color import color_style
from django.utils.itercompat import is_iterable
try:
any
except NameError:
from django.utils.itercompat import any
class ModelErrorCollection:
def __init__(self, outfile=sys.stdout):
self.errors = []

View File

@ -3,7 +3,6 @@ from django.core import signals
from django.core.exceptions import ImproperlyConfigured
from django.db.utils import ConnectionHandler, ConnectionRouter, load_backend, DEFAULT_DB_ALIAS, \
DatabaseError, IntegrityError
from django.utils.functional import curry
__all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
'IntegrityError', 'DEFAULT_DB_ALIAS')

View File

@ -1,8 +1,8 @@
import datetime
import decimal
import hashlib
from time import time
from django.utils.hashcompat import md5_constructor
from django.utils.log import getLogger
@ -130,9 +130,8 @@ def truncate_name(name, length=None, hash_len=4):
if length is None or len(name) <= length:
return name
hash = md5_constructor(name).hexdigest()[:hash_len]
return '%s%s' % (name[:length-hash_len], hash)
hsh = hashlib.md5(name).hexdigest()[:hash_len]
return '%s%s' % (name[:length-hash_len], hsh)
def format_number(value, max_digits, decimal_places):
"""

View File

@ -1,5 +1,7 @@
import types
import copy
import sys
import types
from functools import update_wrapper
from itertools import izip
import django.db.models.manager # Imported to register signal handler.
@ -17,8 +19,7 @@ from django.db import (connections, router, transaction, DatabaseError,
from django.db.models import signals
from django.db.models.loading import register_models, get_model
from django.utils.translation import ugettext_lazy as _
import django.utils.copycompat as copy
from django.utils.functional import curry, update_wrapper
from django.utils.functional import curry
from django.utils.encoding import smart_str, force_unicode
from django.utils.text import get_text_list, capfirst
from django.conf import settings

View File

@ -1,17 +1,16 @@
from functools import wraps
from operator import attrgetter
from django.db import connections, transaction, IntegrityError
from django.db.models import signals, sql
from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE
from django.utils.datastructures import SortedDict
from django.utils.functional import wraps
class ProtectedError(IntegrityError):
def __init__(self, msg, protected_objects):
self.protected_objects = protected_objects
# TODO change this to use super() when we drop Python 2.4
IntegrityError.__init__(self, msg, protected_objects)
super(ProtectedError, self).__init__(msg, protected_objects)
def CASCADE(collector, field, sub_objs, using):

View File

@ -1,7 +1,5 @@
import datetime
from django.utils import tree
from django.utils.copycompat import deepcopy
class ExpressionNode(tree.Node):
"""

View File

@ -1,3 +1,4 @@
import copy
import datetime
import decimal
import re
@ -5,8 +6,6 @@ import time
import math
from itertools import tee
import django.utils.copycompat as copy
from django.db import connection
from django.db.models.fields.subclassing import LegacyConnection
from django.db.models.query_utils import QueryWrapper

View File

@ -1,8 +1,6 @@
import datetime
import os
import django.utils.copycompat as copy
from django.conf import settings
from django.db.models.fields import Field
from django.core.files.base import File, ContentFile

View File

@ -1,4 +1,4 @@
from django.utils import copycompat as copy
import copy
from django.conf import settings
from django.db import router
from django.db.models.query import QuerySet, EmptyQuerySet, insert_query, RawQuerySet

View File

@ -11,11 +11,6 @@ from django.utils.translation import activate, deactivate_all, get_language, str
from django.utils.encoding import force_unicode, smart_str
from django.utils.datastructures import SortedDict
try:
all
except NameError:
from django.utils.itercompat import all
# Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip()

View File

@ -2,6 +2,7 @@
The main QuerySet implementation. This provides the public API for the ORM.
"""
import copy
from itertools import izip
from django.db import connections, router, transaction, IntegrityError
@ -11,7 +12,6 @@ from django.db.models.query_utils import (Q, select_related_descend,
deferred_class_factory, InvalidQuery)
from django.db.models.deletion import Collector
from django.db.models import signals, sql
from django.utils.copycompat import deepcopy
# Used to control how many objects are worked with at once in some cases (e.g.
# when deleting objects).
@ -51,7 +51,7 @@ class QuerySet(object):
if k in ('_iter','_result_cache'):
obj.__dict__[k] = None
else:
obj.__dict__[k] = deepcopy(v, memo)
obj.__dict__[k] = copy.deepcopy(v, memo)
return obj
def __getstate__(self):

View File

@ -7,7 +7,6 @@ circular import difficulties.
"""
import weakref
from django.utils.copycompat import deepcopy
from django.db.backends import util
from django.utils import tree

View File

@ -7,7 +7,7 @@ databases). The abstraction barrier only works one way: this module has to know
all about the internals of models in order to get the information it needs.
"""
from django.utils.copycompat import deepcopy
import copy
from django.utils.tree import Node
from django.utils.datastructures import SortedDict
from django.utils.encoding import force_unicode
@ -244,19 +244,19 @@ class Query(object):
obj.dupe_avoidance = self.dupe_avoidance.copy()
obj.select = self.select[:]
obj.tables = self.tables[:]
obj.where = deepcopy(self.where, memo=memo)
obj.where = copy.deepcopy(self.where, memo=memo)
obj.where_class = self.where_class
if self.group_by is None:
obj.group_by = None
else:
obj.group_by = self.group_by[:]
obj.having = deepcopy(self.having, memo=memo)
obj.having = copy.deepcopy(self.having, memo=memo)
obj.order_by = self.order_by[:]
obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
obj.distinct = self.distinct
obj.select_related = self.select_related
obj.related_select_cols = []
obj.aggregates = deepcopy(self.aggregates, memo=memo)
obj.aggregates = copy.deepcopy(self.aggregates, memo=memo)
if self.aggregate_select_mask is None:
obj.aggregate_select_mask = None
else:
@ -279,7 +279,7 @@ class Query(object):
obj._extra_select_cache = self._extra_select_cache.copy()
obj.extra_tables = self.extra_tables
obj.extra_order_by = self.extra_order_by
obj.deferred_loading = deepcopy(self.deferred_loading, memo=memo)
obj.deferred_loading = copy.deepcopy(self.deferred_loading, memo=memo)
if self.filter_is_sticky and self.used_aliases:
obj.used_aliases = self.used_aliases.copy()
else:
@ -476,7 +476,7 @@ class Query(object):
# Now relabel a copy of the rhs where-clause and add it to the current
# one.
if rhs.where:
w = deepcopy(rhs.where)
w = copy.deepcopy(rhs.where)
w.relabel_aliases(change_map)
if not self.where:
# Since 'self' matches everything, add an explicit "include
@ -497,7 +497,7 @@ class Query(object):
if isinstance(col, (list, tuple)):
self.select.append((change_map.get(col[0], col[0]), col[1]))
else:
item = deepcopy(col)
item = copy.deepcopy(col)
item.relabel_aliases(change_map)
self.select.append(item)
self.select_fields = rhs.select_fields[:]

View File

@ -11,12 +11,9 @@ called, a commit is made.
Managed transactions don't do those commits, but will need some kind of manual
or implicit commits or rollbacks.
"""
import sys
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
import sys
from functools import wraps
from django.conf import settings
from django.db import connections, DEFAULT_DB_ALIAS
@ -209,18 +206,8 @@ class Transaction(object):
def __call__(self, func):
@wraps(func)
def inner(*args, **kwargs):
# Once we drop support for Python 2.4 this block should become:
# with self:
# func(*args, **kwargs)
self.__enter__()
try:
res = func(*args, **kwargs)
except:
self.__exit__(*sys.exc_info())
raise
else:
self.__exit__(None, None, None)
return res
with self:
func(*args, **kwargs)
return inner
def _transaction_func(entering, exiting, using):

View File

@ -230,7 +230,7 @@ class BoundNonDescriptorMethodWeakref(BoundMethodWeakref):
if target is not None:
function = self.weakFunc()
if function is not None:
# Using curry() would be another option, but it erases the
# Using partial() would be another option, but it erases the
# "signature" of the function. That is, after a function is
# curried, the inspect module can't be used to determine how
# many arguments the function expects, nor what keyword

View File

@ -68,11 +68,7 @@ class SelectDateWidget(Widget):
if settings.USE_L10N:
try:
input_format = get_format('DATE_INPUT_FORMATS')[0]
# Python 2.4 compatibility:
# v = datetime.datetime.strptime(value, input_format)
# would be clearer, but datetime.strptime was added in
# Python 2.5
v = datetime.datetime(*(time.strptime(value, input_format)[0:6]))
v = datetime.datetime.strptime(value, input_format)
year_val, month_val, day_val = v.year, v.month, v.day
except ValueError:
pass

View File

@ -2,6 +2,7 @@
Field classes.
"""
import copy
import datetime
import os
import re
@ -16,7 +17,6 @@ except ImportError:
from django.core.exceptions import ValidationError
from django.core import validators
import django.utils.copycompat as copy
from django.utils import formats
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode, smart_str

View File

@ -2,8 +2,8 @@
Form classes
"""
import copy
from django.core.exceptions import ValidationError
from django.utils.copycompat import deepcopy
from django.utils.datastructures import SortedDict
from django.utils.html import conditional_escape
from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
@ -89,7 +89,7 @@ class BaseForm(StrAndUnicode):
# alter self.fields, we create self.fields here by copying base_fields.
# Instances should always modify self.fields; they should not modify
# self.base_fields.
self.fields = deepcopy(self.base_fields)
self.fields = copy.deepcopy(self.base_fields)
def __unicode__(self):
return self.as_table()

View File

@ -1,13 +1,14 @@
"""
HTML Widget classes
"""
import copy
import datetime
from itertools import chain
import time
from itertools import chain
from urlparse import urljoin
from util import flatatt
import django.utils.copycompat as copy
from django.conf import settings
from django.utils.datastructures import MultiValueDict, MergeDict
from django.utils.html import escape, conditional_escape

View File

@ -364,7 +364,7 @@ class QueryDict(MultiValueDict):
return result
def __deepcopy__(self, memo):
import django.utils.copycompat as copy
import copy
result = self.__class__('', mutable=True, encoding=self.encoding)
memo[id(self)] = result
for key, value in dict.items(self):

View File

@ -1,3 +1,4 @@
import hashlib
import re
from django.conf import settings
@ -5,7 +6,6 @@ from django import http
from django.core.mail import mail_managers
from django.utils.http import urlquote
from django.core import urlresolvers
from django.utils.hashcompat import md5_constructor
from django.utils.log import getLogger
logger = getLogger('django.request')
@ -113,7 +113,7 @@ class CommonMiddleware(object):
if response.has_header('ETag'):
etag = response['ETag']
else:
etag = '"%s"' % md5_constructor(response.content).hexdigest()
etag = '"%s"' % hashlib.md5(response.content).hexdigest()
if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag:
cookies = response.cookies
response = http.HttpResponseNotModified()

View File

@ -5,6 +5,7 @@ This module provides a middleware that implements protection
against request forgeries from other sites.
"""
import hashlib
import itertools
import re
import random
@ -12,7 +13,6 @@ import random
from django.conf import settings
from django.core.urlresolvers import get_callable
from django.utils.cache import patch_vary_headers
from django.utils.hashcompat import md5_constructor
from django.utils.http import same_origin
from django.utils.log import getLogger
from django.utils.safestring import mark_safe
@ -47,12 +47,11 @@ def _get_failure_view():
def _get_new_csrf_key():
return md5_constructor("%s%s"
% (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
return hashlib.md5("%s%s" % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
def _make_legacy_session_token(session_id):
return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
return hashlib.md5(settings.SECRET_KEY + session_id).hexdigest()
def get_token(request):

View File

@ -1,12 +1,13 @@
import imp
import re
from functools import partial
from inspect import getargspec
from django.conf import settings
from django.template.context import Context, RequestContext, ContextPopException
from django.utils.importlib import import_module
from django.utils.itercompat import is_iterable
from django.utils.functional import curry, Promise
from django.utils.functional import Promise
from django.utils.text import smart_split, unescape_string_literal, get_text_list
from django.utils.encoding import smart_unicode, force_unicode, smart_str
from django.utils.translation import ugettext_lazy
@ -884,7 +885,7 @@ class Library(object):
func_args = resolved_vars
return func(*func_args)
compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
compile_func.__doc__ = func.__doc__
self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
return func
@ -936,7 +937,7 @@ class Library(object):
new_context['csrf_token'] = csrf_token
return self.nodelist.render(new_context)
compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
compile_func.__doc__ = func.__doc__
self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
return func

View File

@ -1,12 +1,9 @@
"""Default variable filters."""
import re
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
import random as random_module
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from functools import wraps
from django.template.base import Variable, Library
from django.conf import settings

View File

@ -3,10 +3,10 @@ Wrapper class that takes a list of template loaders as an argument and attempts
to load templates from them in order, caching the result.
"""
import hashlib
from django.core.exceptions import ImproperlyConfigured
from django.template.base import TemplateDoesNotExist
from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin
from django.utils.hashcompat import sha_constructor
from django.utils.importlib import import_module
class Loader(BaseLoader):
@ -38,7 +38,7 @@ class Loader(BaseLoader):
key = template_name
if template_dirs:
# If template directories were specified, use a hash to differentiate
key = '-'.join([template_name, sha_constructor('|'.join(template_dirs)).hexdigest()])
key = '-'.join([template_name, hashlib.sha1('|'.join(template_dirs)).hexdigest()])
if key not in self.template_cache:
template, origin = self.find_template(template_name, template_dirs)

View File

@ -1,9 +1,9 @@
import hashlib
from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
from django.template import resolve_variable
from django.core.cache import cache
from django.utils.encoding import force_unicode
from django.utils.http import urlquote
from django.utils.hashcompat import md5_constructor
register = Library()
@ -24,7 +24,7 @@ class CacheNode(Node):
except (ValueError, TypeError):
raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
# Build a unicode key for this fragment and all vary-on's.
args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
args = hashlib.md5(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
value = cache.get(cache_key)
if value is None:

View File

@ -1,11 +1,11 @@
import urllib
from urlparse import urlparse, urlunparse, urlsplit
import sys
import os
import re
import mimetypes
import warnings
from copy import copy
from urlparse import urlparse, urlunparse, urlsplit
try:
from cStringIO import StringIO
except ImportError:

View File

@ -7,12 +7,6 @@ from django.test.utils import setup_test_environment, teardown_test_environment
from django.test.testcases import OutputChecker, DocTestRunner, TestCase
from django.utils import unittest
try:
all
except NameError:
from django.utils.itercompat import all
__all__ = ('DjangoTestRunner', 'DjangoTestSuiteRunner', 'run_tests')
# The module name for tests outside models.py

View File

@ -1,5 +1,6 @@
import re
import sys
from functools import wraps
from urlparse import urlsplit, urlunsplit
from xml.dom.minidom import parseString, Node
@ -16,21 +17,13 @@ from django.test.client import Client
from django.test.utils import get_warnings_state, restore_warnings_state
from django.utils import simplejson, unittest as ut2
from django.utils.encoding import smart_str
from django.utils.functional import wraps
__all__ = ('DocTestRunner', 'OutputChecker', 'TestCase', 'TransactionTestCase',
'skipIfDBFeature', 'skipUnlessDBFeature')
try:
all
except NameError:
from django.utils.itercompat import all
normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", lambda m: "Decimal(\"%s\")" % m.groups()[0], s)
def to_list(value):
"""
Puts value into a list if it's not already one.
@ -550,11 +543,9 @@ class TransactionTestCase(ut2.TestCase):
def connections_support_transactions():
"""
Returns True if all connections support transactions. This is messy
because 2.4 doesn't support any or all.
Returns True if all connections support transactions.
"""
return all(conn.features.supports_transactions
for conn in connections.all())
return all(conn.features.supports_transactions for conn in connections.all())
class TestCase(TransactionTestCase):
"""

View File

@ -17,6 +17,7 @@ An example: i18n middleware would need to distinguish caches by the
"Accept-language" header.
"""
import hashlib
import re
import time
@ -24,7 +25,6 @@ from django.conf import settings
from django.core.cache import get_cache
from django.utils.encoding import smart_str, iri_to_uri
from django.utils.http import http_date
from django.utils.hashcompat import md5_constructor
from django.utils.translation import get_language
from django.http import HttpRequest
@ -102,7 +102,7 @@ def patch_response_headers(response, cache_timeout=None):
if cache_timeout < 0:
cache_timeout = 0 # Can't have max-age negative
if settings.USE_ETAGS and not response.has_header('ETag'):
response['ETag'] = '"%s"' % md5_constructor(response.content).hexdigest()
response['ETag'] = '"%s"' % hashlib.md5(response.content).hexdigest()
if not response.has_header('Last-Modified'):
response['Last-Modified'] = http_date()
if not response.has_header('Expires'):
@ -155,19 +155,19 @@ def _i18n_cache_key_suffix(request, cache_key):
def _generate_cache_key(request, method, headerlist, key_prefix):
"""Returns a cache key from the headers given in the header list."""
ctx = md5_constructor()
ctx = hashlib.md5()
for header in headerlist:
value = request.META.get(header, None)
if value is not None:
ctx.update(value)
path = md5_constructor(iri_to_uri(request.get_full_path()))
path = hashlib.md5(iri_to_uri(request.get_full_path()))
cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
key_prefix, request.method, path.hexdigest(), ctx.hexdigest())
return _i18n_cache_key_suffix(request, cache_key)
def _generate_cache_header_key(key_prefix, request):
"""Returns a cache key for the header cache."""
path = md5_constructor(iri_to_uri(request.get_full_path()))
path = hashlib.md5(iri_to_uri(request.get_full_path()))
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
key_prefix, path.hexdigest())
return _i18n_cache_key_suffix(request, cache_key)

View File

@ -1,14 +0,0 @@
"""
Fixes Python 2.4's failure to deepcopy unbound functions.
"""
import copy
import types
# Monkeypatch copy's deepcopy registry to handle functions correctly.
if (hasattr(copy, '_deepcopy_dispatch') and types.FunctionType not in copy._deepcopy_dispatch):
copy._deepcopy_dispatch[types.FunctionType] = copy._deepcopy_atomic
# Pose as the copy module now.
del copy, types
from copy import *

View File

@ -1,11 +1,10 @@
"""
Django's standard crypto functions and utilities.
"""
import hashlib
import hmac
from django.conf import settings
from django.utils.hashcompat import sha_constructor, sha_hmac
def salted_hmac(key_salt, value, secret=None):
"""
@ -20,16 +19,13 @@ def salted_hmac(key_salt, value, secret=None):
# We need to generate a derived key from our base key. We can do this by
# passing the key_salt and our base key through a pseudo-random function and
# SHA1 works nicely.
key = sha_constructor(key_salt + secret).digest()
key = hashlib.sha1(key_salt + secret).digest()
# If len(key_salt + secret) > sha_constructor().block_size, the above
# line is redundant and could be replaced by key = key_salt + secret, since
# the hmac module does the same thing for keys longer than the block size.
# However, we need to ensure that we *always* do this.
return hmac.new(key, msg=value, digestmod=sha_hmac)
return hmac.new(key, msg=value, digestmod=hashlib.sha1)
def constant_time_compare(val1, val2):
"""

View File

@ -1,8 +1,6 @@
import copy
from types import GeneratorType
from django.utils.copycompat import copy, deepcopy
class MergeDict(object):
"""
A simple class for creating new "virtual" dictionaries that actually look
@ -127,7 +125,7 @@ class SortedDict(dict):
seen.add(key)
def __deepcopy__(self, memo):
return self.__class__([(key, deepcopy(value, memo))
return self.__class__([(key, copy.deepcopy(value, memo))
for key, value in self.iteritems()])
def __setitem__(self, key, value):
@ -269,7 +267,6 @@ class MultiValueDict(dict):
])
def __deepcopy__(self, memo=None):
import django.utils.copycompat as copy
if memo is None:
memo = {}
result = self.__class__()
@ -365,7 +362,7 @@ class MultiValueDict(dict):
def copy(self):
"""Returns a shallow copy of this object."""
return copy(self)
return copy.copy(self)
def update(self, *args, **kwargs):
"""

View File

@ -1,9 +1,6 @@
"Functions that help with dynamically creating decorators for views."
try:
from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
except ImportError:
from django.utils.functional import wraps, update_wrapper, WRAPPER_ASSIGNMENTS # Python 2.4 fallback.
from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
class classonlymethod(classmethod):
def __get__(self, instance, owner):

View File

@ -49,66 +49,13 @@
# agrees to be bound by the terms and conditions of this License
# Agreement.
from functools import wraps
def curry(_curried_func, *args, **kwargs):
def _curried(*moreargs, **morekwargs):
return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
return _curried
### Begin from Python 2.5 functools.py ########################################
# Summary of changes made to the Python 2.5 code below:
# * swapped ``partial`` for ``curry`` to maintain backwards-compatibility
# in Django.
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation.
# All Rights Reserved.
###############################################################################
# update_wrapper() and wraps() are tools to help write
# wrapper functions that can handle naive introspection
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Update a wrapper function to look like the wrapped function
wrapper is the function to be updated
wrapped is the original function
assigned is a tuple naming the attributes assigned directly
from the wrapped function to the wrapper function (defaults to
functools.WRAPPER_ASSIGNMENTS)
updated is a tuple naming the attributes off the wrapper that
are updated with the corresponding attribute from the wrapped
function (defaults to functools.WRAPPER_UPDATES)
"""
for attr in assigned:
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()
return wrapper
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Decorator factory to apply update_wrapper() to a wrapper function
Returns a decorator that invokes update_wrapper() with the decorated
function as the wrapper argument and the arguments to wraps() as the
remaining arguments. Default arguments are as for update_wrapper().
This is a convenience function to simplify applying curry() to
update_wrapper().
"""
return curry(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
### End from Python 2.5 functools.py ##########################################
def memoize(func, cache, num_args):
"""
Wrap a function so that results for any argument tuple are stored in
@ -343,10 +290,8 @@ class SimpleLazyObject(LazyObject):
memo[id(self)] = result
return result
else:
# Changed to use deepcopy from copycompat, instead of copy
# For Python 2.4.
from django.utils.copycompat import deepcopy
return deepcopy(self._wrapped, memo)
import copy
return copy.deepcopy(self._wrapped, memo)
# Need to pretend to be the wrapped class, for the sake of objects that care
# about this (especially in equality tests)

View File

@ -1,20 +0,0 @@
"""
The md5 and sha modules are deprecated since Python 2.5, replaced by the
hashlib module containing both hash algorithms. Here, we provide a common
interface to the md5 and sha constructors, depending on system version.
"""
import sys
if sys.version_info >= (2, 5):
import hashlib
md5_constructor = hashlib.md5
md5_hmac = md5_constructor
sha_constructor = hashlib.sha1
sha_hmac = sha_constructor
else:
import md5
md5_constructor = md5.new
md5_hmac = md5
import sha
sha_constructor = sha.new
sha_hmac = sha

View File

@ -31,15 +31,3 @@ def is_iterable(x):
return False
else:
return True
def all(iterable):
for item in iterable:
if not item:
return False
return True
def any(iterable):
for item in iterable:
if item:
return True
return False

View File

@ -18,27 +18,7 @@ try:
except ImportError:
from django.utils.dictconfig import dictConfig
if sys.version_info < (2, 5):
class LoggerCompat(object):
def __init__(self, logger):
self._logger = logger
def __getattr__(self, name):
val = getattr(self._logger, name)
if callable(val):
def _wrapper(*args, **kwargs):
# Python 2.4 logging module doesn't support 'extra' parameter to
# methods of Logger
kwargs.pop('extra', None)
return val(*args, **kwargs)
return _wrapper
else:
return val
def getLogger(name=None):
return LoggerCompat(logging.getLogger(name=name))
else:
getLogger = logging.getLogger
getLogger = logging.getLogger
# Ensure the creation of the Django logger
# with a null handler. This ensures we don't get any
@ -49,7 +29,7 @@ if not logger.handlers:
class AdminEmailHandler(logging.Handler):
def __init__(self, include_html=False):
logging.Handler.__init__(self)
logging.Handler.__init__(self)
self.include_html = include_html
"""An exception log handler that e-mails log entries to site admins.
@ -63,15 +43,7 @@ class AdminEmailHandler(logging.Handler):
from django.views.debug import ExceptionReporter
try:
if sys.version_info < (2,5):
# A nasty workaround required because Python 2.4's logging
# module doesn't support passing in extra context.
# For this handler, the only extra data we need is the
# request, and that's in the top stack frame.
request = record.exc_info[2].tb_frame.f_locals['request']
else:
request = record.request
request = record.request
subject = '%s (%s IP): %s' % (
record.levelname,
(request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'),
@ -97,5 +69,4 @@ class AdminEmailHandler(logging.Handler):
message = "%s\n\n%s" % (stack_trace, request_repr)
reporter = ExceptionReporter(request, is_email=True, *exc_info)
html_message = self.include_html and reporter.get_traceback_html() or None
mail.mail_admins(subject, message, fail_silently=True,
html_message=html_message)
mail.mail_admins(subject, message, fail_silently=True, html_message=html_message)

View File

@ -3,7 +3,7 @@ A class for storing a tree graph. Primarily used for filter constructs in the
ORM.
"""
from django.utils.copycompat import deepcopy
import copy
class Node(object):
"""
@ -58,8 +58,8 @@ class Node(object):
"""
obj = Node(connector=self.connector, negated=self.negated)
obj.__class__ = self.__class__
obj.children = deepcopy(self.children, memodict)
obj.subtree_parents = deepcopy(self.subtree_parents, memodict)
obj.children = copy.deepcopy(self.children, memodict)
obj.subtree_parents = copy.deepcopy(self.subtree_parents, memodict)
return obj
def __len__(self):

View File

@ -1,8 +1,4 @@
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from functools import wraps
from django.utils.decorators import decorator_from_middleware_with_args, available_attrs
from django.utils.cache import patch_cache_control, add_never_cache_headers
from django.middleware.cache import CacheMiddleware

View File

@ -1,10 +1,6 @@
from django.middleware.csrf import CsrfViewMiddleware
from django.utils.decorators import decorator_from_middleware, available_attrs
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from functools import wraps
csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
csrf_protect.__name__ = "csrf_protect"

View File

@ -2,13 +2,9 @@
Decorators for views based on HTTP headers.
"""
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from calendar import timegm
from datetime import timedelta
from functools import wraps
from django.utils.decorators import decorator_from_middleware, available_attrs
from django.utils.http import http_date, parse_http_date_safe, parse_etags, quote_etag

View File

@ -1,8 +1,4 @@
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from functools import wraps
from django.utils.cache import patch_vary_headers
from django.utils.decorators import available_attrs

View File

@ -1,8 +1,8 @@
from functools import update_wrapper
from django import http
from django.core.exceptions import ImproperlyConfigured
from django.template import RequestContext, loader
from django.template.response import TemplateResponse
from django.utils.functional import update_wrapper
from django.utils.log import getLogger
from django.utils.decorators import classonlymethod

View File

@ -3,6 +3,7 @@
# Unit tests for cache framework
# Uses whatever cache backend is set in the test settings file.
import hashlib
import os
import tempfile
import time
@ -19,7 +20,6 @@ from django.test.utils import get_warnings_state, restore_warnings_state
from django.utils import translation
from django.utils import unittest
from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
from django.utils.hashcompat import md5_constructor
from django.views.decorators.cache import cache_page
from regressiontests.cache.models import Poll, expensive_calculation
@ -850,7 +850,7 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
"""Test that keys are hashed into subdirectories correctly"""
self.cache.set("foo", "bar")
key = self.cache.make_key("foo")
keyhash = md5_constructor(key).hexdigest()
keyhash = hashlib.md5(key).hexdigest()
keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
self.assertTrue(os.path.exists(keypath))
@ -860,7 +860,7 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
"""
self.cache.set("foo", "bar")
key = self.cache.make_key("foo")
keyhash = md5_constructor(key).hexdigest()
keyhash = hashlib.md5(key).hexdigest()
keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
self.assertTrue(os.path.exists(keypath))

View File

@ -1,9 +1,9 @@
import hashlib
import time
from django.conf import settings
from django.contrib.comments.forms import CommentForm
from django.contrib.comments.models import Comment
from django.utils.hashcompat import sha_constructor
from regressiontests.comment_tests.models import Article
from regressiontests.comment_tests.tests import CommentTestCase
@ -57,7 +57,7 @@ class CommentFormTests(CommentTestCase):
# The Django 1.2 method hard-coded here:
info = (content_type, object_pk, timestamp, settings.SECRET_KEY)
security_hash = sha_constructor("".join(info)).hexdigest()
security_hash = hashlib.sha1("".join(info)).hexdigest()
d['security_hash'] = security_hash
f = CommentForm(a, data=d)

View File

@ -3,7 +3,6 @@ import sys
from django.dispatch import Signal
from django.utils import unittest
import django.utils.copycompat as copy
if sys.platform.startswith('java'):
def garbage_collect():

View File

@ -1,7 +1,6 @@
import copy
import datetime
import django.utils.copycompat as copy
from django.contrib.auth.models import User
from django.db import models

View File

@ -1,5 +1,7 @@
#! -*- coding: utf-8 -*-
import errno
import hashlib
import os
import shutil
from StringIO import StringIO
@ -10,7 +12,6 @@ from django.http.multipartparser import MultiPartParser
from django.test import TestCase, client
from django.utils import simplejson
from django.utils import unittest
from django.utils.hashcompat import sha_constructor
from models import FileModel, temp_storage, UPLOAD_TO
import uploadhandler
@ -46,10 +47,10 @@ class FileUploadTests(TestCase):
for key in post_data.keys():
try:
post_data[key + '_hash'] = sha_constructor(post_data[key].read()).hexdigest()
post_data[key + '_hash'] = hashlib.sha1(post_data[key].read()).hexdigest()
post_data[key].seek(0)
except AttributeError:
post_data[key + '_hash'] = sha_constructor(post_data[key]).hexdigest()
post_data[key + '_hash'] = hashlib.sha1(post_data[key]).hexdigest()
response = self.client.post('/file_uploads/verify/', post_data)

View File

@ -1,10 +1,10 @@
import hashlib
import os
from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse, HttpResponseServerError
from django.utils import simplejson
from models import FileModel, UPLOAD_TO
from uploadhandler import QuotaUploadHandler, ErroringUploadHandler
from django.utils.hashcompat import sha_constructor
from tests import UNICODE_FILENAME
def file_upload_view(request):
@ -37,9 +37,9 @@ def file_upload_view_verify(request):
continue
submitted_hash = form_data[key + '_hash']
if isinstance(value, UploadedFile):
new_hash = sha_constructor(value.read()).hexdigest()
new_hash = hashlib.sha1(value.read()).hexdigest()
else:
new_hash = sha_constructor(value).hexdigest()
new_hash = hashlib.sha1(value).hexdigest()
if new_hash != submitted_hash:
return HttpResponseServerError()

View File

@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import copy
import datetime
from decimal import Decimal
import re
import time
from decimal import Decimal
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import *
from django.forms.widgets import RadioFieldRenderer
from django.utils import copycompat as copy
from django.utils import formats
from django.utils.safestring import mark_safe
from django.utils.translation import activate, deactivate

View File

@ -1,7 +1,7 @@
from functools import update_wrapper
from django.conf import settings
from django.db import connection, DEFAULT_DB_ALIAS
from django.test import TestCase, skipUnlessDBFeature
from django.utils import functional
from models import Reporter, Article
@ -23,7 +23,7 @@ def ignore_not_implemented(func):
return func(*args, **kwargs)
except NotImplementedError:
return None
functional.update_wrapper(_inner, func)
update_wrapper(_inner, func)
return _inner
class IgnoreNotimplementedError(type):

View File

@ -1,10 +1,11 @@
"""
Tests for stuff in django.utils.datastructures.
"""
import copy
import pickle
import unittest
from django.utils.copycompat import copy
from django.utils.datastructures import *

View File

@ -1,6 +1,6 @@
import copy
import unittest
import django.utils.copycompat as copy
from django.utils.functional import SimpleLazyObject
class _ComplexObject(object):