[py3k] import range using six.moves
authorRémi Cardona <remi.cardona@logilab.fr>
Tue, 15 Sep 2015 16:56:57 +0200
changeset 10609 e2d8e81bfe68
parent 10608 7fc548d9dd8e
child 10610 d53b9c157f99
[py3k] import range using six.moves
dataimport/pgstore.py
devtools/fill.py
devtools/httptest.py
devtools/test/unittest_dbfill.py
devtools/testlib.py
entities/lib.py
entity.py
md5crypt.py
predicates.py
rset.py
schema.py
server/querier.py
server/repository.py
server/sources/native.py
server/sources/rql2sql.py
server/test/unittest_ldapsource.py
server/test/unittest_postgres.py
server/test/unittest_repository.py
server/test/unittest_security.py
test/unittest_utils.py
view.py
web/captcha.py
web/htmlwidgets.py
web/test/unittest_magicsearch.py
web/views/autoform.py
web/views/baseviews.py
web/views/csvexport.py
web/views/cwsources.py
web/views/cwuser.py
web/views/editforms.py
web/views/idownloadable.py
web/views/owl.py
web/views/plots.py
web/views/pyviews.py
web/views/rdf.py
web/views/sparql.py
web/views/tableview.py
web/views/timetable.py
web/views/xbel.py
web/views/xmlrss.py
--- a/dataimport/pgstore.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/dataimport/pgstore.py	Tue Sep 15 16:56:57 2015 +0200
@@ -27,7 +27,7 @@
 from collections import defaultdict
 from base64 import b64encode
 
-from six.moves import cPickle as pickle
+from six.moves import cPickle as pickle, range
 
 from cubicweb.utils import make_uid
 from cubicweb.server.sqlutils import SQL_PREFIX
@@ -42,7 +42,7 @@
     try:
         chunksize = (len(statements) / nb_threads) + 1
         threads = []
