Skip to content

Commit 9c120e6

Browse files
committed
Make generator protocol interface and adjust generator.go to use it
1 parent 4a525b9 commit 9c120e6

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

py/generator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (it *Generator) M__next__() Object {
7676
// without yielding another value. When send() is called to start the
7777
// generator, it must be called with None as the argument, because
7878
// there is no yield expression that could receive the value.
79-
func (it *Generator) Send(value Object) {
79+
func (it *Generator) Send(value Object) Object {
8080
panic("generator send not implemented")
8181
}
8282

@@ -88,7 +88,7 @@ func (it *Generator) Send(value Object) {
8888
// StopIteration exception is raised. If the generator function does
8989
// not catch the passed-in exception, or raises a different exception,
9090
// then that exception propagates to the caller.
91-
func (it *Generator) Throw(args Tuple, kwargs StringDict) {
91+
func (it *Generator) Throw(args Tuple, kwargs StringDict) Object {
9292
panic("generator throw not implemented")
9393
}
9494

@@ -102,9 +102,9 @@ func (it *Generator) Throw(args Tuple, kwargs StringDict) {
102102
// generator raises any other exception, it is propagated to the
103103
// caller. close() does nothing if the generator has already exited
104104
// due to an exception or normal exit.
105-
func (it *Generator) Close() {
105+
func (it *Generator) Close() Object {
106106
panic("generator close not implemented")
107107
}
108108

109109
// Check interface is satisfied
110-
var _ I_iterator = (*Generator)(nil)
110+
var _ I_generator = (*Generator)(nil)

py/internal.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,15 @@ func Next(self Object) Object {
247247
// FIXME should be TypeError
248248
panic(fmt.Sprintf("TypeError: '%s' object is not iterable", self.Type().Name))
249249
}
250+
251+
// Call send for the python object
252+
func Send(self, value Object) Object {
253+
if I, ok := self.(I_send); ok {
254+
return I.Send(value)
255+
} else if res, ok := TypeCall1(self, "send", value); ok {
256+
return res
257+
}
258+
259+
// FIXME should be TypeError
260+
panic(fmt.Sprintf("TypeError: '%s' object doesn't have send method", self.Type().Name))
261+
}

py/py.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,25 @@ type I_iterator interface {
560560
I__next__
561561
}
562562

563+
// Generator interfaces
564+
type I_send interface {
565+
Send(value Object) Object
566+
}
567+
type I_throw interface {
568+
Throw(args Tuple, kwargs StringDict) Object
569+
}
570+
type I_close interface {
571+
Close() Object
572+
}
573+
574+
// Interface all generators must satisfy
575+
type I_generator interface {
576+
I_iterator
577+
I_send
578+
I_throw
579+
I_close
580+
}
581+
563582
// Called (if present) by the reversed() built-in to implement reverse
564583
// iteration. It should return a new iterator object that iterates
565584
// over all the objects in the container in reverse order.

0 commit comments

Comments
 (0)