traefik / yaegi

Yaegi is Another Elegant Go Interpreter
https://pkg.go.dev/github.com/traefik/yaegi
Apache License 2.0
6.94k stars 343 forks source link

go:generate yaegi extract (The generated file has errors) #1512

Closed yqchilde closed 1 year ago

yqchilde commented 1 year ago

The following program sample.go triggers an unexpected result

package log

func Error(args ...interface{}) {
    getCaller()
    log.l.Error(args...)
}

func Errorf(format string, args ...interface{}) {
    getCaller()
    log.l.Errorf(format, args...)
}

func Fatal(args ...interface{}) {
    getCaller()
    log.l.Fatal(args...)
}

func Fatalf(format string, args ...interface{}) {
    getCaller()
    log.l.Fatalf(format, args...)
}

Expected result

yaegiyu extract yaegi-test/pkg/log

package yaegi-test

import (
    "yaegi-test/pkg/log"
    "reflect"
)

func init() {
    Symbols["yaegi-test/pkg/log/log"] = map[string]reflect.Value{
        // function, constant and variable definitions
        "Error":     reflect.ValueOf(log.Error),
        "Errorf":    reflect.ValueOf(log.Errorf),
        "Fatal":     reflect.ValueOf(log.Fatal),
        "Fatalf":    reflect.ValueOf(log.Fatalf),
    }
}

Got

package yaegi-test

import (
    "yaegi-test/pkg/log"
    "reflect"
)

func init() {
    Symbols["yaegi-test/pkg/log/log"] = map[string]reflect.Value{
        // function, constant and variable definitions
        "Error":     reflect.ValueOf(log.Error),
        "Errorf":    reflect.ValueOf(log.Errorf),
        "Fatal":     reflect.ValueOf(logFatal),
        "Fatalf":    reflect.ValueOf(logFatalf),
    }
}

Yaegi Version

v0.15.0

Additional Notes

https://github.com/traefik/yaegi/blob/master/extract/extract.go#L116

Because logFatal is defined in restricted, errors are reported in the final generated file. I wonder if this key should be ignored directly from the map

mvertes commented 1 year ago

I do not understand exactly what is wrong. Is it the behaviour of yaegi extract or the behaviour of log functions called from the interpreter ? If you need to avoid the virtualisation layer for the log package, you can use yaegi -unrestricted or in the shell: export YAEGI_UNRESTRICTED=1.

yqchilde commented 1 year ago

Thanks.