From 337df2ad1ec2f2a13ef65dc8f56ce1ce8c8cec77 Mon Sep 17 00:00:00 2001 From: Kyle Ellrott Date: Wed, 18 Jan 2023 11:33:50 -0800 Subject: [PATCH] py: improve dict intialization method --- py/dict.go | 37 +++++++++++++++++++++++++++++++++++-- py/tests/dict.py | 15 +++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/py/dict.go b/py/dict.go index f0aa938c..9aac7631 100644 --- a/py/dict.go +++ b/py/dict.go @@ -9,7 +9,9 @@ package py -import "bytes" +import ( + "bytes" +) const dictDoc = `dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's @@ -22,7 +24,7 @@ dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)` var ( - StringDictType = NewType("dict", dictDoc) + StringDictType = NewTypeX("dict", dictDoc, DictNew, nil) DictType = NewType("dict", dictDoc) expectingDict = ExceptionNewf(TypeError, "a dict is required") ) @@ -97,6 +99,37 @@ func init() { // Used for variables etc where the keys can only be strings type StringDict map[string]Object +// DictNew +func DictNew(metatype *Type, args Tuple, kwargs StringDict) (Object, error) { + if len(args) > 1 { + return nil, ExceptionNewf(TypeError, "dict expects at most one argument") + } + out := NewStringDict() + if len(args) == 1 { + arg := args[0] + seq, err := SequenceList(arg) + if err != nil { + return nil, err + } + for _, i := range seq.Items { + switch z := i.(type) { + case Tuple: + if zStr, ok := z[0].(String); ok { + out[string(zStr)] = z[1] + } + default: + return nil, ExceptionNewf(TypeError, "non-tuple sequence") + } + } + } + if len(kwargs) > 0 { + for k, v := range kwargs { + out[k] = v + } + } + return out, nil +} + // Type of this StringDict object func (o StringDict) Type() *Type { return StringDictType diff --git a/py/tests/dict.py b/py/tests/dict.py index 8fc9619e..274f6c69 100644 --- a/py/tests/dict.py +++ b/py/tests/dict.py @@ -56,6 +56,21 @@ def doDel(d, key): assert not a.__contains__('hello') assert a.__contains__('hi') +doc="init" +a = dict( zip( "a,b,c".split(","), "1,2,3".split(",") ) ) +assert a["a"] == "1" +assert a["b"] == "2" +assert a["c"] == "3" + +a = dict(a="1", b="2", c="3") +assert a["a"] == "1" +assert a["b"] == "2" +assert a["c"] == "3" + +assertRaises(TypeError, dict, "a") +assertRaises(TypeError, dict, 1) +assertRaises(TypeError, dict, {"a":1}, {"b":2}) + doc="__contain__" a = {'hello': 'world'} assert a.__contains__('hello')