瀏覽代碼

[py3] Added Python 3 compatibility for xrange.

Aymeric Augustin 12 年之前
父節點
當前提交
a84d79f572
共有 32 個文件被更改,包括 77 次插入53 次删除
  1. 1 0
      django/contrib/gis/gdal/datasource.py
  2. 1 0
      django/contrib/gis/gdal/feature.py
  3. 1 0
      django/contrib/gis/gdal/geometries.py
  4. 1 0
      django/contrib/gis/gdal/layer.py
  5. 1 0
      django/contrib/gis/gdal/tests/test_geom.py
  6. 5 4
      django/contrib/gis/geos/collections.py
  7. 1 0
      django/contrib/gis/geos/coordseq.py
  8. 2 1
      django/contrib/gis/geos/linestring.py
  9. 1 0
      django/contrib/gis/geos/mutable_list.py
  10. 1 0
      django/contrib/gis/geos/point.py
  11. 1 0
      django/contrib/gis/geos/polygon.py
  12. 1 0
      django/contrib/gis/geos/prototypes/misc.py
  13. 1 0
      django/contrib/gis/geos/tests/test_geos.py
  14. 1 0
      django/contrib/gis/maps/google/gmap.py
  15. 11 10
      django/contrib/gis/maps/google/zoom.py
  16. 2 2
      django/contrib/localflavor/mx/forms.py
  17. 3 3
      django/contrib/localflavor/tr/forms.py
  18. 5 5
      django/contrib/messages/tests/base.py
  19. 1 1
      django/contrib/messages/tests/cookie.py
  20. 1 0
      django/contrib/sessions/backends/cache.py
  21. 1 0
      django/db/models/sql/where.py
  22. 20 19
      django/dispatch/dispatcher.py
  23. 1 0
      django/forms/formsets.py
  24. 1 0
      django/utils/crypto.py
  25. 1 1
      django/utils/importlib.py
  26. 1 0
      django/utils/ipv6.py
  27. 1 0
      tests/modeltests/delete/tests.py
  28. 2 2
      tests/modeltests/many_to_one_null/tests.py
  29. 3 2
      tests/regressiontests/backends/tests.py
  30. 2 2
      tests/regressiontests/dispatch/tests/test_saferef.py
  31. 1 0
      tests/regressiontests/middleware/tests.py
  32. 1 1
      tests/regressiontests/utils/datastructures.py

+ 1 - 0
django/contrib/gis/gdal/datasource.py

@@ -46,6 +46,7 @@ from django.contrib.gis.gdal.layer import Layer
 from django.contrib.gis.gdal.prototypes import ds as capi
 
 from django.utils import six
+from django.utils.six.moves import xrange
 
 # For more information, see the OGR C API source code:
 #  http://www.gdal.org/ogr/ogr__api_8h.html

+ 1 - 0
django/contrib/gis/gdal/feature.py

@@ -8,6 +8,7 @@ from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType
 from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api
 
 from django.utils import six
+from django.utils.six.moves import xrange
 
 # For more information, see the OGR C API source code:
 #  http://www.gdal.org/ogr/ogr__api_8h.html

+ 1 - 0
django/contrib/gis/gdal/geometries.py

@@ -58,6 +58,7 @@ from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
 from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex
 
 from django.utils import six
+from django.utils.six.moves import xrange
 
 # For more information, see the OGR C API source code:
 #  http://www.gdal.org/ogr/ogr__api_8h.html

+ 1 - 0
django/contrib/gis/gdal/layer.py

@@ -15,6 +15,7 @@ from django.contrib.gis.gdal.srs import SpatialReference
 from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api, srs as srs_api
 
 from django.utils import six
+from django.utils.six.moves import xrange
 
 # For more information, see the OGR C API source code:
 #  http://www.gdal.org/ogr/ogr__api_8h.html

+ 1 - 0
django/contrib/gis/gdal/tests/test_geom.py

@@ -7,6 +7,7 @@ except ImportError:
 from django.contrib.gis.gdal import (OGRGeometry, OGRGeomType, OGRException,
     OGRIndexError, SpatialReference, CoordTransform, GDAL_VERSION)
 from django.contrib.gis.geometry.test_data import TestDataMixin
