Skip to content
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

bug: Marshal and Unmarshal don't support bytes #172

Open
HarikrishnanBalagopal opened this issue Feb 22, 2023 · 0 comments · May be fixed by #173
Open

bug: Marshal and Unmarshal don't support bytes #172

HarikrishnanBalagopal opened this issue Feb 22, 2023 · 0 comments · May be fixed by #173

Comments

@HarikrishnanBalagopal
Copy link

HarikrishnanBalagopal commented Feb 22, 2023

Bug

The function Unmarshal doesn't have a case for handling the starlark.Bytes type.

starlib/util/util.go

Lines 27 to 158 in 7fb7ff9

// Unmarshal decodes a starlark.Value into it's golang counterpart
func Unmarshal(x starlark.Value) (val interface{}, err error) {
switch v := x.(type) {
case starlark.NoneType:
val = nil
case starlark.Bool:
val = v.Truth() == starlark.True
case starlark.Int:
var tmp int
err = starlark.AsInt(x, &tmp)
val = tmp
case starlark.Float:
if f, ok := starlark.AsFloat(x); !ok {
err = fmt.Errorf("couldn't parse float")
} else {
val = f
}
case starlark.String:
val = v.GoString()
case startime.Time:
val = time.Time(v)
case *starlark.Dict:
var (
dictVal starlark.Value
pval interface{}
kval interface{}
keys []interface{}
vals []interface{}
// key as interface if found one key is not a string
ki bool
)
for _, k := range v.Keys() {
dictVal, _, err = v.Get(k)
if err != nil {
return
}
pval, err = Unmarshal(dictVal)
if err != nil {
err = fmt.Errorf("unmarshaling starlark value: %w", err)
return
}
kval, err = Unmarshal(k)
if err != nil {
err = fmt.Errorf("unmarshaling starlark key: %w", err)
return
}
if _, ok := kval.(string); !ok {
// found key as not a string
ki = true
}
keys = append(keys, kval)
vals = append(vals, pval)
}
// prepare result
rs := map[string]interface{}{}
ri := map[interface{}]interface{}{}
for i, key := range keys {
// key as interface
if ki {
ri[key] = vals[i]
} else {
rs[key.(string)] = vals[i]
}
}
if ki {
val = ri // map[interface{}]interface{}
} else {
val = rs // map[string]interface{}
}
case *starlark.List:
var (
i int
listVal starlark.Value
iter = v.Iterate()
value = make([]interface{}, v.Len())
)
defer iter.Done()
for iter.Next(&listVal) {
value[i], err = Unmarshal(listVal)
if err != nil {
return
}
i++
}
val = value
case starlark.Tuple:
var (
i int
tupleVal starlark.Value
iter = v.Iterate()
value = make([]interface{}, v.Len())
)
defer iter.Done()
for iter.Next(&tupleVal) {
value[i], err = Unmarshal(tupleVal)
if err != nil {
return
}
i++
}
val = value
case *starlark.Set:
fmt.Println("errnotdone: SET")
err = fmt.Errorf("sets aren't yet supported")
case *starlarkstruct.Struct:
if _var, ok := v.Constructor().(Unmarshaler); ok {
err = _var.UnmarshalStarlark(x)
if err != nil {
err = errors.Wrapf(err, "failed marshal %q to Starlark object", v.Constructor().Type())
return
}
val = _var
} else {
err = fmt.Errorf("constructor object from *starlarkstruct.Struct not supported Marshaler to starlark object: %s", v.Constructor().Type())
}
default:
fmt.Println("errbadtype:", x.Type())
err = fmt.Errorf("unrecognized starlark type: %s", x.Type())
}
return
}

Context

$ starlark
Welcome to Starlark (go.starlark.net)
>>> bytes([1,2])
b"\x01\x02"
@HarikrishnanBalagopal HarikrishnanBalagopal changed the title bug: Unmarshal doesn't support bytes for some reason bug: Unmarshal doesn't support bytes Feb 22, 2023
@HarikrishnanBalagopal HarikrishnanBalagopal changed the title bug: Unmarshal doesn't support bytes bug: Marshal and Unmarshal don't support bytes Feb 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant