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())