+from django.utils.six.moves import xrange
 from django.utils import unittest
 
 class OGRGeomTest(unittest.TestCase, TestDataMixin):

+ 5 - 4
django/contrib/gis/geos/collections.py

@@ -10,6 +10,7 @@ from django.contrib.gis.geos.linestring import LineString, LinearRing
 from django.contrib.gis.geos.point import Point
 from django.contrib.gis.geos.polygon import Polygon
 from django.contrib.gis.geos import prototypes as capi
+from django.utils.six.moves import xrange
 
 class GeometryCollection(GEOSGeometry):
     _typeid = 7
@@ -100,11 +101,11 @@ class MultiLineString(GeometryCollection):
 
     @property
     def merged(self):
-        """ 
-        Returns a LineString representing the line merge of this 
+        """
+        Returns a LineString representing the line merge of this
         MultiLineString.
-        """ 
-        return self._topology(capi.geos_linemerge(self.ptr))         
+        """
+        return self._topology(capi.geos_linemerge(self.ptr))
 
 class MultiPolygon(GeometryCollection):
     _allowed = Polygon

+ 1 - 0
django/contrib/gis/geos/coordseq.py

@@ -8,6 +8,7 @@ from django.contrib.gis.geos.base import GEOSBase, numpy
 from django.contrib.gis.geos.error import GEOSException, GEOSIndexError
 from django.contrib.gis.geos.libgeos import CS_PTR
 from django.contrib.gis.geos import prototypes as capi
+from django.utils.six.moves import xrange
 
 class GEOSCoordSeq(GEOSBase):
     "The internal representation of a list of coordinates inside a Geometry."

+ 2 - 1
django/contrib/gis/geos/linestring.py

@@ -4,6 +4,7 @@ from django.contrib.gis.geos.error import GEOSException
 from django.contrib.gis.geos.geometry import GEOSGeometry
 from django.contrib.gis.geos.point import Point
 from django.contrib.gis.geos import prototypes as capi
+from django.utils.six.moves import xrange
 
 class LineString(GEOSGeometry):
     _init_func = capi.create_linestring
@@ -128,7 +129,7 @@ class LineString(GEOSGeometry):
     @property
     def merged(self):
         "Returns the line merge of this LineString."
-        return self._topology(capi.geos_linemerge(self.ptr))   
+        return self._topology(capi.geos_linemerge(self.ptr))
 
     @property
     def x(self):

+ 1 - 0
django/contrib/gis/geos/mutable_list.py

@@ -10,6 +10,7 @@ Author: Aryeh Leib Taurog.
 """
 from django.utils.functional import total_ordering
 from django.utils import six
+from django.utils.six.moves import xrange
 
 @total_ordering
 class ListMixin(object):

+ 1 - 0
django/contrib/gis/geos/point.py

@@ -3,6 +3,7 @@ from django.contrib.gis.geos.error import GEOSException
 from django.contrib.gis.geos.geometry import GEOSGeometry
 from django.contrib.gis.geos import prototypes as capi
 from django.utils import six
+from django.utils.six.moves import xrange
 
 class Point(GEOSGeometry):
     _minlength = 2

+ 1 - 0
django/contrib/gis/geos/polygon.py

@@ -4,6 +4,7 @@ from django.contrib.gis.geos.libgeos import get_pointer_arr, GEOM_PTR
 from django.contrib.gis.geos.linestring import LinearRing
 from django.contrib.gis.geos import prototypes as capi
 from django.utils import six
+from django.utils.six.moves import xrange
 
 class Polygon(GEOSGeometry):
     _minlength = 1

+ 1 - 0
django/contrib/gis/geos/prototypes/misc.py

@@ -7,6 +7,7 @@ from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE
 from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string
 from django.contrib.gis.geos.prototypes.geom import geos_char_p
 from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
+from django.utils.six.moves import xrange
 
 __all__ = ['geos_area', 'geos_distance', 'geos_length']
 

+ 1 - 0
django/contrib/gis/geos/tests/test_geos.py

@@ -9,6 +9,7 @@ from django.contrib.gis.geos.libgeos import GEOS_PREPARE
 from django.contrib.gis.geometry.test_data import TestDataMixin
 
 from django.utils import six
+from django.utils.six.moves import xrange
 from django.utils import unittest
 
 

+ 1 - 0
django/contrib/gis/maps/google/gmap.py

@@ -2,6 +2,7 @@ from django.conf import settings
 from django.template.loader import render_to_string
 from django.utils.html import format_html
 from django.utils.safestring import mark_safe
+from django.utils.six.moves import xrange
 
 from django.contrib.gis.maps.google.overlays import GPolygon, GPolyline, GMarker
 

+ 11 - 10
django/contrib/gis/maps/google/zoom.py

@@ -1,5 +1,6 @@
 from django.contrib.gis.geos import GEOSGeometry, LinearRing, Polygon, Point
 from django.contrib.gis.maps.google.gmap import GoogleMapException
+from django.utils.six.moves import xrange
 from math import pi, sin, log, exp, atan
 
 # Constants used for degree to radian conversion, and vice-versa.
@@ -20,21 +21,21 @@ class GoogleZoom(object):
 
     "Google Maps Hacks" may be found at http://safari.oreilly.com/0596101619
     """
-    
+
     def __init__(self, num_zoom=19, tilesize=256):
         "Initializes the Google Zoom object."
         # Google's tilesize is 256x256, square tiles are assumed.
         self._tilesize = tilesize
-        
+
         # The number of zoom levels
         self._nzoom = num_zoom
 
-        # Initializing arrays to hold the parameters for each one of the 
+        # Initializing arrays to hold the parameters for each one of the
         # zoom levels.
         self._degpp = [] # Degrees per pixel
         self._radpp = [] # Radians per pixel
         self._npix  = [] # 1/2 the number of pixels for a tile at the given zoom level
-        
+
         # Incrementing through the zoom levels and populating the parameter arrays.
         z = tilesize # The number of pixels per zoom level.
         for i in xrange(num_zoom):
@@ -70,9 +71,9 @@ class GoogleZoom(object):
         # with with the number of degrees/pixel at the given zoom level.
         px_x = round(npix + (lon * self._degpp[zoom]))
 
-        # Creating the factor, and ensuring that 1 or -1 is not passed in as the 
+        # Creating the factor, and ensuring that 1 or -1 is not passed in as the
         # base to the logarithm.  Here's why:
-        #  if fac = -1, we'll get log(0) which is undefined; 
+        #  if fac = -1, we'll get log(0) which is undefined;
         #  if fac =  1, our logarithm base will be divided by 0, also undefined.
         fac = min(max(sin(DTOR * lat), -0.9999), 0.9999)
 
@@ -98,7 +99,7 @@ class GoogleZoom(object):
 
         # Returning the longitude, latitude coordinate pair.
         return (lon, lat)
