Skip to content

Commit d0c72a9

Browse files
committed
vm: stop dict literals or dict comp panicing with non string keys
1 parent f16c0ab commit d0c72a9

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

notes.txt

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ FIXME recursive types for __repr__ in list, dict, tuple
3030
Limitations & Missing parts
3131
===========================
3232
* string keys only in dictionaries
33-
* intermediate fix - stop it panicing!
3433
* line numbers missing in SyntaxErrors
3534
* \N{...} escapes not implemented
3635
* lots of builtins still to implement

py/dict.go

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dict(**kwargs) -> new dictionary initialized with the name=value pairs
2020
var (
2121
StringDictType = NewType("dict", dictDoc)
2222
DictType = NewType("dict", dictDoc)
23+
expectingDict = ExceptionNewf(TypeError, "Expecting dict")
2324
)
2425

2526
// String to object dictionary
@@ -42,6 +43,15 @@ func NewStringDictSized(n int) StringDict {
4243
return make(StringDict, n)
4344
}
4445

46+
// Checks that obj is exactly a dictionary and returns an error if not
47+
func DictCheckExact(obj Object) (StringDict, error) {
48+
dict, ok := obj.(StringDict)
49+
if !ok {
50+
return nil, expectingDict
51+
}
52+
return dict, nil
53+
}
54+
4555
// Copy a dictionary
4656
func (d StringDict) Copy() StringDict {
4757
e := make(StringDict, len(d))

vm/eval.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -574,14 +574,13 @@ func do_MAP_ADD(vm *Vm, i int32) error {
574574
key := vm.TOP()
575575
value := vm.SECOND()
576576
vm.DROPN(2)
577-
dict := vm.PEEK(int(i))
578-
// FIXME assert(PyDict_CheckExact(dict));
579-
// err = PyDict_SetItem(map, key, value); /* v[w] = u */
580-
_, err := py.SetItem(dict, key, value)
577+
dictObj := vm.PEEK(int(i))
578+
dict, err := py.DictCheckExact(dictObj)
581579
if err != nil {
582580
return err
583581
}
584-
return nil
582+
_, err = dict.M__setitem__(key, value)
583+
return err
585584
}
586585

587586
// Returns with TOS to the caller of the function.
@@ -1233,13 +1232,16 @@ func do_SETUP_FINALLY(vm *Vm, delta int32) error {
12331232
// Store a key and value pair in a dictionary. Pops the key and value
12341233
// while leaving the dictionary on the stack.
12351234
func do_STORE_MAP(vm *Vm, arg int32) error {
1236-
key := string(vm.TOP().(py.String)) // FIXME
1235+
key := vm.TOP()
12371236
value := vm.SECOND()
12381237
dictObj := vm.THIRD()
12391238
vm.DROPN(2)
1240-
dict := dictObj.(py.StringDict)
1241-
dict[key] = value
1242-
return nil
1239+
dict, err := py.DictCheckExact(dictObj)
1240+
if err != nil {
1241+
return err
1242+
}
1243+
_, err = dict.M__setitem__(key, value)
1244+
return err
12431245
}
12441246

12451247
// Pushes a reference to the local co_varnames[var_num] onto the stack.

0 commit comments

Comments
 (0)