-        for i in xrange(nb_threads):
+        for i in range(nb_threads):
             chunks = statements[i*chunksize:(i+1)*chunksize]
             thread = threading.Thread(target=_execmany_thread,
                                       args=(sql_connect, chunks,
@@ -186,7 +186,7 @@
     rows = []
     if columns is None:
         if isinstance(data[0], (tuple, list)):
-            columns = range(len(data[0]))
+            columns = list(range(len(data[0])))
         elif isinstance(data[0], dict):
             columns = data[0].keys()
         else:
--- a/devtools/fill.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/devtools/fill.py	Tue Sep 15 16:56:57 2015 +0200
@@ -27,6 +27,8 @@
 from datetime import datetime, date, time, timedelta
 from decimal import Decimal
 
+from six.moves import range
+
 from logilab.common import attrdict
 from logilab.mtconverter import xml_escape
 from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
@@ -287,7 +289,7 @@
                         returns acceptable values for this attribute
     """
     queries = []
-    for index in xrange(entity_num):
+    for index in range(entity_num):
         restrictions = []
         args = {}
         for attrname, value in make_entity(etype, schema, vreg, index, choice_func).items():
@@ -509,8 +511,8 @@
                     break
         else:
             # FIXME: 20 should be read from config
-            subjeidsiter = [choice(tuple(subjeids)) for i in xrange(min(len(subjeids), 20))]
-            objeidsiter = [choice(tuple(objeids)) for i in xrange(min(len(objeids), 20))]
+            subjeidsiter = [choice(tuple(subjeids)) for i in range(min(len(subjeids), 20))]
+            objeidsiter = [choice(tuple(objeids)) for i in range(min(len(objeids), 20))]
             for subjeid, objeid in zip(subjeidsiter, objeidsiter):
                 if subjeid != objeid and not (subjeid, objeid) in used:
                     used.add( (subjeid, objeid) )
--- a/devtools/httptest.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/devtools/httptest.py	Tue Sep 15 16:56:57 2015 +0200
@@ -26,7 +26,7 @@
 import threading
 import socket
 
-from six.moves import http_client
+from six.moves import range, http_client
 from six.moves.urllib.parse import urlparse
 
 from twisted.internet import reactor, error
--- a/devtools/test/unittest_dbfill.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/devtools/test/unittest_dbfill.py	Tue Sep 15 16:56:57 2015 +0200
@@ -22,6 +22,8 @@
 import re
 import datetime
 
+from six.moves import range
+
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb.devtools.fill import ValueGenerator, make_tel
@@ -86,7 +88,7 @@
         # Test for random index
         for index in range(5):
             cost_value = self.bug_valgen.generate_attribute_value({}, 'cost', index)
-            self.assertIn(cost_value, range(index+1))
+            self.assertIn(cost_value, list(range(index+1)))
 
     def test_date(self):
         """test date generation"""
--- a/devtools/testlib.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/devtools/testlib.py	Tue Sep 15 16:56:57 2015 +0200
@@ -28,6 +28,7 @@
 from warnings import warn
 from itertools import chain
 
+from six.moves import range
 from six.moves.urllib.parse import urlparse, parse_qs, unquote as urlunquote
 
 import yams.schema
@@ -1182,7 +1183,7 @@
                 else:
                     rql = 'Any X WHERE X is %s' % etype
                 rset = req.execute(rql)
-                for row in xrange(len(rset)):
+                for row in range(len(rset)):
                     if limit and row > limit:
                         break
                     # XXX iirk
--- a/entities/lib.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/entities/lib.py	Tue Sep 15 16:56:57 2015 +0200
@@ -21,6 +21,7 @@
 from warnings import warn
 from datetime import datetime
 
+from six.moves import range
 from six.moves.urllib.parse import urlsplit, urlunsplit
 
 from logilab.mtconverter import xml_escape
@@ -67,7 +68,7 @@
                                 {'y': self.eid})
         if skipeids is None:
             skipeids = set()
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             eid = rset[i][0]
             if eid in skipeids:
                 continue
--- a/entity.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/entity.py	Tue Sep 15 16:56:57 2015 +0200
@@ -22,6 +22,8 @@
 from warnings import warn
 from functools import partial
 
+from six.moves import range
+
 from logilab.common.decorators import cached
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import yes
@@ -892,10 +894,10 @@
                 raise Exception('unable to fetch attributes for entity with eid %s'
                                 % self.eid)
             # handle attributes
-            for i in xrange(1, lastattr):
+            for i in range(1, lastattr):
                 self.cw_attr_cache[str(selected[i-1][0])] = rset[i]
             # handle relations
-            for i in xrange(lastattr, len(rset)):
+            for i in range(lastattr, len(rset)):
                 rtype, role = selected[i-1][0]
                 value = rset[i]
                 if value is None:
--- a/md5crypt.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/md5crypt.py	Tue Sep 15 16:56:57 2015 +0200
@@ -43,6 +43,9 @@
 
 from hashlib import md5 # pylint: disable=E0611
 
+from six.moves import range
+
+
 def to64 (v, n):
     ret = ''
     while (n - 1 >= 0):
@@ -62,7 +65,7 @@
     salt = salt[:8]
     ctx = pw + MAGIC + salt
     final = md5(pw + salt + pw).digest()
-    for pl in xrange(len(pw), 0, -16):
+    for pl in range(len(pw), 0, -16):
         if pl > 16:
             ctx = ctx + final[:16]
         else:
@@ -79,7 +82,7 @@
     # The following is supposed to make
     # things run slower.
     # my question: WTF???
-    for i in xrange(1000):
+    for i in range(1000):
         ctx1 = ''
         if i & 1:
             ctx1 = ctx1 + pw
--- a/predicates.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/predicates.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 from warnings import warn
 from operator import eq
 
+from six.moves import range
+
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import Predicate, objectify_predicate, yes
 
@@ -332,7 +334,7 @@
             # on rset containing several entity types, each row may be
             # individually adaptable, while the whole rset won't be if the
             # same adapter can't be used for each type
-            for row in xrange(len(kwargs['rset'])):
+            for row in range(len(kwargs['rset'])):
                 kwargs.setdefault('col', 0)
                 _score = super(adaptable, self).__call__(cls, req, row=row, **kwargs)
                 if not _score:
--- a/rset.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/rset.py	Tue Sep 15 16:56:57 2015 +0200
@@ -21,6 +21,8 @@
 
 from warnings import warn
 
+from six.moves import range
+
 from logilab.common import nullobject
 from logilab.common.decorators import cached, clear_cache, copy_cache
 from rql import nodes, stmts
@@ -186,7 +188,7 @@
         """
         rows, descr = [], []
         rset = self.copy(rows, descr)
-        for i in xrange(len(self)):
+        for i in range(len(self)):
             if not filtercb(self.get_entity(i, col)):
                 continue
             rows.append(self.rows[i])
@@ -311,7 +313,7 @@
             newselect.limit = limit
             newselect.offset = offset
             aliases = [nodes.VariableRef(newselect.get_variable(chr(65+i), i))
-                       for i in xrange(len(rqlst.children[0].selection))]
+                       for i in range(len(rqlst.children[0].selection))]
             for vref in aliases:
                 newselect.append_selected(nodes.VariableRef(vref.variable))
             newselect.set_with([nodes.SubQuery(aliases, rqlst)], check=False)
@@ -387,7 +389,7 @@
 
     def entities(self, col=0):
         """iter on entities with eid in the `col` column of the result set"""
-        for i in xrange(len(self)):
+        for i in range(len(self)):
             # may have None values in case of outer join (or aggregat on eid
             # hacks)
             if self.rows[i][col] is not None:
@@ -606,7 +608,7 @@
                 except AttributeError:
                     # not a variable
                     continue
-                for i in xrange(len(select.selection)):
+                for i in range(len(select.selection)):
                     if i == col:
                         continue
                     coletype = self.description[row][i]
--- a/schema.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/schema.py	Tue Sep 15 16:56:57 2015 +0200
@@ -26,6 +26,8 @@
 from logging import getLogger
 from warnings import warn
 
+from six.moves import range
+
 from logilab.common import tempattr
 from logilab.common.decorators import cached, clear_cache, monkeypatch, cachedproperty
 from logilab.common.logging_ext import set_log_methods
@@ -364,7 +366,7 @@
             get_eschema = _cw.vreg.schema.eschema
             try:
                 for eaction, col in has_perm_defs:
-                    for i in xrange(len(rset)):
+                    for i in range(len(rset)):
                         eschema = get_eschema(rset.description[i][col])
                         eschema.check_perm(_cw, eaction, eid=rset[i][col])
                 if self.eid is not None:
--- a/server/querier.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/querier.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 
 from itertools import repeat
 
+from six.moves import range
+
 from rql import RQLSyntaxError, CoercionError
 from rql.stmts import Union
 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
@@ -643,7 +645,7 @@
                 # so compute description manually even if there is only
                 # one solution
                 basedescr = [None] * len(plan.selected)
-                todetermine = zip(xrange(len(plan.selected)), repeat(False))
+                todetermine = zip(range(len(plan.selected)), repeat(False))
                 descr = _build_descr(cnx, results, basedescr, todetermine)
             # FIXME: get number of affected entities / relations on non
             # selection queries ?
@@ -670,7 +672,7 @@
     unstables = rqlst.get_variable_indices()
     basedescr = []
     todetermine = []
-    for i in xrange(len(rqlst.children[0].selection)):
+    for i in range(len(rqlst.children[0].selection)):
         ttype = _selection_idx_type(i, rqlst, args)
         if ttype is None or ttype == 'Any':
             ttype = None
--- a/server/repository.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/repository.py	Tue Sep 15 16:56:57 2015 +0200
@@ -35,7 +35,7 @@
 from time import time, localtime, strftime
 from contextlib import contextmanager
 
-from six.moves import queue
+from six.moves import range, queue
 
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.deprecation import deprecated
@@ -243,7 +243,7 @@
         #    proper initialization
         self._get_cnxset().close(True)
         self.cnxsets = [] # list of available cnxsets (can't iterate on a Queue)
-        for i in xrange(config['connections-pool-size']):
+        for i in range(config['connections-pool-size']):
             self.cnxsets.append(self.system_source.wrapped_connection())
             self._cnxsets_pool.put_nowait(self.cnxsets[-1])
 
--- a/server/sources/native.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/sources/native.py	Tue Sep 15 16:56:57 2015 +0200
@@ -38,7 +38,7 @@
 import logging
 import sys
 
-from six.moves import cPickle as pickle
+from six.moves import range, cPickle as pickle
 
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.configuration import Method
@@ -1687,7 +1687,7 @@
         self.logger.info('number of rows: %d', rowcount)
         blocksize = self.blocksize
         if rowcount > 0:
-            for i, start in enumerate(xrange(0, rowcount, blocksize)):
+            for i, start in enumerate(range(0, rowcount, blocksize)):
                 rows = list(itertools.islice(rows_iterator, blocksize))
                 serialized = self._serialize(table, columns, rows)
                 archive.writestr('tables/%s.%04d' % (table, i), serialized)
--- a/server/sources/rql2sql.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/sources/rql2sql.py	Tue Sep 15 16:56:57 2015 +0200
@@ -52,6 +52,8 @@
 import threading
 from datetime import datetime, time
 
+from six.moves import range
+
 from logilab.common.date import utcdatetime, utctime
 from logilab.database import FunctionDescr, SQL_FUNCTIONS_REGISTRY
 
@@ -189,13 +191,13 @@
                 thisexistssols = [newsols[0]]
                 thisexistsvars = set()
                 existssols[var.scope] = thisexistssols, thisexistsvars
-            for i in xrange(len(newsols)-1, 0, -1):
+            for i in range(len(newsols)-1, 0, -1):
                 if vtype != newsols[i][vname]:
                     thisexistssols.append(newsols.pop(i))
                     thisexistsvars.add(vname)
         else:
             # remember unstable variables
-            for i in xrange(1, len(newsols)):
+            for i in range(1, len(newsols)):
                 if vtype != newsols[i][vname]:
                     unstable.add(vname)
     if invariants:
--- a/server/test/unittest_ldapsource.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/test/unittest_ldapsource.py	Tue Sep 15 16:56:57 2015 +0200
@@ -26,6 +26,8 @@
 import subprocess
 import tempfile
 
+from six.moves import range
+
 from logilab.common.testlib import TestCase, unittest_main, mock_object, Tags
 
 from cubicweb import AuthenticationError
@@ -70,7 +72,7 @@
         sys.stderr.write(stderr)
 
     #ldapuri = 'ldapi://' + join(basedir, "ldapi").replace('/', '%2f')
-    port = get_available_port(xrange(9000, 9100))
+    port = get_available_port(range(9000, 9100))
     host = 'localhost:%s' % port
     ldapuri = 'ldap://%s' % host
     cmdline = ["/usr/sbin/slapd", "-f",  slapdconf,  "-h",  ldapuri, "-d", "0"]
--- a/server/test/unittest_postgres.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/test/unittest_postgres.py	Tue Sep 15 16:56:57 2015 +0200
@@ -19,6 +19,8 @@
 from datetime import datetime
 from threading import Thread
 
+from six.moves import range
+
 from logilab.common.testlib import SkipTest
 
 from cubicweb import ValidationError
@@ -55,7 +57,7 @@
         range1 = []
         range2 = []
         def allocate_eid_ranges(session, target):
-            for x in xrange(1, 10):
+            for x in range(1, 10):
                 eid = source.create_eid(session, count=x)
                 target.extend(range(eid-x, eid))
 
--- a/server/test/unittest_repository.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/test/unittest_repository.py	Tue Sep 15 16:56:57 2015 +0200
@@ -22,6 +22,8 @@
 import time
 import logging
 
+from six.moves import range
+
 from yams.constraints import UniqueConstraint
 from yams import register_base_type, unregister_base_type
 
@@ -589,11 +591,11 @@
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
             t0 = time.time()
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
-            for j in xrange(0, 2000, 100):
+            for j in range(0, 2000, 100):
                 abraham.cw_set(personne_composite=personnes[j:j+100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
@@ -610,7 +612,7 @@
     def test_add_relation_non_inlined(self):
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             cnx.commit()
@@ -619,7 +621,7 @@
                                         personne_composite=personnes[:100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
-            for j in xrange(100, 2000, 100):
+            for j in range(100, 2000, 100):
                 abraham.cw_set(personne_composite=personnes[j:j+100])
             t2 = time.time()
             self.info('more relations: %.2gs', (t2-t1))
@@ -630,7 +632,7 @@
     def test_add_relation_inlined(self):
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             cnx.commit()
@@ -639,7 +641,7 @@
                                         personne_inlined=personnes[:100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
-            for j in xrange(100, 2000, 100):
+            for j in range(100, 2000, 100):
                 abraham.cw_set(personne_inlined=personnes[j:j+100])
             t2 = time.time()
             self.info('more relations: %.2gs', (t2-t1))
@@ -652,7 +654,7 @@
         """ to be compared with test_session_add_relations"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -669,7 +671,7 @@
         """ to be compared with test_session_add_relation"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -686,7 +688,7 @@
         """ to be compared with test_session_add_relations"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -703,7 +705,7 @@
         """ to be compared with test_session_add_relation"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
--- a/server/test/unittest_security.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/server/test/unittest_security.py	Tue Sep 15 16:56:57 2015 +0200
@@ -17,6 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """functional tests for server'security"""
 
+from six.moves import range
+
 from logilab.common.testlib import unittest_main
 
 from cubicweb.devtools.testlib import CubicWebTC
@@ -666,7 +668,7 @@
                 rset = cnx.execute('Any X, U WHERE X is EmailAddress, U use_email X')
                 msg = ['Preexisting email readable by anon found!']
                 tmpl = '  - "%s" used by user "%s"'
-                for i in xrange(len(rset)):
+                for i in range(len(rset)):
                     email, user = rset.get_entity(i, 0), rset.get_entity(i, 1)
                     msg.append(tmpl % (email.dc_title(), user.dc_title()))
                 raise RuntimeError('\n'.join(msg))
--- a/test/unittest_utils.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/test/unittest_utils.py	Tue Sep 15 16:56:57 2015 +0200
@@ -21,6 +21,7 @@
 import decimal
 import datetime
 
+from six.moves import range
 
 from logilab.common.testlib import TestCase, DocTest, unittest_main
 
@@ -67,7 +68,7 @@
     def test_querycache(self):
         c = QueryCache(ceiling=20)
         # write only
-        for x in xrange(10):
+        for x in range(10):
             c[x] = x
         self.assertEqual(c._usage_report(),
                          {'transientcount': 0,
@@ -75,7 +76,7 @@
                           'permanentcount': 0})
         c = QueryCache(ceiling=10)
         # we should also get a warning
-        for x in xrange(20):
+        for x in range(20):
             c[x] = x
         self.assertEqual(c._usage_report(),
                          {'transientcount': 0,
@@ -83,8 +84,8 @@
                           'permanentcount': 0})
         # write + reads
         c = QueryCache(ceiling=20)
-        for n in xrange(4):
-            for x in xrange(10):
+        for n in range(4):
+            for x in range(10):
                 c[x] = x
                 c[x]
         self.assertEqual(c._usage_report(),
@@ -92,8 +93,8 @@
                           'itemcount': 10,
                           'permanentcount': 0})
         c = QueryCache(ceiling=20)
-        for n in xrange(17):
-            for x in xrange(10):
+        for n in range(17):
+            for x in range(10):
                 c[x] = x
                 c[x]
         self.assertEqual(c._usage_report(),
@@ -101,8 +102,8 @@
                           'itemcount': 10,
                           'permanentcount': 10})
         c = QueryCache(ceiling=20)
-        for n in xrange(17):
-            for x in xrange(10):
+        for n in range(17):
+            for x in range(10):
                 c[x] = x
                 if n % 2:
                     c[x]
@@ -169,14 +170,14 @@
 
     def test_append(self):
         l = SizeConstrainedList(10)
-        for i in xrange(12):
+        for i in range(12):
             l.append(i)
-        self.assertEqual(l, range(2, 12))
+        self.assertEqual(l, list(range(2, 12)))
 
     def test_extend(self):
-        testdata = [(range(5), range(5)),
-                    (range(10), range(10)),
-                    (range(12), range(2, 12)),
+        testdata = [(list(range(5)), list(range(5))),
+                    (list(range(10)), list(range(10))),
+                    (list(range(12)), list(range(2, 12))),
                     ]
         for extension, expected in testdata:
             l = SizeConstrainedList(10)
--- a/view.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/view.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 from warnings import warn
 from functools import partial
 
+from six.moves import range
+
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import yes
 from logilab.mtconverter import xml_escape
@@ -173,7 +175,7 @@
         # specific view
         if rset.rowcount != 1:
             kwargs.setdefault('initargs', self.cw_extra_kwargs)
-            for i in xrange(len(rset)):
+            for i in range(len(rset)):
                 if wrap:
                     self.w(u'<div class="section">')
                 self.wview(self.__regid__, rset, row=i, **kwargs)
@@ -394,7 +396,7 @@
         if rset is None:
             rset = self.cw_rset = self._cw.execute(self.startup_rql())
         if rset:
-            for i in xrange(len(rset)):
+            for i in range(len(rset)):
                 self.wview(self.__regid__, rset, row=i, **kwargs)
         else:
             self.no_entities(**kwargs)
--- a/web/captcha.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/captcha.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 from random import randint, choice
 from io import BytesIO
 
+from six.moves import range
+
 from PIL import Image, ImageFont, ImageDraw, ImageFilter
 
 
@@ -51,7 +53,7 @@
     draw = ImageDraw.Draw(img)
     # draw 100 random colored boxes on the background
     x, y = img.size
-    for num in xrange(100):
+    for num in range(100):
         draw.rectangle((randint(0, x), randint(0, y),
                         randint(0, x), randint(0, y)),
                        fill=randint(0, 0xffffff))
--- a/web/htmlwidgets.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/htmlwidgets.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 import random
 from math import floor
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_deprecated
 
@@ -343,7 +345,7 @@
             self.w(u'<th %s>%s</th>' % (' '.join(attrs), column.name or u''))
         self.w(u'</tr>')
         self.w(u'</thead><tbody>')
-        for rowindex in xrange(len(self.model.get_rows())):
+        for rowindex in range(len(self.model.get_rows())):
             klass = (rowindex%2==1) and 'odd' or 'even'
             self.w(u'<tr class="%s" %s>' % (klass, self.highlight))
             for column, sortvalue in self.itercols(rowindex):
--- a/web/test/unittest_magicsearch.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/test/unittest_magicsearch.py	Tue Sep 15 16:56:57 2015 +0200
@@ -21,6 +21,8 @@
 import sys
 from contextlib import contextmanager
 
+from six.moves import range
+
 from logilab.common.testlib import TestCase, unittest_main
 
 from rql import BadRQLQuery, RQLSyntaxError
@@ -330,7 +332,7 @@
         # suggestions should contain any possible value for
         # a given attribute (limited to 10)
         with self.admin_access.web_request() as req:
-            for i in xrange(15):
+            for i in range(15):
                 req.create_entity('Personne', nom=u'n%s' % i, prenom=u'p%s' % i)
             req.cnx.commit()
         self.assertListEqual(['Any X WHERE X is Personne, X nom "n0"',
--- a/web/views/autoform.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/autoform.py	Tue Sep 15 16:56:57 2015 +0200
@@ -123,6 +123,8 @@
 
 from warnings import warn
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import iclassmethod, cached
 from logilab.common.deprecation import deprecated
@@ -610,7 +612,7 @@
                     toggleable_rel_link_func = toggleable_relation_link
                 else:
                     toggleable_rel_link_func = lambda x, y, z: u''
-                for row in xrange(rset.rowcount):
+                for row in range(rset.rowcount):
                     nodeid = relation_id(entity.eid, rschema, role,
                                          rset[row][0])
                     if nodeid in pending_deletes:
--- a/web/views/baseviews.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/baseviews.py	Tue Sep 15 16:56:57 2015 +0200
@@ -81,6 +81,8 @@
 from datetime import timedelta
 from warnings import warn
 
+from six.moves import range
+
 from rql import nodes
 
 from logilab.mtconverter import TransformError, xml_escape
@@ -232,7 +234,7 @@
         rset = self.cw_rset
         if rset is None:
             raise NotImplementedError(self)
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             self.wview(self.__regid__, rset, row=i, **kwargs)
             if len(rset) > 1:
                 self.w(u"\n")
@@ -314,7 +316,7 @@
             self.w(u'<ul>\n')
         else:
             self.w(u'<ul%s class="%s">\n' % (listid, klass or 'section'))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(row=i, col=0, vid=subvid, klass=klass, **kwargs)
         self.w(u'</ul>\n')
         if title:
@@ -427,7 +429,7 @@
     def call(self, subvid=None, **kwargs):
         kwargs['vid'] = subvid
         rset = self.cw_rset
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             self.cell_call(i, 0, **kwargs)
             if i < rset.rowcount-1:
                 self.w(self.separator)
--- a/web/views/csvexport.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/csvexport.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from cubicweb.schema import display_name
 from cubicweb.predicates import any_rset, empty_rset
 from cubicweb.uilib import UnicodeCSVWriter
@@ -88,7 +90,7 @@
         rows_by_type = {}
         writer = self.csvwriter()
         rowdef_by_type = {}
-        for index in xrange(len(self.cw_rset)):
+        for index in range(len(self.cw_rset)):
             entity = self.cw_rset.complete_entity(index)
             if entity.e_schema not in rows_by_type:
                 rowdef_by_type[entity.e_schema] = [rs for rs, at in entity.e_schema.attribute_definitions()
--- a/web/views/cwsources.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/cwsources.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,9 @@
 
 import logging
 from itertools import repeat
+
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cachedproperty
 
@@ -95,7 +98,7 @@
             if hostconfig:
                 self.w(u'<h3>%s</h3>' % self._cw._('CWSourceHostConfig_plural'))
                 self._cw.view('table', hostconfig, w=self.w,
-                              displaycols=range(2),
+                              displaycols=list(range(2)),
                               cellvids={1: 'editable-final'})
 
 
--- a/web/views/cwuser.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/cwuser.py	Tue Sep 15 16:56:57 2015 +0200
@@ -22,6 +22,8 @@
 
 from hashlib import sha1 # pylint: disable=E0611
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb import tags
@@ -64,7 +66,7 @@
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
          xmlns:rdfs="http://www.w3org/2000/01/rdf-schema#"
          xmlns:foaf="http://xmlns.com/foaf/0.1/"> '''% self._cw.encoding)
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u'</rdf:RDF>\n')
 
--- a/web/views/editforms.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/editforms.py	Tue Sep 15 16:56:57 2015 +0200
@@ -24,6 +24,8 @@
 
 from copy import copy
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cached
 from logilab.common.registry import yes
@@ -230,7 +232,7 @@
     def __init__(self, req, rset, **kwargs):
         kwargs.setdefault('__redirectrql', rset.printable_rql())
         super(TableEditForm, self).__init__(req, rset=rset, **kwargs)
-        for row in xrange(len(self.cw_rset)):
+        for row in range(len(self.cw_rset)):
             form = self._cw.vreg['forms'].select('edition', self._cw,
                                                  rset=self.cw_rset, row=row,
                                                  formtype='muledit',
--- a/web/views/idownloadable.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/idownloadable.py	Tue Sep 15 16:56:57 2015 +0200
@@ -22,6 +22,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from logilab.mtconverter import BINARY_ENCODINGS, TransformError, xml_escape
 from logilab.common.deprecation import class_renamed, deprecated
 
@@ -166,7 +168,7 @@
 
     def call(self, **kwargs):
         rset = self.cw_rset
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             self.w(u'<div class="efile">')
             self.wview(self.__regid__, rset, row=i, col=0, **kwargs)
             self.w(u'</div>')
--- a/web/views/owl.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/owl.py	Tue Sep 15 16:56:57 2015 +0200
@@ -21,6 +21,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from logilab.mtconverter import TransformError, xml_escape
 
 from cubicweb.view import StartupView, EntityView
@@ -166,7 +168,7 @@
 
     def call(self):
         self.w(OWL_OPENING_ROOT % {'appid': self._cw.vreg.schema.name})
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(OWL_CLOSING_ROOT)
 
--- a/web/views/plots.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/plots.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from logilab.common.date import datetime2ticks
 from logilab.common.deprecation import class_deprecated
 from logilab.common.registry import objectify_predicate
@@ -154,7 +156,7 @@
         abscissa = [row[0] for row in self.cw_rset]
         plots = []
         nbcols = len(self.cw_rset.rows[0])
-        for col in xrange(1, nbcols):
+        for col in range(1, nbcols):
             data = [row[col] for row in self.cw_rset]
             plots.append(filterout_nulls(abscissa, data))
         plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
--- a/web/views/pyviews.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/pyviews.py	Tue Sep 15 16:56:57 2015 +0200
@@ -19,6 +19,8 @@
 """
 __docformat__ = "restructuredtext en"
 
+from six.moves import range
+
 from cubicweb.view import View
 from cubicweb.predicates import match_kwargs
 from cubicweb.web.views import tableview
@@ -100,7 +102,7 @@
 
     def build_column_renderers(self):
         return [self.column_renderer(colid)
-                for colid in xrange(len(self.pyvalue[0]))]
+                for colid in range(len(self.pyvalue[0]))]
 
     def facets_form(self, mainvar=None):
         return None # not supported
--- a/web/views/rdf.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/rdf.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from yams import xy
 
 from cubicweb.schema import VIRTUAL_RTYPES
@@ -56,7 +58,7 @@
             graph.bind('cw', CW)
             for prefix, xmlns in xy.XY.prefixes.items():
                 graph.bind(prefix, rdflib.Namespace(xmlns))
-            for i in xrange(self.cw_rset.rowcount):
+            for i in range(self.cw_rset.rowcount):
                 entity = self.cw_rset.complete_entity(i, 0)
                 self.entity2graph(graph, entity)
             self.w(graph.serialize(format=self.format))
--- a/web/views/sparql.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/sparql.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from yams import xy
 from rql import TypeResolverException
 
@@ -111,7 +113,7 @@
         rqlst = self.cw_rset.syntax_tree().children[0]
         varnames = [var.name for var in rqlst.selection]
         results = E.results()
-        for rowidx in xrange(len(self.cw_rset)):
+        for rowidx in range(len(self.cw_rset)):
             result = E.result()
             for colidx, varname in enumerate(varnames):
                 result.append(self.cell_binding(rowidx, colidx, varname))
--- a/web/views/tableview.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/tableview.py	Tue Sep 15 16:56:57 2015 +0200
@@ -67,6 +67,8 @@
 from copy import copy
 from types import MethodType
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cachedproperty
 from logilab.common.deprecation import class_deprecated
@@ -225,7 +227,7 @@
 
     def render_table_body(self, w, colrenderers):
         w(u'<tbody>')
-        for rownum in xrange(self.view.table_size):
+        for rownum in range(self.view.table_size):
             self.render_row(w, rownum, colrenderers)
         w(u'</tbody>')
 
@@ -646,10 +648,10 @@
         # compute displayed columns
         if self.displaycols is None:
             if headers is not None:
-                displaycols = range(len(headers))
+                displaycols = list(range(len(headers)))
             else:
                 rqlst = self.cw_rset.syntax_tree()
-                displaycols = range(len(rqlst.children[0].selection))
+                displaycols = list(range(len(rqlst.children[0].selection)))
         else:
             displaycols = self.displaycols
         # compute table headers
@@ -977,9 +979,9 @@
             if 'displaycols' in self._cw.form:
                 displaycols = [int(idx) for idx in self._cw.form['displaycols']]
             elif headers is not None:
-                displaycols = range(len(headers))
+                displaycols = list(range(len(headers)))
             else:
-                displaycols = range(len(self.cw_rset.syntax_tree().children[0].selection))
+                displaycols = list(range(len(self.cw_rset.syntax_tree().children[0].selection)))
         return displaycols
 
     def _setup_tablesorter(self, divid):
@@ -1298,7 +1300,7 @@
         self.w(u'<table class="%s">' % self.table_css)
         self.table_header(sample)
         self.w(u'<tbody>')
-        for row in xrange(self.cw_rset.rowcount):
+        for row in range(self.cw_rset.rowcount):
             self.cell_call(row=row, col=0)
         self.w(u'</tbody>')
         self.w(u'</table>')
--- a/web/views/timetable.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/timetable.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.date import ONEDAY, date_range, todatetime
 
@@ -51,7 +53,7 @@
         users = []
         users_max = {}
         # XXX: try refactoring with calendar.py:OneMonthCal
-        for row in xrange(self.cw_rset.rowcount):
+        for row in range(self.cw_rset.rowcount):
             task = self.cw_rset.get_entity(row, 0)
             icalendarable = task.cw_adapt_to('ICalendarable')
             if len(self.cw_rset[row]) > 1 and self.cw_rset.description[row][1] == 'CWUser':
@@ -88,7 +90,7 @@
 
         rows = []
         # colors here are class names defined in cubicweb.css
-        colors = ["col%x" % i for i in xrange(12)]
+        colors = ["col%x" % i for i in range(12)]
         next_color_index = 0
 
         visited_tasks = {} # holds a description of a task for a user
--- a/web/views/xbel.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/xbel.py	Tue Sep 15 16:56:57 2015 +0200
@@ -20,6 +20,8 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb.predicates import is_instance
@@ -42,7 +44,7 @@
         self.w(u'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">')
         self.w(u'<xbel version="1.0">')
         self.w(u'<title>%s</title>' % self._cw._('bookmarks'))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u"</xbel>")
 
--- a/web/views/xmlrss.py	Tue Sep 15 15:07:13 2015 +0200
+++ b/web/views/xmlrss.py	Tue Sep 15 16:56:57 2015 +0200
@@ -23,6 +23,8 @@
 from base64 import b64encode
 from time import timezone
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb.predicates import (is_instance, non_final_entity, one_line_rset,
@@ -64,7 +66,7 @@
         """display a list of entities by calling their <item_vid> view"""
         self.w(u'<?xml version="1.0" encoding="%s"?>\n' % self._cw.encoding)
         self.w(u'<%s size="%s">\n' % (self.xml_root, len(self.cw_rset)))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u'</%s>\n' % self.xml_root)
 
@@ -256,7 +258,7 @@
     def call(self):
         """display a list of entities by calling their <item_vid> view"""
         self._open()
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self._close()