-    
+
     def tile(self, lonlat, zoom):
         """
         Returns a Polygon  corresponding to the region represented by a fictional
@@ -119,7 +120,7 @@ class GoogleZoom(object):
 
         # Constructing the Polygon, representing the tile and returning.
         return Polygon(LinearRing(ll, (ll[0], ur[1]), ur, (ur[0], ll[1]), ll), srid=4326)
-        
+
     def get_zoom(self, geom):
         "Returns the optimal Zoom level for the given geometry."
         # Checking the input type.
@@ -139,10 +140,10 @@ class GoogleZoom(object):
             # When we span more than one tile, this is an approximately good
             # zoom level.
             if (env_w > tile_w) or (env_h > tile_h):
-                if z == 0: 
+                if z == 0:
                     raise GoogleMapException('Geometry width and height should not exceed that of the Earth.')
                 return z-1
-        
+
         # Otherwise, we've zoomed in to the max.
         return self._nzoom-1
 

+ 2 - 2
django/contrib/localflavor/mx/forms.py

@@ -148,7 +148,7 @@ class MXRFCField(RegexField):
         if len(rfc) == 11:
             rfc = '-' + rfc
 
-        sum_ = sum(i * chars.index(c) for i, c in zip(reversed(xrange(14)), rfc))
+        sum_ = sum(i * chars.index(c) for i, c in zip(reversed(range(14)), rfc))
         checksum = 11 - sum_ % 11
 
         if checksum == 10:
@@ -215,7 +215,7 @@ class MXCURPField(RegexField):
     def _checksum(self, value):
         chars = '0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ'
 
-        s = sum(i * chars.index(c) for i, c in zip(reversed(xrange(19)), value))
+        s = sum(i * chars.index(c) for i, c in zip(reversed(range(19)), value))
         checksum = 10 - s % 10
 
         if checksum == 10:

+ 3 - 3
django/contrib/localflavor/tr/forms.py

@@ -80,10 +80,10 @@ class TRIdentificationNumberField(Field):
             raise ValidationError(self.error_messages['invalid'])
         if int(value[0]) == 0:
             raise ValidationError(self.error_messages['invalid'])
-        chksum = (sum([int(value[i]) for i in xrange(0,9,2)])*7-
-                          sum([int(value[i]) for i in xrange(1,9,2)])) % 10
+        chksum = (sum([int(value[i]) for i in range(0, 9, 2)]) * 7 -
+                          sum([int(value[i]) for i in range(1, 9, 2)])) % 10
         if chksum != int(value[9]) or \
-           (sum([int(value[i]) for i in xrange(10)]) % 10) != int(value[10]):
+           (sum([int(value[i]) for i in range(10)]) % 10) != int(value[10]):
             raise ValidationError(self.error_messages['invalid'])
         return value
 

+ 5 - 5
django/contrib/messages/tests/base.py

@@ -152,7 +152,7 @@ class BaseTest(TestCase):
         cycle.
         """
         data = {
-            'messages': ['Test message %d' % x for x in xrange(10)],
+            'messages': ['Test message %d' % x for x in range(10)],
         }
         show_url = reverse('django.contrib.messages.tests.urls.show')
         for level in ('debug', 'info', 'success', 'warning', 'error'):
@@ -170,7 +170,7 @@ class BaseTest(TestCase):
     @override_settings(MESSAGE_LEVEL=constants.DEBUG)
     def test_with_template_response(self):
         data = {
-            'messages': ['Test message %d' % x for x in xrange(10)],
+            'messages': ['Test message %d' % x for x in range(10)],
         }
         show_url = reverse('django.contrib.messages.tests.urls.show_template_response')
         for level in self.levels.keys():
@@ -194,7 +194,7 @@ class BaseTest(TestCase):
         before a GET.
         """
         data = {
-            'messages': ['Test message %d' % x for x in xrange(10)],
+            'messages': ['Test message %d' % x for x in range(10)],
         }
         show_url = reverse('django.contrib.messages.tests.urls.show')
         messages = []
@@ -226,7 +226,7 @@ class BaseTest(TestCase):
         when one attempts to store a message.
         """
         data = {
-            'messages': ['Test message %d' % x for x in xrange(10)],
+            'messages': ['Test message %d' % x for x in range(10)],
         }
         show_url = reverse('django.contrib.messages.tests.urls.show')
         for level in ('debug', 'info', 'success', 'warning', 'error'):
@@ -251,7 +251,7 @@ class BaseTest(TestCase):
         raised if 'fail_silently' = True
         """
         data = {
-            'messages': ['Test message %d' % x for x in xrange(10)],
+            'messages': ['Test message %d' % x for x in range(10)],
             'fail_silently': True,
         }
         show_url = reverse('django.contrib.messages.tests.urls.show')

+ 1 - 1
django/contrib/messages/tests/cookie.py

@@ -123,7 +123,7 @@ class CookieTest(BaseTest):
             {
                 'message': Message(constants.INFO, 'Test message'),
                 'message_list': [Message(constants.INFO, 'message %s') \
-                                 for x in xrange(5)] + [{'another-message': \
+                                 for x in range(5)] + [{'another-message': \
                                  Message(constants.ERROR, 'error')}],
             },
             Message(constants.INFO, 'message %s'),

+ 1 - 0
django/contrib/sessions/backends/cache.py

@@ -1,5 +1,6 @@
 from django.contrib.sessions.backends.base import SessionBase, CreateError
 from django.core.cache import cache
+from django.utils.six.moves import xrange
 
 KEY_PREFIX = "django.contrib.sessions.cache"
 

+ 1 - 0
django/db/models/sql/where.py

@@ -12,6 +12,7 @@ from django.utils import tree
 from django.db.models.fields import Field
 from django.db.models.sql.datastructures import EmptyResultSet
 from django.db.models.sql.aggregates import Aggregate
+from django.utils.six.moves import xrange
 
 # Connection types
 AND = 'AND'

+ 20 - 19
django/dispatch/dispatcher.py

@@ -2,6 +2,7 @@ import weakref
 import threading
 
 from django.dispatch import saferef
+from django.utils.six.moves import xrange
 
 WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref)
 
@@ -13,17 +14,17 @@ def _make_id(target):
 class Signal(object):
     """
     Base class for all signals
