SF #904720:  dict.update should take a 2-tuple sequence like dict.__init_
(Championed by Bob Ippolito.)

The update() method for mappings now accepts all the same argument forms
as the dict() constructor.  This includes item lists and/or keyword
arguments.
diff --git a/Lib/UserDict.py b/Lib/UserDict.py
index 8141e7f..87cc6a3 100644
--- a/Lib/UserDict.py
+++ b/Lib/UserDict.py
@@ -4,8 +4,6 @@
     def __init__(self, dict=None, **kwargs):
         self.data = {}
         if dict is not None:
-            if not hasattr(dict,'keys'):
-                dict = type({})(dict)   # make mapping from a sequence
             self.update(dict)
         if len(kwargs):
             self.update(kwargs)
@@ -39,14 +37,18 @@
     def itervalues(self): return self.data.itervalues()
     def values(self): return self.data.values()
     def has_key(self, key): return self.data.has_key(key)
-    def update(self, dict):
-        if isinstance(dict, UserDict):
+    def update(self, dict=None, **kwargs):
+        if dict is None:
+            pass
+        elif isinstance(dict, UserDict):
             self.data.update(dict.data)
-        elif isinstance(dict, type(self.data)):
+        elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
             self.data.update(dict)
         else:
             for k, v in dict.items():
                 self[k] = v
+        if len(kwargs):
+            self.data.update(kwargs)
     def get(self, key, failobj=None):
         if not self.has_key(key):
             return failobj
@@ -136,17 +138,21 @@
             raise KeyError, 'container is empty'
         del self[k]
         return (k, v)
-    def update(self, other):
+    def update(self, other=None, **kwargs):
         # Make progressively weaker assumptions about "other"
-        if hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
+        if other is None:
+            pass
+        elif hasattr(other, 'iteritems'):  # iteritems saves memory and lookups
             for k, v in other.iteritems():
                 self[k] = v
-        elif hasattr(other, '__iter__'): # iter saves memory
-            for k in other:
-                self[k] = other[k]
-        else:
+        elif hasattr(other, 'keys'):
             for k in other.keys():
                 self[k] = other[k]
+        else:
+            for k, v in other:
+                self[k] = v
+        if kwargs:
+            self.update(kwargs)
     def get(self, key, default=None):
         try:
             return self[key]
diff --git a/Lib/os.py b/Lib/os.py
index 8cec912..fdb9a46 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -433,9 +433,6 @@
                 return key.upper() in self.data
             def get(self, key, failobj=None):
                 return self.data.get(key.upper(), failobj)
-            def update(self, dict):
-                for k, v in dict.items():
-                    self[k] = v
             def copy(self):
                 return dict(self)
 
@@ -447,9 +444,6 @@
             def __setitem__(self, key, item):
                 putenv(key, item)
                 self.data[key] = item
-            def update(self, dict):
-                for k, v in dict.items():
-                    self[k] = v
             try:
                 unsetenv
             except NameError:
diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py
index 99554c7..f3c7c8c 100644
--- a/Lib/test/test_call.py
+++ b/Lib/test/test_call.py
@@ -86,41 +86,41 @@
         self.assertRaises(TypeError, {}.keys, x=2, y=2)
 
     def test_oldargs1_0(self):
-        self.assertRaises(TypeError, {}.update)
+        self.assertRaises(TypeError, [].count)
 
     def test_oldargs1_1(self):
-        {}.update({})
+        [].count(1)
 
     def test_oldargs1_2(self):
-        self.assertRaises(TypeError, {}.update, {}, 1)
+        self.assertRaises(TypeError, [].count, 1, 2)
 
     def test_oldargs1_0_ext(self):
         try:
-            {}.update(*())
+            [].count(*())
         except TypeError:
             pass
         else:
             raise RuntimeError
 
     def test_oldargs1_1_ext(self):
-        {}.update(*({},))
+        [].count(*(1,))
 
     def test_oldargs1_2_ext(self):
         try:
-            {}.update(*({}, 2))
+            [].count(*(1, 2))
         except TypeError:
             pass
         else:
             raise RuntimeError
 
     def test_oldargs1_0_kw(self):
-        self.assertRaises(TypeError, {}.update, x=2)
+        self.assertRaises(TypeError, [].count, x=2)
 
     def test_oldargs1_1_kw(self):
-        self.assertRaises(TypeError, {}.update, {}, x=2)
+        self.assertRaises(TypeError, [].count, {}, x=2)
 
     def test_oldargs1_2_kw(self):
-        self.assertRaises(TypeError, {}.update, x=2, y=2)
+        self.assertRaises(TypeError, [].count, x=2, y=2)
 
 
 def test_main():
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index aa8f854..4b4e19c 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -253,7 +253,7 @@
 if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict update'
 d.clear()
 try: d.update(None)
-except AttributeError: pass
+except (TypeError, AttributeError): pass
 else: raise TestFailed, 'dict.update(None), AttributeError expected'
 class SimpleUserDict:
     def __init__(self):
diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py
index 602fd90..0ed4369 100644
--- a/Lib/test/test_userdict.py
+++ b/Lib/test/test_userdict.py
@@ -93,8 +93,12 @@
         #update
         p.update(self.reference)
         self.assertEqual(dict(p), self.reference)
+        items = p.items()
+        p = self._empty_mapping()
+        p.update(items)
+        self.assertEqual(dict(p), self.reference)
         d = self._full_mapping(self.reference)
-        #setdefaullt
+        #setdefault
         key, value = d.iteritems().next()
         knownkey, knownvalue = self.other.iteritems().next()
         self.assertEqual(d.setdefault(key, knownvalue), value)
diff --git a/Lib/weakref.py b/Lib/weakref.py
index 09bed65..5c66186 100644
--- a/Lib/weakref.py
+++ b/Lib/weakref.py
@@ -122,10 +122,15 @@
         else:
             return wr()
 
-    def update(self, dict):
+    def update(self, dict=None, **kwargs):
         d = self.data
-        for key, o in dict.items():
-            d[key] = ref(o, self.__makeremove(key))
+        if dict is not None:
+            if not hasattr(dict, "items"):
+                dict = type({})(dict)
+            for key, o in dict.items():
+                d[key] = ref(o, self.__makeremove(key))
+        if len(kwargs):
+            self.update(kwargs)
 
     def values(self):
         L = []
@@ -239,10 +244,15 @@
     def setdefault(self, key, default):
         return self.data.setdefault(ref(key, self._remove),default)
 
-    def update(self, dict):
+    def update(self, dict=None, **kwargs):
         d = self.data
-        for key, value in dict.items():
-            d[ref(key, self._remove)] = value
+        if dict is not None:
+            if not hasattr(dict, "items"):
+                dict = type({})(dict)
+            for key, value in dict.items():
+                d[ref(key, self._remove)] = value
+        if len(kwargs):
+            self.update(kwargs)
 
 
 class BaseIter: