-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
Bug
The function Unmarshal doesn't have a case for handling the starlark.Bytes type.
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"
Metadata
Metadata
Assignees
Labels
No labels