]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fixes to __setitem__ in the list adapter to handle some slices that
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 May 2009 17:13:13 +0000 (17:13 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 May 2009 17:13:13 +0000 (17:13 +0000)
usually go right to __setslice__

lib/sqlalchemy/orm/collections.py
test/orm/collection.py

index 4b002f2a4b827e1f6dd7ae2bb0fe2a7b32f6ccc9..6e64e9ba79cdc54001f657dabcb3d77e20fc9330 100644 (file)
@@ -945,17 +945,18 @@ def _list_decorators():
             else:
                 # slice assignment requires __delitem__, insert, __len__
                 if index.stop is None:
-                    stop = 0
+                    stop = len(self)
                 elif index.stop < 0:
                     stop = len(self) + index.stop
                 else:
                     stop = index.stop
+                start = index.start or 0
                 step = index.step or 1
-                rng = range(index.start or 0, stop, step)
+                rng = range(start, stop, step)
                 if step == 1:
                     for i in rng:
-                        del self[index.start]
-                    i = index.start
+                        del self[start]
+                    i = start
                     for item in value:
                         self.insert(i, item)
                         i += 1
@@ -985,7 +986,7 @@ def _list_decorators():
                 fn(self, index)
         _tidy(__delitem__)
         return __delitem__
-    
+
     # Py2K
     def __setslice__(fn):
         def __setslice__(self, start, end, values):
index 3d48f1d76226cc4e52b322bec97810e245b2f743..023ed13d24d0841d80d4e36fcb7e9ef85eb522c0 100644 (file)
@@ -189,7 +189,7 @@ class CollectionsTest(_base.ORMTest):
                 del direct[::2]
                 del control[::2]
                 assert_eq()
-
+            
         if hasattr(direct, 'remove'):
             e = creator()
             direct.append(e)
@@ -199,8 +199,7 @@ class CollectionsTest(_base.ORMTest):
             control.remove(e)
             assert_eq()
         
-        # Py2K
-        if hasattr(direct, '__setslice__'):
+        if hasattr(direct, '__setitem__') or hasattr(direct, '__setslice__'):
             values = [creator(), creator()]
             direct[0:1] = values
             control[0:1] = values
@@ -226,7 +225,7 @@ class CollectionsTest(_base.ORMTest):
             control[1::2] = values
             assert_eq()
 
-        if hasattr(direct, '__delslice__'):
+        if hasattr(direct, '__delitem__') or hasattr(direct, '__delslice__'):
             for i in range(1, 4):
                 e = creator()
                 direct.append(e)
@@ -243,7 +242,6 @@ class CollectionsTest(_base.ORMTest):
             del direct[:]
             del control[:]
             assert_eq()
-        # end Py2K
         
         if hasattr(direct, 'extend'):
             values = [creator(), creator(), creator()]
@@ -343,6 +341,45 @@ class CollectionsTest(_base.ORMTest):
         self._test_list(list)
         self._test_list_bulk(list)
 
+    def test_list_setitem_with_slices(self):
+        
+        # this is a "list" that has no __setslice__
+        # or __delslice__ methods.  The __setitem__
+        # and __delitem__ must therefore accept
+        # slice objects (i.e. as in py3k)
+        class ListLike(object):
+            def __init__(self):
+                self.data = list()
+            def append(self, item):
+                self.data.append(item)
+            def remove(self, item):
+                self.data.remove(item)
+            def insert(self, index, item):
+                self.data.insert(index, item)
+            def pop(self, index=-1):
+                return self.data.pop(index)
+            def extend(self):
+                assert False
+            def __len__(self):
+                return len(self.data)
+            def __setitem__(self, key, value):
+                self.data[key] = value
+            def __getitem__(self, key):
+                return self.data[key]
+            def __delitem__(self, key):
+                del self.data[key]
+            def __iter__(self):
+                return iter(self.data)
+            __hash__ = object.__hash__
+            def __eq__(self, other):
+                return self.data == other
+            def __repr__(self):
+                return 'ListLike(%s)' % repr(self.data)
+
+        self._test_adapter(ListLike)
+        self._test_list(ListLike)
+        self._test_list_bulk(ListLike)
+
     def test_list_subclass(self):
         class MyList(list):
             pass