Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
  • Loading branch information...
commit 13864703bc1d5dd4dac63c96c6a4b42a392bc57f 1 parent a87be35
@adrianholovaty adrianholovaty authored
Showing with 113 additions and 326 deletions.
  1. +11 −14 django/core/mail/backends/console.py
  2. +1 −4 django/core/mail/message.py
  3. +0 −5 django/core/management/validation.py
  4. +0 −1  django/db/__init__.py
  5. +3 −4 django/db/backends/util.py
  6. +4 −3 django/db/models/base.py
  7. +2 −3 django/db/models/deletion.py
  8. +0 −2  django/db/models/expressions.py
  9. +1 −2  django/db/models/fields/__init__.py
  10. +0 −2  django/db/models/fields/files.py
  11. +1 −1  django/db/models/manager.py
  12. +0 −5 django/db/models/options.py
  13. +2 −2 django/db/models/query.py
  14. +0 −1  django/db/models/query_utils.py
  15. +7 −7 django/db/models/sql/query.py
  16. +4 −17 django/db/transaction.py
  17. +1 −1  django/dispatch/saferef.py
  18. +1 −5 django/forms/extras/widgets.py
  19. +1 −1  django/forms/fields.py
  20. +2 −2 django/forms/forms.py
  21. +3 −2 django/forms/widgets.py
  22. +1 −1  django/http/__init__.py
  23. +2 −2 django/middleware/common.py
  24. +3 −4 django/middleware/csrf.py
  25. +4 −3 django/template/base.py
  26. +2 −5 django/template/defaultfilters.py
  27. +2 −2 django/template/loaders/cached.py
  28. +2 −2 django/templatetags/cache.py
  29. +1 −1  django/test/client.py
  30. +0 −6 django/test/simple.py
  31. +3 −12 django/test/testcases.py
  32. +5 −5 django/utils/cache.py
  33. +0 −14 django/utils/copycompat.py
  34. +4 −8 django/utils/crypto.py
  35. +3 −6 django/utils/datastructures.py
  36. +1 −4 django/utils/decorators.py
  37. +3 −58 django/utils/functional.py
  38. +0 −20 django/utils/hashcompat.py
  39. +0 −12 django/utils/itercompat.py
  40. +4 −33 django/utils/log.py
  41. +3 −3 django/utils/tree.py
  42. +1 −5 django/views/decorators/cache.py
  43. +1 −5 django/views/decorators/csrf.py
  44. +1 −5 django/views/decorators/http.py
  45. +1 −5 django/views/decorators/vary.py
  46. +1 −1  django/views/generic/base.py
  47. +3 −3 tests/regressiontests/cache/tests.py
  48. +2 −2 tests/regressiontests/comment_tests/tests/comment_form_tests.py
  49. +0 −1  tests/regressiontests/dispatch/tests/test_dispatcher.py
  50. +1 −2  tests/regressiontests/extra_regress/models.py
  51. +4 −3 tests/regressiontests/file_uploads/tests.py
  52. +3 −3 tests/regressiontests/file_uploads/views.py
  53. +3 −2 tests/regressiontests/forms/tests/widgets.py
  54. +2 −2 tests/regressiontests/introspection/tests.py
  55. +2 −1  tests/regressiontests/utils/datastructures.py
  56. +1 −1  tests/regressiontests/utils/simplelazyobject.py
View
25 django/core/mail/backends/console.py
@@ -18,20 +18,17 @@ def send_messages(self, email_messages):
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
5 django/core/mail/message.py
@@ -3,10 +3,7 @@
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
5 django/core/management/validation.py
@@ -4,11 +4,6 @@
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
1  django/db/__init__.py
@@ -3,7 +3,6 @@
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
7 django/db/backends/util.py
@@ -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
7 django/db/models/base.py
@@ -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.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
5 django/db/models/deletion.py
@@ -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
2  django/db/models/expressions.py
@@ -1,7 +1,5 @@
import datetime
-
from django.utils import tree
-from django.utils.copycompat import deepcopy
class ExpressionNode(tree.Node):
"""
View
3  django/db/models/fields/__init__.py
@@ -1,3 +1,4 @@
+import copy
import datetime
import decimal
import re
@@ -5,8 +6,6 @@
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
2  django/db/models/fields/files.py
@@ -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
2  django/db/models/manager.py
@@ -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
5 django/db/models/options.py
@@ -11,11 +11,6 @@
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
4 django/db/models/query.py
@@ -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 @@
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 @@ def __deepcopy__(self, memo):
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
1  django/db/models/query_utils.py
@@ -7,7 +7,6 @@
"""
import weakref
-from django.utils.copycompat import deepcopy
from django.db.backends import util
from django.utils import tree
View
14 django/db/models/sql/query.py
@@ -7,7 +7,7 @@
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 @@ def clone(self, klass=None, memo=None, **kwargs):
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 @@ def clone(self, klass=None, memo=None, **kwargs):
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 @@ def combine(self, rhs, connector):
# 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 @@ def combine(self, rhs, connector):
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
21 django/db/transaction.py
@@ -11,12 +11,9 @@
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 @@ def __exit__(self, exc_type, exc_value, traceback):
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
2  django/dispatch/saferef.py
@@ -230,7 +230,7 @@ def __call__(self):
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
6 django/forms/extras/widgets.py
@@ -68,11 +68,7 @@ def render(self, name, value, attrs=None):
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
2  django/forms/fields.py
@@ -2,6 +2,7 @@
Field classes.
"""
+import copy
import datetime
import os
import re
@@ -16,7 +17,6 @@
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
4 django/forms/forms.py
@@ -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 @@ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
# 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
5 django/forms/widgets.py
@@ -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
2  django/http/__init__.py
@@ -364,7 +364,7 @@ def __copy__(self):
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
4 django/middleware/common.py
@@ -1,3 +1,4 @@
+import hashlib
import re
from django.conf import settings
@@ -5,7 +6,6 @@
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 @@ def process_response(self, request, response):
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
7 django/middleware/csrf.py
@@ -5,6 +5,7 @@
against request forgeries from other sites.
"""
+import hashlib
import itertools
import re
import random
@@ -12,7 +13,6 @@
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
7 django/template/base.py
@@ -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 @@ def render(self, context):
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 @@ def render(self, context):
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
7 django/template/defaultfilters.py
@@ -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
4 django/template/loaders/cached.py
@@ -3,10 +3,10 @@
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 @@ def load_template(self, template_name, template_dirs=None):
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
4 django/templatetags/cache.py
@@ -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 @@ def render(self, context):
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
2  django/test/client.py
@@ -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
6 django/test/simple.py
@@ -7,12 +7,6 @@
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
15 django/test/testcases.py
@@ -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.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 @@ def assertNumQueries(self, num, func=None, *args, **kwargs):
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
10 django/utils/cache.py
@@ -17,6 +17,7 @@
"Accept-language" header.
"""
+import hashlib
import re
import time
@@ -24,7 +25,6 @@
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
14 django/utils/copycompat.py
@@ -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
12 django/utils/crypto.py
@@ -1,11 +1,10 @@
"""
Django's standard crypto functions and utilities.
"""
-import hmac
+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
9 django/utils/datastructures.py
@@ -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 @@ def __init__(self, data=None):
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 @@ def __copy__(self):
])
def __deepcopy__(self, memo=None):
- import django.utils.copycompat as copy
if memo is None:
memo = {}
result = self.__class__()
@@ -365,7 +362,7 @@ def itervalues(self):
def copy(self):
"""Returns a shallow copy of this object."""
- return copy(self)
+ return copy.copy(self)
def update(self, *args, **kwargs):
"""
View
5 django/utils/decorators.py
@@ -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
61 django/utils/functional.py
@@ -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 @@ def __deepcopy__(self, memo):
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
20 django/utils/hashcompat.py
@@ -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
12 django/utils/itercompat.py
@@ -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
37 django/utils/log.py
@@ -18,27 +18,7 @@ def emit(self, record):
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 @@ def getLogger(name=None):
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 @@ def emit(self, record):
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 @@ def emit(self, record):
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
6 django/utils/tree.py
@@ -3,7 +3,7 @@
ORM.
"""
-from django.utils.copycompat import deepcopy
+import copy
class Node(object):
"""
@@ -58,8 +58,8 @@ def __deepcopy__(self, memodict):
"""
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
6 django/views/decorators/cache.py
@@ -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
6 django/views/decorators/csrf.py
@@ -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
6 django/views/decorators/http.py
@@ -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
6 django/views/decorators/vary.py
@@ -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
2  django/views/generic/base.py
@@ -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
6 tests/regressiontests/cache/tests.py
@@ -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.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 @@ def test_hashing(self):
"""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 @@ def test_subdirectory_removal(self):
"""
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
4 tests/regressiontests/comment_tests/tests/comment_form_tests.py
@@ -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 @@ def testDjango12Hash(self):
# 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
1  tests/regressiontests/dispatch/tests/test_dispatcher.py
@@ -3,7 +3,6 @@
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
3  tests/regressiontests/extra_regress/models.py
@@ -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
7 tests/regressiontests/file_uploads/tests.py
@@ -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.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 @@ def test_large_upload(self):
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
6 tests/regressiontests/file_uploads/views.py
@@ -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
5 tests/regressiontests/forms/tests/widgets.py
@@ -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
4 tests/regressiontests/introspection/tests.py
@@ -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 _inner(*args, **kwargs):
return func(*args, **kwargs)
except NotImplementedError:
return None
- functional.update_wrapper(_inner, func)
+ update_wrapper(_inner, func)
return _inner
class IgnoreNotimplementedError(type):
View
3  tests/regressiontests/utils/datastructures.py
@@ -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
2  tests/regressiontests/utils/simplelazyobject.py
@@ -1,6 +1,6 @@
+import copy
import unittest
-import django.utils.copycompat as copy
from django.utils.functional import SimpleLazyObject
class _ComplexObject(object):
Please sign in to comment.
Something went wrong with that request. Please try again.