[Jython-checkins] jython: PyListDerived should be iterated over and not plain copied for cases where

darjus.loktevic jython-checkins at python.org
Thu Nov 12 22:45:46 EST 2015


https://hg.python.org/jython/rev/522c0382a022
changeset:   7803:522c0382a022
user:        Darjus Loktevic <darjus at gmail.com>
date:        Fri Nov 13 14:45:38 2015 +1100
summary:
  PyListDerived should be iterated over and not plain copied for cases where someone subclasses list and overrides __iter__ + test

files:
  Lib/test/test_list_jy.py        |  27 ++++++++++++++++++--
  src/org/python/core/PyList.java |  10 +++++++-
  2 files changed, 33 insertions(+), 4 deletions(-)


diff --git a/Lib/test/test_list_jy.py b/Lib/test/test_list_jy.py
--- a/Lib/test/test_list_jy.py
+++ b/Lib/test/test_list_jy.py
@@ -52,7 +52,7 @@
 
     def test_tuple_equality(self):
         self.assertEqual([(1,), [1]].count([1]), 1) # http://bugs.jython.org/issue1317
- 
+
     def test_big_list(self):
         """Verify that fairly large collection literals of primitives can be constructed."""
         # use \n to separate to avoid parser problems
@@ -236,11 +236,32 @@
         self.assertEqual(jl, [1,2,3,4])
 
 
+class ListSubclassTestCase(unittest.TestCase):
+
+    def test_subclass_iter_copy(self):
+
+        class MyList(list):
+
+            def __iter__(self):
+                i = 0
+                results = super(MyList, self).__iter__()
+                for result in results:
+                    yield result
+                    i += 1
+
+                # add extra result for validation
+                yield i
+
+        lst = MyList(['a', 'b', 'c'])
+        self.assertEqual(list(lst), ['a', 'b', 'c', 3])
+
+
 def test_main():
-    test_support.run_unittest(ListTestCase,
+    test_support.run_unittest(ListSubclassTestCase,
+                              ListTestCase,
                               ThreadSafetyTestCase,
                               ExtendedSliceTestCase,
                               JavaListTestCase)
-
+    
 if __name__ == "__main__":
     test_main()
diff --git a/src/org/python/core/PyList.java b/src/org/python/core/PyList.java
--- a/src/org/python/core/PyList.java
+++ b/src/org/python/core/PyList.java
@@ -127,7 +127,15 @@
         if (seq == null) {
             return;
         }
-        if (seq instanceof PyList) {
+
+        /* PyListDerived should be iterated over and not plain copied for cases where someone subclasses list
+        and overrides __iter__
+         */
+        if (seq instanceof PyListDerived) {
+            for (PyObject item : seq.asIterable()) {
+                append(item);
+            }
+        } else if (seq instanceof PyList) {
             list.addAll(((PyList) seq).list); // don't convert
         } else if (seq instanceof PyTuple) {
             list.addAll(((PyTuple) seq).getList());

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list