[1.1.X] Fixed a bunch of Python 2.3 incompatibilities that had crept into the 1.1.X branch.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12595 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Karen Tracey 2010-02-26 05:14:36 +00:00
parent 6c031fbef7
commit 6ca3154bcd
15 changed files with 79 additions and 26 deletions

View File

@ -56,12 +56,12 @@ class ModelBase(type):
new_class.add_to_class('_meta', Options(meta, **kwargs)) new_class.add_to_class('_meta', Options(meta, **kwargs))
if not abstract: if not abstract:
new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
tuple(x.DoesNotExist tuple([x.DoesNotExist
for x in parents if hasattr(x, '_meta') and not x._meta.abstract) for x in parents if hasattr(x, '_meta') and not x._meta.abstract])
or (ObjectDoesNotExist,), module)) or (ObjectDoesNotExist,), module))
new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned', new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
tuple(x.MultipleObjectsReturned tuple([x.MultipleObjectsReturned
for x in parents if hasattr(x, '_meta') and not x._meta.abstract) for x in parents if hasattr(x, '_meta') and not x._meta.abstract])
or (MultipleObjectsReturned,), module)) or (MultipleObjectsReturned,), module))
if base_meta and not base_meta.abstract: if base_meta and not base_meta.abstract:
# Non-abstract child classes inherit some attributes from their # Non-abstract child classes inherit some attributes from their

View File

@ -1,11 +1,15 @@
import datetime import datetime
import decimal
import os import os
import re import re
import time import time
import django.utils.copycompat as copy import django.utils.copycompat as copy
try:
import decimal
except ImportError:
from django.utils import _decimal as decimal # for Python 2.3
from django.db import connection from django.db import connection
from django.db.models import signals from django.db.models import signals
from django.db.models.query_utils import QueryWrapper from django.db.models.query_utils import QueryWrapper

View File

@ -148,8 +148,8 @@ class AppCache(object):
model_list = [] model_list = []
for app in app_list: for app in app_list:
model_list.extend( model_list.extend(
model for model in app.values() [model for model in app.values()
if (not model._deferred or include_deferred) if (not model._deferred or include_deferred)]
) )
return model_list return model_list

View File

@ -12,6 +12,10 @@ from django.utils.copycompat import deepcopy
from django.utils import tree from django.utils import tree
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3.
class CyclicDependency(Exception): class CyclicDependency(Exception):
""" """

View File

@ -18,8 +18,7 @@ from django.db.models.fields import FieldDoesNotExist
from django.db.models.query_utils import select_related_descend from django.db.models.query_utils import select_related_descend
from django.db.models.sql import aggregates as base_aggregates_module from django.db.models.sql import aggregates as base_aggregates_module
from django.db.models.sql.expressions import SQLEvaluator from django.db.models.sql.expressions import SQLEvaluator
from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode, from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, ExtraWhere, AND, OR
ExtraWhere, AND, OR)
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from datastructures import EmptyResultSet, Empty, MultiJoin from datastructures import EmptyResultSet, Empty, MultiJoin
from constants import * from constants import *

View File

@ -7,7 +7,6 @@ import os
import re import re
import time import time
import urlparse import urlparse
from decimal import Decimal, DecimalException
try: try:
from cStringIO import StringIO from cStringIO import StringIO
except ImportError: except ImportError:
@ -18,6 +17,16 @@ import django.utils.copycompat as copy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode, smart_str from django.utils.encoding import smart_unicode, smart_str
# Python 2.3 fallbacks
try:
from decimal import Decimal, DecimalException
except ImportError:
from django.utils._decimal import Decimal, DecimalException
try:
set
except NameError:
from sets import Set as set
from util import ErrorList, ValidationError from util import ErrorList, ValidationError
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget

View File

@ -2,6 +2,11 @@
HTML Widget classes HTML Widget classes
""" """
try:
set
except NameError:
from sets import Set as set # Python 2.3 fallback
import django.utils.copycompat as copy import django.utils.copycompat as copy
from itertools import chain from itertools import chain
from django.conf import settings from django.conf import settings

View File

@ -2,6 +2,11 @@ from types import GeneratorType
from django.utils.copycompat import deepcopy from django.utils.copycompat import deepcopy
# Python 2.3 doesn't have set as a builtin
try:
set
except NameError:
from sets import Set as set
class MergeDict(object): class MergeDict(object):
""" """

View File

@ -67,9 +67,15 @@ def is_iterable(x):
else: else:
return True return True
def sorted(in_value): def sorted(in_value, key=None):
"A naive implementation of sorted" "A naive implementation of sorted"
out_value = in_value[:] if key:
out_value = [(key(item), index, item) for index, item in enumerate(in_value)]
else:
out_value = in_value[:]
out_value.sort() out_value.sort()
return out_value if key:
return [item[2] for item in out_value]
else:
return out_value

View File

@ -141,12 +141,12 @@ class ClientTest(TestCase):
def test_redirect_http(self): def test_redirect_http(self):
"GET a URL that redirects to an http URI" "GET a URL that redirects to an http URI"
response = self.client.get('/test_client/http_redirect_view/',follow=True) response = self.client.get('/test_client/http_redirect_view/',follow=True)
self.assertFalse(response.test_was_secure_request) self.failIf(response.test_was_secure_request)
def test_redirect_https(self): def test_redirect_https(self):
"GET a URL that redirects to an https URI" "GET a URL that redirects to an https URI"
response = self.client.get('/test_client/https_redirect_view/',follow=True) response = self.client.get('/test_client/https_redirect_view/',follow=True)
self.assertTrue(response.test_was_secure_request) self.failUnless(response.test_was_secure_request)
def test_notfound_response(self): def test_notfound_response(self):
"GET a URL that responds as '404:Not Found'" "GET a URL that responds as '404:Not Found'"

View File

@ -42,7 +42,7 @@ MergeDict can merge MultiValueDicts
True True
>>> sorted(mm.items(), key=lambda k: k[0]) >>> sorted(mm.items(), key=lambda k: k[0])
[('key1', 'value1'), ('key2', 'value3'), ('key4', 'value6')] [('key1', 'value1'), ('key2', 'value3'), ('key4', 'value6')]
>>> [(k,mm.getlist(k)) for k in sorted(mm)] >>> [(k,mm.getlist(k)) for k in sorted(mm.keys())]
[('key1', ['value1']), ('key2', ['value2', 'value3']), ('key4', ['value5', 'value6'])] [('key1', ['value1']), ('key2', ['value2', 'value3']), ('key4', ['value5', 'value6'])]
### MultiValueDict ########################################################## ### MultiValueDict ##########################################################
@ -106,7 +106,17 @@ True
>>> d.pop('one', 'missing') >>> d.pop('one', 'missing')
'missing' 'missing'
>>> SortedDict((i, i) for i in xrange(3)) This SortedDict test tests that it works properly when called with a
a generator expression. But having that syntax anywhere in the test
when run under Python 2.3 will cause a SyntaxError. Thus the rigamorale
with eval so that the test will run and test what it is intended to test
when run on Pythons > 2.3, but not cause a SyntaxError when run on Python 2.3.
>>> import sys
>>> if sys.version_info[0] == 2 and sys.version_info[1] == 3:
... arg = '[(i, i) for i in xrange(3)]'
... else:
... arg = '((i, i) for i in xrange(3))'
>>> SortedDict(eval(arg))
{0: 0, 1: 1, 2: 2} {0: 0, 1: 1, 2: 2}
We don't know which item will be popped in popitem(), so we'll just check that We don't know which item will be popped in popitem(), so we'll just check that
@ -171,3 +181,9 @@ AttributeError: Object is immutable!
'Normal: a. Modified: *a' 'Normal: a. Modified: *a'
""" """
try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3

View File

@ -6,6 +6,11 @@ from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import connection, models from django.db import connection, models
try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3
class Item(models.Model): class Item(models.Model):
name = models.CharField(max_length=15) name = models.CharField(max_length=15)
text = models.TextField(default="xyzzy") text = models.TextField(default="xyzzy")

View File

@ -185,4 +185,4 @@ class NoInlineDeletionTest(TestCase):
inline = MediaPermanentInline(EpisodePermanent, fake_site) inline = MediaPermanentInline(EpisodePermanent, fake_site)
fake_request = object() fake_request = object()
formset = inline.get_formset(fake_request) formset = inline.get_formset(fake_request)
self.assertFalse(formset.can_delete) self.failIf(formset.can_delete)

View File

@ -63,12 +63,12 @@ class GenericRelationTests(TestCase):
# search with a non-matching note and a matching org name # search with a non-matching note and a matching org name
qs = Contact.objects.filter(Q(notes__note__icontains=r'other note') | qs = Contact.objects.filter(Q(notes__note__icontains=r'other note') |
Q(organizations__name__icontains=r'org name')) Q(organizations__name__icontains=r'org name'))
self.assertTrue(org_contact in qs) self.failUnless(org_contact in qs)
# search again, with the same query parameters, in reverse order # search again, with the same query parameters, in reverse order
qs = Contact.objects.filter( qs = Contact.objects.filter(
Q(organizations__name__icontains=r'org name') | Q(organizations__name__icontains=r'org name') |
Q(notes__note__icontains=r'other note')) Q(notes__note__icontains=r'other note'))
self.assertTrue(org_contact in qs) self.failUnless(org_contact in qs)

View File

@ -15,7 +15,7 @@ class USLocalflavorTests(TestCase):
def test_required(self): def test_required(self):
"""Test that required USStateFields throw appropriate errors.""" """Test that required USStateFields throw appropriate errors."""
form = PlaceForm({'state':'GA', 'name':'Place in GA'}) form = PlaceForm({'state':'GA', 'name':'Place in GA'})
self.assertFalse(form.is_valid()) self.failIf(form.is_valid())
self.assertEqual(form.errors['state_req'], [u'This field is required.']) self.assertEqual(form.errors['state_req'], [u'This field is required.'])
def test_field_blank_option(self): def test_field_blank_option(self):