yaegi
yaegi copied to clipboard
Exported interface can not have Method named "Active"
The following program sample.go
triggers an unexpected result
// modified from interp/interp_export_test.go
package interp_test
import (
"reflect"
"testing"
"github.com/traefik/yaegi/interp"
)
type Helloer interface {
Hello()
Active() bool
}
func Hi(h Helloer) {
println("In Hi:")
h.Hello()
println("Active: ", h.Active())
}
type Wrap struct {
IValue interface{}
WHello func() // related to the Hello() method.
// Other interface method wrappers...
WActive func() bool
}
func (w Wrap) Hello() { w.WHello() }
func (w Wrap) Active() bool { return w.WActive() }
func TestInterface(t *testing.T) {
i := interp.New(interp.Options{})
// export the Wrap type to the interpreter under virtual "wrap" package
err := i.Use(interp.Exports{
"github.com/traefik/yaegi/interp_test/interp_test": {
"Helloer": reflect.ValueOf((*Helloer)(nil)),
"_Helloer": reflect.ValueOf((*Wrap)(nil)),
},
})
if err != nil {
t.Fatal(err)
}
eval(t, i, `
import "github.com/traefik/yaegi/interp_test"
type MyInt int
func (m MyInt) Hello() { println("hello from Myint", m) }
func (m MyInt) Active() bool { return false }
func NewMyInt(i int) interp_test.Helloer {
m := MyInt(i)
return m
}
`)
NewMyInt := eval(t, i, "NewMyInt").Interface().(func(int) Helloer)
w := NewMyInt(4)
Hi(w)
}
Expected result
=== RUN TestInterface
In Hi:
hello from Myint 4
Active: false
--- PASS: TestInterface (0.00s)
PASS
ok github.com/traefik/yaegi/interp 0.011s
Got
=== RUN TestInterface
11:7: panic
--- FAIL: TestInterface (0.00s)
panic: reflect.Set: value of type func() bool is not assignable to type func() [recovered]
panic: reflect.Set: value of type func() bool is not assignable to type func() [recovered]
panic: reflect.Set: value of type func() bool is not assignable to type func()
goroutine 34 [running]:
testing.tRunner.func1.2({0xcfd5c0, 0xc0002071f0})
/usr/local/go/src/testing/testing.go:1389 +0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1392 +0x39f
panic({0xcfd5c0, 0xc0002071f0})
/usr/local/go/src/runtime/panic.go:838 +0x207
github.com/traefik/yaegi/interp.runCfg.func1()
/workspaces/yaegi/interp/run.go:193 +0x145
panic({0xcfd5c0, 0xc0002071f0})
/usr/local/go/src/runtime/panic.go:838 +0x207
reflect.Value.assignTo({0xcf8ec0?, 0xc000356a80?, 0xff9c78?}, {0xe239f1, 0xb}, 0xcf4de0, 0x0)
/usr/local/go/src/reflect/value.go:3062 +0x2ac
reflect.Value.Set({0xcf4de0?, 0xc00020acd0?, 0xd54fa0?}, {0xcf8ec0?, 0xc000356a80?, 0x4fc1be?})
/usr/local/go/src/reflect/value.go:2088 +0xeb
github.com/traefik/yaegi/interp.genInterfaceWrapper.func1(0xcfc8c0?)
/workspaces/yaegi/interp/run.go:1108 +0x813
github.com/traefik/yaegi/interp._return.func1(0xc0003480b0)
/workspaces/yaegi/interp/run.go:2424 +0x22
github.com/traefik/yaegi/interp.runCfg(0xc000352000, 0xc0003480b0, 0xc0002c15c0?, 0xcfc8c0?)
/workspaces/yaegi/interp/run.go:201 +0x29d
github.com/traefik/yaegi/interp.genFunctionWrapper.func2.1({0xc0002044b0, 0x1, 0x1?})
/workspaces/yaegi/interp/run.go:1023 +0x4a5
github.com/traefik/yaegi/interp_test.TestInterface(0xc000228680)
/workspaces/yaegi/interp/interp_export_test.go:115 +0x402
testing.tRunner(0xc000228680, 0xe7d8a8)
/usr/local/go/src/testing/testing.go:1439 +0x102
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1486 +0x35f
FAIL github.com/traefik/yaegi/interp 0.013s
Yaegi Version
5665c9a4108e5f878c0d1d8d1e1913eb3c314154
Additional Notes
If I rename Active
to IsActive
or whatever, it works as expected.
Any progress on this? This strange issue blocks me export interface with name of Active
😂
@mvertes Happen to find similar behaviour occurred on macOS, while other platform worked as expected:
On host I export a function like FooWithCallback(func(error) bool)
, in script call this function with a callback returns false
.
FooWithCallback(func(_ error) bool {return false})
FooWithCallback
always reads true
on macOS
Yaegi Version
v0.11.2 & v0.12.0 go version go1.18.3 darwin/arm64