-    
+
     Internal attributes:
-    
+
         receivers
             { receriverkey (id) : weakref(receiver) }
     """
-    
+
     def __init__(self, providing_args=None):
         """
         Create a new signal.
-        
+
         providing_args
             A list of the arguments this signal can pass along in a send() call.
         """
@@ -36,9 +37,9 @@ class Signal(object):
     def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
         """
         Connect receiver to sender for signal.
-    
+
         Arguments:
-        
+
             receiver
                 A function or an instance method which is to receive signals.
                 Receivers must be hashable objects.
@@ -46,7 +47,7 @@ class Signal(object):
                 If weak is True, then receiver must be weak-referencable (more
                 precisely saferef.safeRef() must be able to create a reference
                 to the receiver).
-        
+
                 Receivers must be able to accept keyword arguments.
 
                 If receivers have a dispatch_uid attribute, the receiver will
@@ -62,19 +63,19 @@ class Signal(object):
                 module will attempt to use weak references to the receiver
                 objects. If this parameter is false, then strong references will
                 be used.
-        
+
             dispatch_uid
                 An identifier used to uniquely identify a particular instance of
                 a receiver. This will usually be a string, though it may be
                 anything hashable.
         """
         from django.conf import settings
-        
+
         # If DEBUG is on, check that we got a good receiver
         if settings.DEBUG:
             import inspect
             assert callable(receiver), "Signal receivers must be callable."
-            
+
             # Check for **kwargs
             # Not all callables are inspectable with getargspec, so we'll
             # try a couple different ways but in the end fall back on assuming
@@ -90,7 +91,7 @@ class Signal(object):
             if argspec:
                 assert argspec[2] is not None, \
                     "Signal receivers must accept keyword arguments (**kwargs)."
-        
+
         if dispatch_uid:
             lookup_key = (dispatch_uid, _make_id(sender))
         else:
@@ -112,19 +113,19 @@ class Signal(object):
 
         If weak references are used, disconnect need not be called. The receiver
         will be remove from dispatch automatically.
-    
+
         Arguments:
-        
+
             receiver
                 The registered receiver to disconnect. May be none if
                 dispatch_uid is specified.
-            
+
             sender
                 The registered sender to disconnect
-            
+
             weak
                 The weakref state to disconnect
-            
+
             dispatch_uid
                 the unique identifier of the receiver to disconnect
         """
@@ -149,10 +150,10 @@ class Signal(object):
         receivers called if a raises an error.
 
         Arguments:
-        
+
             sender
                 The sender of the signal Either a specific object or None.
-    
+
             named
                 Named arguments which will be passed to receivers.
 
@@ -172,7 +173,7 @@ class Signal(object):
         Send signal from sender to all connected receivers catching errors.
 
         Arguments:
