Skip to content

Cannot assign to variable in imported package #1623

Closed
@theclapp

Description

@theclapp

The following program sample.go triggers an unexpected result

package main

import (
	"fmt"
	"os"
	"reflect"

	"github.com/traefik/yaegi/interp"
)

func main() {
	var F float64

	i := interp.New(interp.Options{})
	if err := i.Use(interp.Exports{
		"pkg/pkg": map[string]reflect.Value{
			"F": reflect.ValueOf(&F).Elem(),
		},
	}); err != nil {
		panic(err)
	}
	i.ImportUsed()

	res, err := i.Eval("pkg.F++; pkg.F")
	if err != nil {
		panic(err)
	}
	if res.Interface().(float64) != 1.0 {
		fmt.Printf("F++: expected 1.0, got %v\n", res.Interface())
	}
	res, err = i.Eval("pkg.F = 4.0; pkg.F")
	if err != nil {
		fmt.Printf("F = 4.0: err: %v\n", err)
		os.Exit(1)
	}
	if res.Interface().(float64) != 4.0 {
		fmt.Printf("F = 4.0: Expected 4.0; got %v\n", res.Interface())
		os.Exit(1)
	}
}

Expected result

$ go run ./sample.go
// no output expected

Got

$ go run ./sample.go
F = 4.0: err: 1:28: cannot assign to %!s(float64=1) (float64 constant)

Yaegi Version

3fbebb3

Additional Notes

In test-case form: add this to the end of interp/interp_eval_test.go:

func TestIssue1623(t *testing.T) {
	var F float64
	Pf := &F
	var ii int
	var s string = "foo"

	i := interp.New(interp.Options{})
	if err := i.Use(interp.Exports{
		"pkg/pkg": map[string]reflect.Value{
			"F":  reflect.ValueOf(&F).Elem(),
			"Pf": reflect.ValueOf(&Pf).Elem(),
			"II": reflect.ValueOf(&ii).Elem(),
			"S":  reflect.ValueOf(&s).Elem(),
		},
	}); err != nil {
		t.Fatal(err)
	}
	i.ImportUsed()

	runTests(t, i, []testCase{
		// {desc: "F++", src: "pkg.F++; pkg.F", res: "1"},
		// {desc: "*Pf = 2", src: "*pkg.Pf = 2; *pkg.Pf", res: "2"},
		// {desc: "check F", src: "pkg.F", res: "2"},
		// {desc: "*(&F) = 3", src: "*(&pkg.F) = 3; pkg.F", res: "3"},
		{desc: "F = 4", src: "pkg.F = 4.0; pkg.F", res: "4"}, // breaks

		// {desc: "II++", src: "pkg.II++; pkg.II", res: "1"},
		{desc: "II = 2", src: "pkg.II = 2; pkg.II", res: "2"}, // breaks

		{desc: `S = "bar"`, src: `pkg.S = "bar"; pkg.S`, res: "bar"}, // breaks
	})
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions