SF 952807:  Unpickling pickled instances of subclasses of datetime.date,
datetime.datetime and datetime.time could yield insane objects.  Thanks
to Jiwon Seo for the fix.

Bugfix candidate.  I'll backport it to 2.3.
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 347b1a9..f7fec57 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -510,6 +510,9 @@
         dt2 = dt - delta
         self.assertEqual(dt2, dt - days)
 
+class SubclassDate(date):
+    sub_var = 1
+
 class TestDate(HarmlessMixedComparison):
     # Tests here should pass for both dates and datetimes, except for a
     # few tests that TestDateTime overrides.
@@ -1029,6 +1032,15 @@
         self.assertEqual(dt1.toordinal(), dt2.toordinal())
         self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month - 7)
 
+    def test_pickling_subclass_date(self):
+
+        args = 6, 7, 23
+        orig = SubclassDate(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
     def test_backdoor_resistance(self):
         # For fast unpickling, the constructor accepts a pickle string.
         # This is a low-overhead backdoor.  A user can (by intent or
@@ -1053,6 +1065,9 @@
 #############################################################################
 # datetime tests
 
+class SubclassDatetime(datetime):
+    sub_var = 1
+
 class TestDateTime(TestDate):
 
     theclass = datetime
@@ -1296,6 +1311,14 @@
         self.assertEqual(b.month, 2)
         self.assertEqual(b.day, 7)
 
+    def test_pickling_subclass_datetime(self):
+        args = 6, 7, 23, 20, 59, 1, 64**2
+        orig = SubclassDatetime(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
     def test_more_compare(self):
         # The test_compare() inherited from TestDate covers the error cases.
         # We just want to test lexicographic ordering on the members datetime
@@ -1500,6 +1523,9 @@
         self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month +
                                           dt1.second - 7)
 
+class SubclassTime(time):
+    sub_var = 1
+
 class TestTime(HarmlessMixedComparison):
 
     theclass = time
@@ -1700,6 +1726,14 @@
             derived = unpickler.loads(green)
             self.assertEqual(orig, derived)
 
+    def test_pickling_subclass_time(self):
+        args = 20, 59, 16, 64**2
+        orig = SubclassTime(*args)
+        for pickler, unpickler, proto in pickle_choices:
+            green = pickler.dumps(orig, proto)
+            derived = unpickler.loads(green)
+            self.assertEqual(orig, derived)
+
     def test_bool(self):
         cls = self.theclass
         self.failUnless(cls(1))