The default __reduce__ on the base object type obscured any
possibility of calling save_reduce().  Add a special hack for this.
The tests for this are much simpler now (no __getstate__ or
__getnewargs__ needed).
diff --git a/Lib/pickle.py b/Lib/pickle.py
index c1c7078..1cee4d5 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -27,7 +27,7 @@
 __version__ = "$Revision$"       # Code version
 
 from types import *
-from copy_reg import dispatch_table, safe_constructors
+from copy_reg import dispatch_table, safe_constructors, _reconstructor
 import marshal
 import sys
 import struct
@@ -320,6 +320,13 @@
             raise PicklingError("Tuple returned by %s must have "
                                 "exactly two or three elements" % reduce)
 
+        # XXX Temporary hack XXX
+        # Override the default __reduce__ for new-style class instances
+        if self.proto >= 2:
+            if func is _reconstructor:
+                self.save_newobj(obj)
+                return
+
         # Save the reduce() output and finally memoize the object
         self.save_reduce(func, args, state)
         self.memoize(obj)
@@ -369,14 +376,37 @@
         # Save a new-style class instance, using protocol 2.
         # XXX Much of this is still experimental.
         t = type(obj)
-        args = ()
         getnewargs = getattr(obj, "__getnewargs__", None)
         if getnewargs:
             args = getnewargs() # This better not reference obj
+        else:
+            for cls in int, long, float, complex, str, unicode, tuple:
+                if isinstance(obj, cls):
+                    args = (cls(obj),)
+                    break
+            else:
+                args = ()
+
+        save = self.save
+        write = self.write
+
         self.save_global(t)
-        self.save(args)
-        self.write(NEWOBJ)
+        save(args)
+        write(NEWOBJ)
         self.memoize(obj)
+
+        if isinstance(obj, list):
+            write(MARK)
+            for x in obj:
+                save(x)
+            write(APPENDS)
+        elif isinstance(obj, dict):
+            write(MARK)
+            for k, v in obj.iteritems():
+                save(k)
+                save(v)
+            write(SETITEMS)
+
         getstate = getattr(obj, "__getstate__", None)
         if getstate:
             state = getstate()
@@ -384,9 +414,8 @@
             state = getattr(obj, "__dict__", None)
             # XXX What about __slots__?
         if state is not None:
-            self.save(state)
-            self.write(BUILD)
-        return
+            save(state)
+            write(BUILD)
 
     # Methods below this point are dispatched through the dispatch table
 
@@ -1173,6 +1202,8 @@
     '\x7f'
     >>>
     """
+    # XXX This is still a quadratic algorithm.
+    # Should use hex() to get started.
     digits = []
     while not -128 <= x < 128:
         digits.append(x & 0xff)
@@ -1195,6 +1226,7 @@
     >>> decode_long("\x7f")
     127L
     """
+    # XXX This is quadratic too.
     x = 0L
     i = 0L
     for c in data:
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index ea658bb..cc464a9 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -301,43 +301,34 @@
                 self.assert_(x is y, (proto, x, s, y))
 
     def test_newobj_tuple(self):
-        x = MyTuple([1, 2, 3], foo=42, bar="hello")
+        x = MyTuple([1, 2, 3])
+        x.foo = 42
+        x.bar = "hello"
         s = self.dumps(x, 2)
         y = self.loads(s)
         self.assertEqual(tuple(x), tuple(y))
         self.assertEqual(x.__dict__, y.__dict__)
+##         import pickletools
+##         print
+##         pickletools.dis(s)
 
     def test_newobj_list(self):
-        x = MyList([1, 2, 3], foo=42, bar="hello")
+        x = MyList([1, 2, 3])
+        x.foo = 42
+        x.bar = "hello"
         s = self.dumps(x, 2)
         y = self.loads(s)
         self.assertEqual(list(x), list(y))
         self.assertEqual(x.__dict__, y.__dict__)
+##         import pickletools
+##         print
+##         pickletools.dis(s)
 
 class MyTuple(tuple):
-    def __new__(cls, *args, **kwds):
-        # Ignore **kwds
-        return tuple.__new__(cls, *args)
-    def __getnewargs__(self):
-        return (tuple(self),)
-    def __init__(self, *args, **kwds):
-        for k, v in kwds.items():
-            setattr(self, k, v)
+    pass
 
 class MyList(list):
-    def __new__(cls, *args, **kwds):
-        # Ignore **kwds
-        return list.__new__(cls, *args)
-    def __init__(self, *args, **kwds):
-        for k, v in kwds.items():
-            setattr(self, k, v)
-    def __getstate__(self):
-        return list(self), self.__dict__
-    def __setstate__(self, arg):
-        lst, dct = arg
-        for x in lst:
-            self.append(x)
-        self.__init__(**dct)
+    pass
 
 class AbstractPickleModuleTests(unittest.TestCase):