@@ -727,6 +727,77 @@ def test_dict_items(self):
727727 obj = d .items ()
728728 self ._test (obj )
729729
730+
731+ class SimpleSequence :
732+ def __getitem__ (self , n ):
733+ if n < 3 :
734+ return n
735+ raise IndexError
736+
737+
738+ class TestOldStackless_WrapFactories (StacklessPickleTestCase ):
739+ def test_iterator (self ):
740+ # Stackless prior to version 3.3.7 used to register its own __reduce__
741+ # method for 'iterator' with copy_reg. This method returned the function
742+ # stackless._wrap.iterator as iterator factory.
743+ #
744+ # This test case ensures that stackless can still unpickle old pickles:
745+
746+ # an old pickle, protocol 0 of iter(SimpleSequence())
747+ p = b'c_stackless._wrap\n iterator\n (ccopy_reg\n _reconstructor\n (ctest_pickle\n SimpleSequence\n c__builtin__\n object\n NtRL0L\n tR(tb.'
748+
749+ # Output of
750+ # from pickletools import dis; dis(p)
751+ # 0: c GLOBAL '_stackless._wrap iterator'
752+ # 27: ( MARK
753+ # 28: c GLOBAL 'copy_reg _reconstructor'
754+ # 53: ( MARK
755+ # 54: c GLOBAL 'test_pickle SimpleSequence'
756+ # 82: c GLOBAL '__builtin__ object'
757+ # 102: N NONE
758+ # 103: t TUPLE (MARK at 53)
759+ # 104: R REDUCE
760+ # 105: L LONG 0
761+ # 109: t TUPLE (MARK at 27)
762+ # 110: R REDUCE
763+ # 111: ( MARK
764+ # 112: t TUPLE (MARK at 111)
765+ # 113: b BUILD
766+ # 114: . STOP
767+ # highest protocol among opcodes = 0
768+
769+ x = self .loads (p )
770+ self .assertIs (type (x ), type (iter (SimpleSequence ())))
771+ self .assertListEqual (list (x ), [0 , 1 , 2 ])
772+
773+ def test_callable_iterator (self ):
774+ # Stackless prior to version 3.3.7 used to register its own __reduce__
775+ # method for 'callable_iterator' with copy_reg. This method returned the function
776+ # stackless._wrap.callable_iterator as callable_iterator factory.
777+ #
778+ # This test case ensures that stackless can still unpickle old pickles:
779+
780+ # an old pickle, protocol 0 of iter(bool, False)
781+ p = b'c_stackless._wrap\n callable_iterator\n (c__builtin__\n bool\n I00\n tR.'
782+
783+ # Output of
784+ # from pickletools import dis; dis(p)
785+ # 0: c GLOBAL '_stackless._wrap callable_iterator'
786+ # 36: ( MARK
787+ # 37: c GLOBAL '__builtin__ bool'
788+ # 55: I INT False
789+ # 59: t TUPLE (MARK at 36)
790+ # 60: R REDUCE
791+ # 61: . STOP
792+ # highest protocol among opcodes = 0
793+
794+ x = self .loads (p )
795+ # Use assertIsInstance, because x may be a subclass of i.
796+ # See bug https://bitbucket.org/stackless-dev/stackless/issues/127
797+ self .assertIsInstance (x , type (iter (bool , False )))
798+ self .assertListEqual (list (x ), [])
799+
800+
730801if __name__ == '__main__' :
731802 if not sys .argv [1 :]:
732803 sys .argv .append ('-v' )
0 commit comments