-        
+
             sender
                 The sender of the signal. Can be any python object (normally one
                 registered with a connect if you actually want something to

+ 1 - 0
django/forms/formsets.py

@@ -8,6 +8,7 @@ from django.forms.widgets import Media, HiddenInput
 from django.utils.encoding import StrAndUnicode
 from django.utils.safestring import mark_safe
 from django.utils import six
+from django.utils.six.moves import xrange
 from django.utils.translation import ugettext as _
 
 

+ 1 - 0
django/utils/crypto.py

@@ -24,6 +24,7 @@ except NotImplementedError:
 
 from django.conf import settings
 from django.utils.encoding import smart_str
+from django.utils.six.moves import xrange
 
 
 _trans_5c = b"".join([chr(x ^ 0x5C) for x in xrange(256)])

+ 1 - 1
django/utils/importlib.py

@@ -6,7 +6,7 @@ def _resolve_name(name, package, level):
     if not hasattr(package, 'rindex'):
         raise ValueError("'package' not set to a string")
     dot = len(package)
-    for x in xrange(level, 1, -1):
+    for x in range(level, 1, -1):
         try:
             dot = package.rindex('.', 0, dot)
         except ValueError:

+ 1 - 0
django/utils/ipv6.py

@@ -2,6 +2,7 @@
 # Copyright 2007 Google Inc. http://code.google.com/p/ipaddr-py/
 # Licensed under the Apache License, Version 2.0 (the "License").
 from django.core.exceptions import ValidationError
+from django.utils.six.moves import xrange
 
 def clean_ipv6_address(ip_str, unpack_ipv4=False,
         error_message="This is not a valid IPv6 address"):

+ 1 - 0
tests/modeltests/delete/tests.py

@@ -2,6 +2,7 @@ from __future__ import absolute_import
 
 from django.db import models, IntegrityError
 from django.test import TestCase, skipUnlessDBFeature, skipIfDBFeature
+from django.utils.six.moves import xrange
 
 from .models import (R, RChild, S, T, U, A, M, MR, MRNull,
     create_a, get_default_r, User, Avatar, HiddenUser, HiddenUserProfile)

+ 2 - 2
tests/modeltests/many_to_one_null/tests.py

@@ -88,8 +88,8 @@ class ManyToOneNullTests(TestCase):
 
     def test_clear_efficiency(self):
         r = Reporter.objects.create()
-        for _ in xrange(3):
+        for _ in range(3):
             r.article_set.create()
         with self.assertNumQueries(1):
             r.article_set.clear()
-        self.assertEqual(r.article_set.count(), 0)
+        self.assertEqual(r.article_set.count(), 0)

+ 3 - 2
tests/regressiontests/backends/tests.py

@@ -17,6 +17,7 @@ from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature,
     TransactionTestCase)
 from django.test.utils import override_settings
 from django.utils import six
+from django.utils.six.moves import xrange
 from django.utils import unittest
 
 from . import models
@@ -531,7 +532,7 @@ class ThreadTests(TestCase):
             from django.db import connection
             connection.cursor()
             connections_set.add(connection.connection)
-        for x in xrange(2):
+        for x in range(2):
             t = threading.Thread(target=runner)
             t.start()
             t.join()
@@ -558,7 +559,7 @@ class ThreadTests(TestCase):
                 # main thread.
                 conn.allow_thread_sharing = True
                 connections_set.add(conn)
-        for x in xrange(2):
+        for x in range(2):
             t = threading.Thread(target=runner)
             t.start()
             t.join()

+ 2 - 2
tests/regressiontests/dispatch/tests/test_saferef.py

@@ -1,7 +1,7 @@
 from django.dispatch.saferef import safeRef
+from django.utils.six.moves import xrange
 from django.utils import unittest
 
-
 class Test1(object):
     def x(self):
         pass
@@ -70,4 +70,4 @@ class SaferefTests(unittest.TestCase):
 
     def _closure(self, ref):
         """Dumb utility mechanism to increment deletion counter"""
-        self.closureCount +=1
+        self.closureCount +=1

+ 1 - 0
tests/regressiontests/middleware/tests.py

@@ -15,6 +15,7 @@ from django.middleware.http import ConditionalGetMiddleware
 from django.middleware.gzip import GZipMiddleware
 from django.test import TestCase, RequestFactory
 from django.test.utils import override_settings
+from django.utils.six.moves import xrange
 
 class CommonMiddlewareTest(TestCase):
     def setUp(self):

+ 1 - 1
tests/regressiontests/utils/datastructures.py

@@ -98,7 +98,7 @@ class SortedDictTests(SimpleTestCase):
         self.assertEqual(l - len(self.d1), 1)
 
     def test_dict_equality(self):
-        d = SortedDict((i, i) for i in xrange(3))
+        d = SortedDict((i, i) for i in range(3))
         self.assertEqual(d, {0: 0, 1: 1, 2: 2})
 
     def test_tuple_init(self):