Skip to content

Commit d3cc08a

Browse files
committed
py: Support zip builtin feature
1 parent 5e97b9b commit d3cc08a

File tree

4 files changed

+92
-1
lines changed

4 files changed

+92
-1
lines changed

builtin/builtin.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func init() {
9292
// "super": py.SuperType,
9393
"tuple": py.TupleType,
9494
"type": py.TypeType,
95-
// "zip": py.ZipType,
95+
"zip": py.ZipType,
9696

9797
// Exceptions
9898
"ArithmeticError": py.ArithmeticError,

builtin/tests/builtin.py

+14
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,20 @@ class C: pass
232232
ok = True
233233
assert ok, "TypeError not raised"
234234

235+
doc="zip"
236+
ok = False
237+
a = [3, 4, 5, 6, 7]
238+
b = [8, 9, 10, 11, 12]
239+
assert [e for e in zip(a, b)] == [(3,8), (4,9), (5,10), (6,11), (7,12)]
240+
try:
241+
zip(1,2,3)
242+
except TypeError as e:
243+
print(e.args[0])
244+
if e.args[0] != "zip argument #1 must support iteration":
245+
raise
246+
ok = True
247+
assert ok, "TypeError not raised"
248+
235249
doc="__import__"
236250
lib = __import__("lib")
237251
assert lib.libfn() == 42

py/tests/zip.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2018 The go-python Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style
3+
# license that can be found in the LICENSE file.
4+
5+
doc="zip"
6+
a = [1, 2, 3, 4, 5]
7+
b = [10, 11, 12]
8+
c = [e for e in zip(a, b)]
9+
for idx, e in enumerate(c):
10+
assert a[idx] == e[0]
11+
assert b[idx] == e[1]
12+
doc="finished"

py/zip.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2018 The go-python Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package py
6+
7+
// A python Zip object
8+
type Zip struct {
9+
itTuple Tuple
10+
size int
11+
}
12+
13+
// A python ZipIterator iterator
14+
type ZipIterator struct {
15+
zip Zip
16+
}
17+
18+
var ZipType = NewTypeX("zip", `zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
19+
20+
Return a list of tuples, where each tuple contains the i-th element
21+
from each of the argument sequences. The returned list is truncated
22+
in length to the length of the shortest argument sequence.`,
23+
ZipTypeNew, nil)
24+
25+
// Type of this object
26+
func (z *Zip) Type() *Type {
27+
return ZipType
28+
}
29+
30+
// ZipTypeNew
31+
func ZipTypeNew(metatype *Type, args Tuple, kwargs StringDict) (Object, error) {
32+
tupleSize := len(args)
33+
itTuple := make(Tuple, tupleSize)
34+
for i := 0; i < tupleSize; i++ {
35+
item := args[i]
36+
iter, err := Iter(item)
37+
if err != nil {
38+
return nil, ExceptionNewf(TypeError, "zip argument #%d must support iteration", i+1)
39+
}
40+
itTuple[i] = iter
41+
}
42+
43+
return &Zip{itTuple: itTuple, size: tupleSize}, nil
44+
}
45+
46+
// Zip iterator
47+
func (z *Zip) M__iter__() (Object, error) {
48+
return z, nil
49+
}
50+
51+
func (z *Zip) M__next__() (Object, error) {
52+
result := make(Tuple, z.size)
53+
for i := 0; i < z.size; i++ {
54+
value, err := Next(z.itTuple[i])
55+
if err != nil {
56+
return nil, err
57+
}
58+
result[i] = value
59+
}
60+
return result, nil
61+
}
62+
63+
// Check interface is satisfied
64+
var _ I__iter__ = (*Zip)(nil)
65+
var _ I__next__ = (*Zip)(nil)

0 commit comments

Comments
 (0)