yaegi
yaegi copied to clipboard
Still problems assigning to variables in other packages from `main`, whether in "binary" or fully-interpreted code
The following test case in interp/interp_eval_test.go
triggers an unexpected result
func TestIssue1632(t *testing.T) {
var j int
i := interp.New(interp.Options{})
if err := i.Use(interp.Exports{
"pkg/pkg": map[string]reflect.Value{
"J": reflect.ValueOf(&j).Elem(),
},
}); err != nil {
t.Fatal(err)
}
i.ImportUsed()
_, err := i.Eval(`func f(i int) int { return i }`)
if err != nil {
t.Fatal(err)
}
testJ := func(initJ int, src, expected string) {
t.Helper()
t.Run(src, func(t *testing.T) {
t.Helper()
j = initJ
assertEval(t, i, src, "", expected)
})
}
// These all work.
testJ(0, "pkg.J = 1; pkg.J", "1")
testJ(0, "pkg.J = pkg.J + 1; pkg.J", "1")
testJ(0, "f(1)", "1")
testJ(1, "f(pkg.J)", "1")
testJ(0, "pkg.J += 1; pkg.J", "1")
testJ(0, "pkg.J += 1; f(*&pkg.J)", "1")
testJ(0, "pkg.J++; f(*&pkg.J)", "1")
testJ(0, "*&pkg.J = f(1); pkg.J", "1")
testJ(0, "k := 1; pkg.J = k; pkg.J", "1")
testJ(0, "k := 1; *&pkg.J = f(k); pkg.J", "1")
testJ(0, "pkg.J += 1; f(*&pkg.J+1)", "2")
// These all fail
testJ(0, "pkg.J += 1; f(pkg.J)", "1") // get 0
testJ(0, "pkg.J += 1; f(pkg.J+1)", "2") // get 1
testJ(0, "pkg.J++; f(pkg.J)", "1") // get 0
testJ(0, "pkg.J = pkg.J + 1; f(pkg.J)", "1") // get 0
testJ(1, "pkg.J = pkg.J + pkg.J; f(pkg.J)", "2") // get 1
testJ(2, "pkg.J = f(1); pkg.J", "1") // get 2 (this one's especially surprising)
testJ(0, "k := 1; pkg.J = f(k); pkg.J", "1") // get 0
testJ(0, "pkg.J = 1; k := pkg.J; k", "1") // get 0
// Try these tests with strictly interpreted code
i = interp.New(interp.Options{})
_, err = i.Eval(`package pkg; var J int`)
if err != nil {
t.Fatal(err)
}
_, err = i.Eval(`package main
import "pkg"
func f(i int) int { return i }`)
if err != nil {
t.Fatal(err)
}
testJ = func(initJ int, src, expected string) {
t.Helper()
t.Run(src, func(t *testing.T) {
t.Helper()
res, err := i.Eval(fmt.Sprintf("pkg.J = %d; pkg.J", initJ))
if err != nil {
t.Fatal(err)
}
if res.Interface().(int) != initJ {
t.Fatalf("Expected pkg.J to be %d, got %v", initJ, res)
}
assertEval(t, i, src, "", expected)
})
}
// These all still succeed
testJ(0, "pkg.J = 1; pkg.J", "1")
testJ(0, "f(1)", "1")
testJ(1, "f(pkg.J)", "1")
testJ(0, "pkg.J += 1; pkg.J", "1")
testJ(0, "pkg.J += 1; f(*&pkg.J)", "1")
testJ(0, "pkg.J++; f(*&pkg.J)", "1")
testJ(0, "*&pkg.J = f(1); pkg.J", "1")
testJ(0, "k := 1; pkg.J = k; pkg.J", "1")
testJ(0, "k := 1; *&pkg.J = f(k); pkg.J", "1")
testJ(0, "pkg.J += 1; f(*&pkg.J+1)", "2")
// These all succeed but don't above
testJ(0, "pkg.J += 1; f(pkg.J)", "1")
testJ(0, "pkg.J += 1; f(pkg.J+1)", "2")
testJ(0, "pkg.J++; f(pkg.J)", "1")
testJ(0, "pkg.J = 1; k := pkg.J; k", "1")
// This fails but didn't used to
testJ(0, "pkg.J = pkg.J + 1; pkg.J", "1") // get 0
// These all still fail
testJ(0, "pkg.J = pkg.J + 1; f(pkg.J)", "1") // get 0
testJ(1, "pkg.J = pkg.J + pkg.J; f(pkg.J)", "2") // get 1
testJ(2, "pkg.J = f(1); pkg.J", "1") // get 2
testJ(0, "k := 1; pkg.J = f(k); pkg.J", "1") // get 0
}
Expected result
All tests pass
Got
--- FAIL: TestIssue1632 (0.00s)
--- FAIL: TestIssue1632/pkg.J_+=_1;_f(pkg.J) (0.00s)
interp_eval_test.go:1974: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_+=_1;_f(pkg.J+1) (0.00s)
interp_eval_test.go:1975: got 1, want 2
--- FAIL: TestIssue1632/pkg.J++;_f(pkg.J) (0.00s)
interp_eval_test.go:1976: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_pkg.J_+_1;_f(pkg.J) (0.00s)
interp_eval_test.go:1977: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_pkg.J_+_pkg.J;_f(pkg.J) (0.00s)
interp_eval_test.go:1978: got 1, want 2
--- FAIL: TestIssue1632/pkg.J_=_f(1);_pkg.J (0.00s)
interp_eval_test.go:1979: got 2, want 1
--- FAIL: TestIssue1632/k_:=_1;_pkg.J_=_f(k);_pkg.J (0.00s)
interp_eval_test.go:1980: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_1;_k_:=_pkg.J;_k (0.00s)
interp_eval_test.go:1981: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_pkg.J_+_1;_pkg.J#01 (0.00s)
interp_eval_test.go:2031: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_pkg.J_+_1;_f(pkg.J)#01 (0.00s)
interp_eval_test.go:2034: got 0, want 1
--- FAIL: TestIssue1632/pkg.J_=_pkg.J_+_pkg.J;_f(pkg.J)#01 (0.00s)
interp_eval_test.go:2035: got 1, want 2
--- FAIL: TestIssue1632/pkg.J_=_f(1);_pkg.J#01 (0.00s)
interp_eval_test.go:2036: got 2, want 1
--- FAIL: TestIssue1632/k_:=_1;_pkg.J_=_f(k);_pkg.J#01 (0.00s)
interp_eval_test.go:2037: got 0, want 1
FAIL
FAIL github.com/traefik/yaegi/interp 0.357s
FAIL
Yaegi Version
381e045
Additional Notes
Related: #1623 .
Obviously I changed assertEval
to use Errorf
instead of Fatalf
.