1. kartic
  2. WebHelpers


slug...@gmail.com  committed f6adc7a

Refine Sprox workaround to check for exact exception reported.

  • Participants
  • Parent commits 4706b6c
  • Branches trunk

Comments (0)

Files changed (3)


View file
  • Ignore whitespace
   - Revert Sprox patch (#59) from 1.3b1; it makes SQLAlchemy inefficient (#63).
     The Sprox object is apparently incompatible because it's not sliceable.
-    Changed get_wrapper() test to require .__getslice__, and moved its stanza
-    below SQLAlchemy tests because SQLAlchemy queries and selects don't have
-    .__getslice__ either; but that's OK because their paginate wrappers
-    emulate it. 
+    (We can't fully check whether it's sliceable. We'd have to call .__getitem__
+    with a slice and and guess what its exception means, and calling it may
+    cause side effects. But the Sprox error, a dict, and my test classes all
+    raise "TypeError: unhashable type", so I check for that.)
 1.3b1 (2011-03-17)

File tests/test_paginate.py

View file
  • Ignore whitespace
     purl = paginate.PageURL_WebOb(request, qualified=True)
     eq_(purl(2), "http://localhost:5000/articles?blah=boo&page=2")
 class UnsliceableSequence(object):
    def __init__(self, seq):
       self.l = seq
    def __len__(self):
        return len(self.l)
+class UnsliceableSequence2(UnsliceableSequence):
+   def __getitem__(self, key):
+        raise TypeError("unhashable type")
 class TestCollectionTypes(unittest.TestCase):
     rng = list(range(10))   # A list in both Python 2 and 3.
     def test_unsliceable_sequence(self):
+    @raises(TypeError)
+    def test_unsliceable_sequence2(self):
+        paginate.Page(UnsliceableSequence2(self.rng))
 class TestSQLAlchemyCollectionTypes(unittest.TestCase):
     def setUp(self):

File webhelpers/paginate.py

View file
  • Ignore whitespace
 from webhelpers.html import literal, HTML
+Sorry, your collection type is not supported by the paginate module. You can
+provide a list, a tuple, a SQLAlchemy " "select object or a SQLAlchemy
+ORM-query object."""
 # import SQLAlchemy if available
     import sqlalchemy
             or isinstance(obj, sqlalchemy.sql.expression.Select):
                 return _SQLAlchemySelect(obj, sqlalchemy_session)
-    # If object is iterable and sliceable we can use it directly
-    required_methods = ["__iter__", "__len__", "__slice__"]
+    # If object is iterable we can use it.  (This is not true if it's
+    # non-sliceable but there doesn't appear to be a way to test for that. We'd
+    # have to call .__getitem__ with a slice and guess what the exception
+    # means, and calling it may cause side effects.)
+    required_methods = ["__iter__", "__len__", "__getitem__"]
     for meth in required_methods:
         if not hasattr(obj, meth):
         return obj
-    raise TypeError("Sorry, your collection type is not supported by the "
-        "paginate module. You can provide a list, a tuple, a SQLAlchemy "
-        "select object or a SQLAlchemy ORM-query object.")
 class _SQLAlchemySelect(object):
             if presliced_list:
                 self.items = self.collection
-                self.items = list(self.collection[self.first_item-1:self.last_item])
+                try:
+                    first = self.first_item - 1
+                    last = self.last_item
+                    self.items = list(self.collection[first:last])
+                except TypeError, e:
+                    if str(e) == "unhashable type":
+                        # Assume this means collection is unsliceable.
+                        raise TypeError(INCOMPATIBLE_COLLECTION_TYPE)
+                    raise
             # Links to previous and next page
             if self.page > self.first_page: