Skip to content

Error in v1.10.1: interface {} is func(interface {}) float64, not func(string) float64 #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zachaller opened this issue Jan 20, 2023 · 11 comments
Labels

Comments

@zachaller
Copy link

We use this in argo-rollouts code base and when we dependabot upgraded use to 1.10 we now have our unit tests failing with this error

interface conversion: interface {} is func(interface {}) float64, not func(string) float64

I have done a little bit of digging and it seems like this file got added which defines a set of functions. This seems to break our env which we have defined here I think because it is missing the type of functions we have passed in such as asFloat

@antonmedv
Copy link
Member

I see. Will try to fix this bug.

@antonmedv antonmedv added the bug label Jan 20, 2023
@zachaller
Copy link
Author

@antonmedv awesome glad it is a bug, and thank you for the great library :D

@antonmedv
Copy link
Member

@zachaller will try to fix it over the weekend.

@antonmedv
Copy link
Member

I need little bit more info, as this code works as expected:

package main

import (
	"fmt"
	"reflect"
	"strconv"

	"github.com/antonmedv/expr"
)

func main() {
	env := map[string]interface{}{
		"int8":    int8(1),
		"asFloat": asFloat,
	}
	code := `asFloat(int8)`

	program, err := expr.Compile(code, expr.Env(env))
	if err != nil {
		panic(err)
	}

	output, err := expr.Run(program, env)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%T(%v)", output, output)
}

func asFloat(in interface{}) float64 {
	switch i := in.(type) {
	case float64:
		return i
	case float32:
		return float64(i)
	case int64:
		return float64(i)
	case int32:
		return float64(i)
	case int16:
		return float64(i)
	case int8:
		return float64(i)
	case int:
		return float64(i)
	case uint64:
		return float64(i)
	case uint32:
		return float64(i)
	case uint16:
		return float64(i)
	case uint8:
		return float64(i)
	case uint:
		return float64(i)
	case string:
		inAsFloat, err := strconv.ParseFloat(i, 64)
		if err == nil {
			return inAsFloat
		}
		panic(err)
	}
	panic(fmt.Sprintf("asFloat() not supported on %v %v", reflect.TypeOf(in), in))
}

Can you create an example with error? Thanks.

@xio812
Copy link

xio812 commented Jan 20, 2023

The error occurs when converting a string to float using asFloat: https://go.dev/play/p/6BG_QVOfdz6

@antonmedv
Copy link
Member

antonmedv commented Jan 20, 2023

Ok, thanks. This is a regression test:

func TestFastCall(t *testing.T) {
	env := map[string]interface{}{
		"func": func(in interface{}) float64 {
			return 8
		},
	}
	code := `func("8")`

	program, err := expr.Compile(code, expr.Env(env))
	assert.NoError(t, err)

	out, err := expr.Run(program, env)
	assert.NoError(t, err)
	assert.Equal(t, float64(8), out)
}

@antonmedv
Copy link
Member

Fixed in 9009d4d Will release a new version.

@antonmedv
Copy link
Member

@zachaller
Copy link
Author

Awesome thank you for the super quick turnaround!

@vincentbernat
Copy link
Contributor

I have another one:

interface conversion: interface {} is core.classifyStringFunc, not func(string) bool (1:1)

However, I have:

type classifyStringFunc func(string) bool

I can work around the issue with

type classifyStringFunc = func(string) bool

Maybe do you prefer another issue?

@antonmedv
Copy link
Member

Maybe do you prefer another issue?

Yes, please.

@antonmedv antonmedv changed the title 1.10 change in behavior Error in v1.10.1: interface {} is func(interface {}) float64, not func(string) float64 Jan 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants