88using System . Numerics ;
99using System . Runtime . InteropServices ;
1010
11- using Microsoft . Scripting ;
12- using Microsoft . Scripting . Runtime ;
13- using Microsoft . Scripting . Utils ;
14-
1511using IronPython . Runtime ;
1612using IronPython . Runtime . Binding ;
1713using IronPython . Runtime . Exceptions ;
1814using IronPython . Runtime . Operations ;
1915using IronPython . Runtime . Types ;
2016
17+ using Microsoft . Scripting ;
18+ using Microsoft . Scripting . Runtime ;
19+
2120[ assembly: PythonModule ( "itertools" , typeof ( IronPython . Modules . PythonIterTools ) ) ]
2221namespace IronPython . Modules {
2322 public static class PythonIterTools {
@@ -233,7 +232,7 @@ private static void EnsureIterator(CodeContext/*!*/ context, object iter) {
233232 if ( iter == null ||
234233 ! PythonOps . HasAttr ( context , iter , "__iter__" ) &&
235234 ! PythonOps . HasAttr ( context , iter , "__getitem__" ) ) {
236- throw PythonOps . TypeError ( "'{0}' object is not iterable" , PythonOps . GetPythonTypeName ( iter ) ) ;
235+ throw PythonOps . TypeError ( "'{0}' object is not iterable" , PythonOps . GetPythonTypeName ( iter ) ) ;
237236 }
238237 }
239238
@@ -276,13 +275,13 @@ public count(BigInteger start) {
276275 InnerEnumerator = BigIntYielder ( this , start , 1 ) ;
277276 }
278277
279- public count ( int start = 0 , int step = 1 ) {
278+ public count ( int start = 0 , int step = 1 ) {
280279 _curInt = start ;
281280 _step = step ;
282281 InnerEnumerator = IntYielder ( this , start , step ) ;
283282 }
284283
285- public count ( [ DefaultParameterValue ( 0 ) ] int start , BigInteger step ) {
284+ public count ( [ DefaultParameterValue ( 0 ) ] int start , BigInteger step ) {
286285 _curInt = start ;
287286 _step = step ;
288287 InnerEnumerator = IntYielder ( this , start , step ) ;
@@ -300,7 +299,7 @@ public count(BigInteger start, BigInteger step) {
300299 InnerEnumerator = BigIntYielder ( this , start , step ) ;
301300 }
302301
303- public count ( CodeContext /*!*/ context , [ DefaultParameterValue ( 0 ) ] object start , [ DefaultParameterValue ( 1 ) ] object step ) {
302+ public count ( CodeContext /*!*/ context , [ DefaultParameterValue ( 0 ) ] object start , [ DefaultParameterValue ( 1 ) ] object step ) {
304303 EnsureNumeric ( context , start ) ;
305304 EnsureNumeric ( context , step ) ;
306305 _cur = start ;
@@ -315,7 +314,7 @@ private static void EnsureNumeric(CodeContext/*!*/ context, object num) {
315314 if ( num == null ||
316315 ! PythonOps . HasAttr ( context , num , "__int__" ) &&
317316 ! PythonOps . HasAttr ( context , num , "__float__" ) ) {
318- throw PythonOps . TypeError ( "a number is required" ) ;
317+ throw PythonOps . TypeError ( "a number is required" ) ;
319318 }
320319 }
321320
@@ -548,9 +547,9 @@ private IEnumerator<object> Yielder(IEnumerator iter) {
548547 private IEnumerator < object > Grouper ( IEnumerator iter , object curKey ) {
549548 while ( PythonContext . Equal ( GetKey ( iter . Current ) , curKey ) ) {
550549 yield return iter . Current ;
551- if ( ! MoveNextHelper ( iter ) ) {
552- _fFinished = true ;
553- yield break ;
550+ if ( ! MoveNextHelper ( iter ) ) {
551+ _fFinished = true ;
552+ yield break ;
554553 }
555554 }
556555 }
@@ -675,7 +674,7 @@ public zip_longest(params object[] iterables) {
675674 }
676675 }
677676
678- public zip_longest ( [ ParamDictionary ] IDictionary < object , object > paramDict , params object [ ] iterables ) {
677+ public zip_longest ( [ ParamDictionary ] IDictionary < object , object > paramDict , params object [ ] iterables ) {
679678 object fill ;
680679
681680 if ( paramDict . TryGetValue ( "fillvalue" , out fill ) ) {
@@ -760,11 +759,14 @@ private static Exception UnexpectedKeywordArgument(IDictionary<object, object> p
760759
761760 [ PythonType ]
762761 public class product : IterBase {
762+ private PythonTuple [ ] tuples ;
763+
763764 public product ( CodeContext context , params object [ ] iterables ) {
764- InnerEnumerator = Yielder ( ArrayUtils . ConvertAll ( iterables , x => new PythonList ( context , PythonOps . GetEnumerator ( x ) ) ) ) ;
765+ tuples = ArrayUtils . ConvertAll ( iterables , x => new PythonTuple ( PythonOps . GetEnumerator ( x ) ) ) ;
766+ InnerEnumerator = Yielder ( tuples ) ;
765767 }
766768
767- public product ( CodeContext context , [ ParamDictionary ] IDictionary < object , object > paramDict , params object [ ] iterables ) {
769+ public product ( CodeContext context , [ ParamDictionary ] IDictionary < object , object > paramDict , params object [ ] iterables ) {
768770 object repeat ;
769771 int iRepeat = 1 ;
770772 if ( paramDict . TryGetValue ( "repeat" , out repeat ) ) {
@@ -782,29 +784,28 @@ public product(CodeContext context, [ParamDictionary]IDictionary<object, object>
782784 throw UnexpectedKeywordArgument ( paramDict ) ;
783785 }
784786
785- PythonList [ ] finalIterables = new PythonList [ iterables . Length * iRepeat ] ;
787+ tuples = new PythonTuple [ iterables . Length * iRepeat ] ;
786788 for ( int i = 0 ; i < iRepeat ; i ++ ) {
787789 for ( int j = 0 ; j < iterables . Length ; j ++ ) {
788- finalIterables [ i * iterables . Length + j ] = new PythonList ( context , iterables [ j ] ) ;
790+ tuples [ i * iterables . Length + j ] = new PythonTuple ( iterables [ j ] ) ;
789791 }
790792 }
791- InnerEnumerator = Yielder ( finalIterables ) ;
793+ InnerEnumerator = Yielder ( tuples ) ;
792794 }
793795
794796 public PythonTuple __reduce__ ( ) {
795- // TODO
796797 return PythonTuple . MakeTuple (
797798 DynamicHelpers . GetPythonType ( this ) ,
798- PythonTuple . MakeTuple ( ) , // arguments
799- null // state
799+ PythonTuple . MakeTuple ( tuples ) , // arguments
800+ null // TODO: state
800801 ) ;
801802 }
802803
803804 public void __setstate__ ( object state ) {
804805 // TODO
805806 }
806807
807- private IEnumerator < object > Yielder ( PythonList [ ] iterables ) {
808+ private IEnumerator < object > Yielder ( PythonTuple [ ] iterables ) {
808809 if ( iterables . Length > 0 ) {
809810 IEnumerator [ ] enums = new IEnumerator [ iterables . Length ] ;
810811 enums [ 0 ] = iterables [ 0 ] . GetEnumerator ( ) ;
@@ -833,6 +834,7 @@ private IEnumerator<object> Yielder(PythonList[] iterables) {
833834 } else {
834835 yield return PythonTuple . EMPTY ;
835836 }
837+ tuples = new PythonTuple [ 1 ] { PythonTuple . EMPTY } ;
836838 }
837839 }
838840
@@ -987,7 +989,7 @@ public permutations(CodeContext context, object iterable) {
987989
988990 public permutations ( CodeContext context , object iterable , object r ) {
989991 _data = new PythonList ( context , iterable ) ;
990-
992+
991993 InnerEnumerator = Yielder ( GetR ( r , _data ) ) ;
992994 }
993995
@@ -1078,7 +1080,7 @@ public repeat(object @object) {
10781080 public repeat ( object @object , int times ) {
10791081 _obj = @object ;
10801082 InnerEnumerator = Yielder ( ) ;
1081- _remaining = times ;
1083+ _remaining = times < 0 ? 0 : times ;
10821084 }
10831085
10841086 private IEnumerator < object > Yielder ( ) {
@@ -1094,10 +1096,9 @@ public int __length_hint__() {
10941096 }
10951097
10961098 public PythonTuple __reduce__ ( ) {
1097- // TODO
10981099 return PythonTuple . MakeTuple (
10991100 DynamicHelpers . GetPythonType ( this ) ,
1100- PythonTuple . MakeTuple ( ) // arguments
1101+ _fInfinite ? PythonTuple . MakeTuple ( _obj ) : PythonTuple . MakeTuple ( _obj , _remaining ) // arguments
11011102 ) ;
11021103 }
11031104
@@ -1150,9 +1151,9 @@ IEnumerator IEnumerable.GetEnumerator() {
11501151
11511152 #endregion
11521153 }
1153-
1154+
11541155 [ PythonType ]
1155- public class starmap : IterBase {
1156+ public class starmap : IterBase {
11561157 public starmap ( CodeContext context , object function , object iterable ) {
11571158 InnerEnumerator = Yielder ( context , function , PythonOps . GetEnumerator ( iterable ) ) ;
11581159 }
@@ -1211,7 +1212,7 @@ public void __setstate__(object state) {
12111212
12121213 private IEnumerator < object > Yielder ( object predicate , IEnumerator iter ) {
12131214 while ( MoveNextHelper ( iter ) ) {
1214- if ( ! Converter . ConvertToBoolean (
1215+ if ( ! Converter . ConvertToBoolean (
12151216 _context . LanguageContext . CallSplat ( predicate , iter . Current )
12161217 ) ) {
12171218 break ;
@@ -1222,8 +1223,8 @@ private IEnumerator<object> Yielder(object predicate, IEnumerator iter) {
12221223 }
12231224 }
12241225
1225- [ PythonHidden ]
1226- public class TeeIterator : IEnumerator , IWeakReferenceable {
1226+ [ PythonType ( "_tee" ) ]
1227+ public sealed class TeeIterator : IEnumerator , IWeakReferenceable {
12271228 internal IEnumerator _iter ;
12281229 internal PythonList _data ;
12291230 private int _curIndex = - 1 ;
0 commit comments