Skip to content

Commit

Permalink
[1.1.X] Fixed a bunch of Python 2.3 incompatibilities that had crept …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
kmtracey committed Feb 26, 2010
1 parent 6c031fb commit 6ca3154
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 26 deletions.
8 changes: 4 additions & 4 deletions django/db/models/base.py
Expand Up @@ -56,12 +56,12 @@ def __new__(cls, name, bases, attrs):
new_class.add_to_class('_meta', Options(meta, **kwargs))
if not abstract:
new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
tuple(x.DoesNotExist
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
tuple([x.DoesNotExist
for x in parents if hasattr(x, '_meta') and not x._meta.abstract])
or (ObjectDoesNotExist,), module))
new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
tuple(x.MultipleObjectsReturned
for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
tuple([x.MultipleObjectsReturned
for x in parents if hasattr(x, '_meta') and not x._meta.abstract])
or (MultipleObjectsReturned,), module))
if base_meta and not base_meta.abstract:
# Non-abstract child classes inherit some attributes from their
Expand Down
8 changes: 6 additions & 2 deletions django/db/models/fields/__init__.py
@@ -1,11 +1,15 @@
import datetime
import decimal
import os
import re
import time

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.models import signals
from django.db.models.query_utils import QueryWrapper
Expand Down Expand Up @@ -437,7 +441,7 @@ def to_python(self, value):

def get_db_prep_value(self, value):
return self.to_python(value)

def formfield(self, **kwargs):
defaults = {'max_length': self.max_length}
defaults.update(kwargs)
Expand Down
4 changes: 2 additions & 2 deletions django/db/models/loading.py
Expand Up @@ -148,8 +148,8 @@ def get_models(self, app_mod=None, include_deferred=False):
model_list = []
for app in app_list:
model_list.extend(
model for model in app.values()
if (not model._deferred or include_deferred)
[model for model in app.values()
if (not model._deferred or include_deferred)]
)
return model_list

Expand Down
4 changes: 4 additions & 0 deletions django/db/models/query_utils.py
Expand Up @@ -12,6 +12,10 @@
from django.utils import tree
from django.utils.datastructures import SortedDict

try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3.

class CyclicDependency(Exception):
"""
Expand Down
3 changes: 1 addition & 2 deletions django/db/models/sql/query.py
Expand Up @@ -18,8 +18,7 @@
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.expressions import SQLEvaluator
from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
ExtraWhere, AND, OR)
from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, ExtraWhere, AND, OR
from django.core.exceptions import FieldError
from datastructures import EmptyResultSet, Empty, MultiJoin
from constants import *
Expand Down
13 changes: 11 additions & 2 deletions django/forms/fields.py
Expand Up @@ -7,7 +7,6 @@
import re
import time
import urlparse
from decimal import Decimal, DecimalException
try:
from cStringIO import StringIO
except ImportError:
Expand All @@ -18,6 +17,16 @@
from django.utils.translation import ugettext_lazy as _
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 widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget

Expand Down Expand Up @@ -489,7 +498,7 @@ def clean(self, data, initial=None):
return None
elif not data and initial:
return initial

# Try to import PIL in either of the two ways it can end up installed.
try:
from PIL import Image
Expand Down
5 changes: 5 additions & 0 deletions django/forms/widgets.py
Expand Up @@ -2,6 +2,11 @@
HTML Widget classes
"""

try:
set
except NameError:
from sets import Set as set # Python 2.3 fallback

import django.utils.copycompat as copy
from itertools import chain
from django.conf import settings
Expand Down
5 changes: 5 additions & 0 deletions django/utils/datastructures.py
Expand Up @@ -2,6 +2,11 @@

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):
"""
Expand Down
12 changes: 9 additions & 3 deletions django/utils/itercompat.py
Expand Up @@ -67,9 +67,15 @@ def is_iterable(x):
else:
return True

def sorted(in_value):
def sorted(in_value, key=None):
"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()
return out_value
if key:
return [item[2] for item in out_value]
else:
return out_value

4 changes: 2 additions & 2 deletions tests/modeltests/test_client/models.py
Expand Up @@ -141,12 +141,12 @@ def test_follow_redirect(self):
def test_redirect_http(self):
"GET a URL that redirects to an http URI"
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):
"GET a URL that redirects to an https URI"
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):
"GET a URL that responds as '404:Not Found'"
Expand Down
20 changes: 18 additions & 2 deletions tests/regressiontests/datastructures/tests.py
Expand Up @@ -42,7 +42,7 @@
True
>>> sorted(mm.items(), key=lambda k: k[0])
[('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'])]
### MultiValueDict ##########################################################
Expand Down Expand Up @@ -106,7 +106,17 @@
>>> d.pop('one', '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}
We don't know which item will be popped in popitem(), so we'll just check that
Expand Down Expand Up @@ -171,3 +181,9 @@
'Normal: a. Modified: *a'
"""

try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3

5 changes: 5 additions & 0 deletions tests/regressiontests/defer_regress/models.py
Expand Up @@ -6,6 +6,11 @@
from django.contrib.contenttypes.models import ContentType
from django.db import connection, models

try:
sorted
except NameError:
from django.utils.itercompat import sorted # For Python 2.3

class Item(models.Model):
name = models.CharField(max_length=15)
text = models.TextField(default="xyzzy")
Expand Down
2 changes: 1 addition & 1 deletion tests/regressiontests/generic_inline_admin/tests.py
Expand Up @@ -185,4 +185,4 @@ def test_no_deletion(self):
inline = MediaPermanentInline(EpisodePermanent, fake_site)
fake_request = object()
formset = inline.get_formset(fake_request)
self.assertFalse(formset.can_delete)
self.failIf(formset.can_delete)
4 changes: 2 additions & 2 deletions tests/regressiontests/generic_relations_regress/tests.py
Expand Up @@ -63,12 +63,12 @@ def test_q_object_or(self):
# search with a non-matching note and a matching org name
qs = Contact.objects.filter(Q(notes__note__icontains=r'other note') |
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
qs = Contact.objects.filter(
Q(organizations__name__icontains=r'org name') |
Q(notes__note__icontains=r'other note'))
self.assertTrue(org_contact in qs)
self.failUnless(org_contact in qs)



8 changes: 4 additions & 4 deletions tests/regressiontests/localflavor/tests.py
Expand Up @@ -5,19 +5,19 @@
class USLocalflavorTests(TestCase):
def setUp(self):
self.form = PlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})

def test_get_display_methods(self):
"""Test that the get_*_display() methods are added to the model instances."""
place = self.form.save()
self.assertEqual(place.get_state_display(), 'Georgia')
self.assertEqual(place.get_state_req_display(), 'North Carolina')

def test_required(self):
"""Test that required USStateFields throw appropriate errors."""
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.'])

def test_field_blank_option(self):
"""Test that the empty option is there."""
state_select_html = """\
Expand Down

0 comments on commit 6ca3154

Please sign in to comment.