diff --git a/src/runtime/dict.cpp b/src/runtime/dict.cpp index 03836522a5f7ec0530a8abd8b3c8399836abd51b..879f39bf7776dde47c4dffa2fa281509e882dbde 100644 --- a/src/runtime/dict.cpp +++ b/src/runtime/dict.cpp @@ -800,7 +800,7 @@ Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { if (args->size()) { Box* arg = args->elts[0]; static BoxedString* keys_str = getStaticString("keys"); - if (autoXDecref(getattrInternal<ExceptionStyle::CXX>(arg, keys_str))) { + if (PyObject_HasAttr(arg, keys_str)) { dictMerge(self, arg); } else { dictMergeFromSeq2(self, arg); diff --git a/test/tests/dict.py b/test/tests/dict.py index c1381358f5ac276b50d1af1585e21f4d451d785c..724e5b335ddbfc99763885c81c8d6915345cf120 100644 --- a/test/tests/dict.py +++ b/test/tests/dict.py @@ -240,3 +240,16 @@ print d # Remove an item using a different key: d = {1:1} d.pop(1L) + + +# dict() will try to access the "keys" attribute, but it should swallow all exceptions +class MyObj(object): + def __iter__(self): + print "iter!" + return [(1, 2)].__iter__() + + def __getattr__(self, attr): + print "getattr", attr + 1/0 + +print dict(MyObj())