Backport 70140, 70141, 70143, and 70144.
Adds tests, switches from list to deque, fixes __reduce__
which was unnecessarily copying __keys.
diff --git a/Lib/collections.py b/Lib/collections.py
index 3319378..0ff5673 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -27,11 +27,11 @@
         except AttributeError:
             # Note the underlying data structure for this class is likely to
             # change in the future.  Do not rely on it or access it directly.
-            self.__keys = []
+            self.__keys = deque()
         self.update(*args, **kwds)
 
     def clear(self):
-        del self.__keys[:]
+        self.__keys.clear()
         dict.clear(self)
 
     def __setitem__(self, key, value):
@@ -58,16 +58,20 @@
 
     def __reduce__(self):
         items = [[k, self[k]] for k in self]
+        tmp = self.__keys
+        del self.__keys
         inst_dict = vars(self).copy()
-        inst_dict.pop('__keys', None)
-        return (self.__class__, (items,), inst_dict)
+        self.__keys = tmp
+        if inst_dict:
+            return (self.__class__, (items,), inst_dict)
+        return self.__class__, (items,)
 
     setdefault = MutableMapping.setdefault
     update = MutableMapping.update
     pop = MutableMapping.pop
 
     def keys(self):
-        return self.__keys[:]
+        return list(self.__keys)
 
     def values(self):
         return map(self.__getitem__, self.__keys)
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 95022a1..f232df4 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -717,6 +717,23 @@
             self.assertEquals(len(dup), len(od))
             self.assertEquals(type(dup), type(od))
 
+    def test_yaml_linkage(self):
+        # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
+        # In yaml, lists are native but tuples are not.
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        # yaml.dump(od) -->
+        # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n  - [b, 2]\n'
+        self.assert_(all(type(pair)==list for pair in od.__reduce__()[1]))
+
+    def test_reduce_not_too_fat(self):
+        # do not save instance dictionary if not needed
+        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+        od = OrderedDict(pairs)
+        self.assertEqual(len(od.__reduce__()), 2)
+        od.x = 10
+        self.assertEqual(len(od.__reduce__()), 3)
+
     def test_repr(self):
         od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
         self.assertEqual(repr(od),