Merged revisions 58886-58929 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r58892 | guido.van.rossum | 2007-11-06 15:32:56 -0800 (Tue, 06 Nov 2007) | 2 lines

  Add missing "return NULL" in overflow check in PyObject_Repr().
........
  r58893 | raymond.hettinger | 2007-11-06 17:13:09 -0800 (Tue, 06 Nov 2007) | 1 line

  Fix marshal's incorrect handling of subclasses of builtin types (backport candidate).
........
  r58895 | raymond.hettinger | 2007-11-06 18:26:17 -0800 (Tue, 06 Nov 2007) | 1 line

  Optimize dict.fromkeys() with dict inputs.  Useful for resetting bag/muliset counts for example.
........
  r58896 | raymond.hettinger | 2007-11-06 18:45:46 -0800 (Tue, 06 Nov 2007) | 1 line

  Add build option for faster loop execution.
........
  r58900 | nick.coghlan | 2007-11-07 03:57:51 -0800 (Wed, 07 Nov 2007) | 1 line

  Add missing NEWS entry
........
  r58905 | christian.heimes | 2007-11-07 09:50:54 -0800 (Wed, 07 Nov 2007) | 1 line

  Backported fix for bug #1392 from py3k branch r58903.
........
  r58906 | christian.heimes | 2007-11-07 10:30:22 -0800 (Wed, 07 Nov 2007) | 1 line

  Backport of Guido's review of my patch.
........
  r58908 | raymond.hettinger | 2007-11-07 18:52:43 -0800 (Wed, 07 Nov 2007) | 1 line

  Add set.isdisjoint()
........
  r58915 | raymond.hettinger | 2007-11-08 10:47:51 -0800 (Thu, 08 Nov 2007) | 1 line

  Reposition the decref (spotted by eagle-eye norwitz).
........
  r58920 | georg.brandl | 2007-11-09 04:31:43 -0800 (Fri, 09 Nov 2007) | 2 lines

  Fix seealso link to sets docs. Do not merge to Py3k.
........
  r58921 | georg.brandl | 2007-11-09 05:08:48 -0800 (Fri, 09 Nov 2007) | 2 lines

  Fix misleading example.
........
  r58923 | georg.brandl | 2007-11-09 09:33:23 -0800 (Fri, 09 Nov 2007) | 3 lines

  Correct a comment about testing methods - nowadays most
  tests don't run directly on import.
........
  r58924 | martin.v.loewis | 2007-11-09 14:56:30 -0800 (Fri, 09 Nov 2007) | 2 lines

  Add Amaury Forgeot d'Arc.
........
  r58925 | raymond.hettinger | 2007-11-09 15:14:44 -0800 (Fri, 09 Nov 2007) | 1 line

  Optimize common case for dict.fromkeys().
........
  r58927 | raymond.hettinger | 2007-11-09 17:54:03 -0800 (Fri, 09 Nov 2007) | 1 line

  Use a freelist to speed-up block allocation and deallocation in collections.deque().
........
  r58929 | guido.van.rossum | 2007-11-10 14:12:24 -0800 (Sat, 10 Nov 2007) | 3 lines

  Issue 1416.  Add getter, setter, deleter methods to properties that can be
  used as decorators to create fully-populated properties.
........
diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst
index 0cf69b4..bc43184 100644
--- a/Doc/library/marshal.rst
+++ b/Doc/library/marshal.rst
@@ -45,12 +45,6 @@
 (they will cause infinite loops).
 
 .. warning::
-
-   Some unsupported types such as subclasses of builtins will appear to marshal
-   and unmarshal correctly, but in fact, their type will change and the
-   additional subclass functionality and instance attributes will be lost.
-
-.. warning::
    
    On machines where C's ``long int`` type has more than 32 bits (such as the
    DEC Alpha), it is possible to create plain Python integers that are longer
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 9073bca..d6a853b 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1418,6 +1418,13 @@
 
    Test *x* for non-membership in *s*.
 
+.. method:: set.isdisjoint(other)
+
+   Return True if the set has no elements in common with *other*.
+   Sets are disjoint if and only if their interesection is the empty set.
+
+   .. versionadded:: 2.6
+
 .. method:: set.issubset(other)
             set <= other
 
diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst
index 30adac9..4226ffd 100644
--- a/Doc/tutorial/introduction.rst
+++ b/Doc/tutorial/introduction.rst
@@ -507,8 +507,9 @@
 
 The built-in function :func:`len` also applies to lists::
 
+   >>> a = ['a', 'b', 'c', 'd']
    >>> len(a)
-   8
+   4
 
 It is possible to nest lists (create lists containing other lists), for
 example::
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index cd92511..3a24b22 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -588,10 +588,9 @@
                 abstest = 'test.' + test
             the_package = __import__(abstest, globals(), locals(), [])
             the_module = getattr(the_package, test)
-            # Most tests run to completion simply as a side-effect of
-            # being imported.  For the benefit of tests that can't run
-            # that way (like test_threaded_import), explicitly invoke
-            # their test_main() function (if it exists).
+            # Old tests run to completion simply as a side-effect of
+            # being imported.  For tests based on unittest or doctest,
+            # explicitly invoke their test_main() function (if it exists).
             indirect_test = getattr(the_module, "test_main", None)
             if indirect_test is not None:
                 indirect_test()
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 961369f..1ea93bb 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1984,6 +1984,71 @@
             p = property(_testcapi.test_with_docstring)
 
 
+def properties_plus():
+    class C:
+        foo = property(doc="hello")
+        @foo.getter
+        def foo(self):
+            return self._foo
+        @foo.setter
+        def foo(self, value):
+            self._foo = abs(value)
+        @foo.deleter
+        def foo(self):
+            del self._foo
+    c = C()
+    assert C.foo.__doc__ == "hello"
+    assert not hasattr(c, "foo")
+    c.foo = -42
+    assert c.foo == 42
+    del c.foo
+    assert not hasattr(c, "foo")
+
+    class D(C):
+        @C.foo.deleter
+        def foo(self):
+            try:
+                del self._foo
+            except AttributeError:
+                pass
+    d = D()
+    d.foo = 24
+    assert d.foo == 24
+    del d.foo
+    del d.foo
+
+    class E:
+        @property
+        def foo(self):
+            return self._foo
+        @foo.setter
+        def foo (self, value):
+            raise RuntimeError
+        @foo.setter
+        @foo.deleter
+        def foo(self, value=None):
+            if value is None:
+                del self._foo
+            else:
+                self._foo = abs(value)
+    e = E()
+    e.foo = -42
+    assert e.foo == 42
+    del e.foo
+
+    class F(E):
+        @E.foo.deleter
+        def foo(self):
+            del self._foo
+        @foo.setter
+        def foo(self, value):
+            self._foo = max(0, value)
+    f = F()
+    f.foo = -10
+    assert f.foo == 0
+    del f.foo
+
+
 def supers():
     if verbose: print("Testing super...")
 
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 89c127a..56ce722 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -236,6 +236,10 @@
 
         self.assertRaises(Exc, baddict2.fromkeys, [1])
 
+        # test fast path for dictionary inputs
+        d = dict(zip(range(6), range(6)))
+        self.assertEqual(dict.fromkeys(d, 0), dict(zip(range(6), [0]*6)))
+
     def test_copy(self):
         d = {1:1, 2:2, 3:3}
         self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py
index 1e3520f..fb70ced 100644
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -188,6 +188,17 @@
         last.append([0])
         self.assertRaises(ValueError, marshal.dumps, head)
 
+    def test_exact_type_match(self):
+        # Former bug:
+        #   >>> class Int(int): pass
+        #   >>> type(loads(dumps(Int())))
+        #   <type 'int'>
+        for typ in (int, float, complex, tuple, list, dict, set, frozenset):
+            # Note: str sublclasses are not tested because they get handled
+            # by marshal's routines for objects supporting the buffer API.
+            subtyp = type('subtyp', (typ,), {})
+            self.assertRaises(ValueError, marshal.dumps, subtyp())
+
 def test_main():
     test_support.run_unittest(IntTestCase,
                               FloatTestCase,
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index 86a5636..ba5801d 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -102,6 +102,20 @@
             self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
             self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
 
+    def test_isdisjoint(self):
+        def f(s1, s2):
+            'Pure python equivalent of isdisjoint()'
+            return not set(s1).intersection(s2)
+        for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
+            s1 = self.thetype(larg)
+            for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
+                for C in set, frozenset, dict.fromkeys, str, list, tuple:
+                    s2 = C(rarg)
+                    actual = s1.isdisjoint(s2)
+                    expected = f(s1, s2)
+                    self.assertEqual(actual, expected)
+                    self.assert_(actual is True or actual is False)
+
     def test_and(self):
         i = self.s.intersection(self.otherword)
         self.assertEqual(self.s & set(self.otherword), i)
@@ -701,6 +715,18 @@
         result = empty_set & self.set
         self.assertEqual(result, empty_set)
 
+    def test_self_isdisjoint(self):
+        result = self.set.isdisjoint(self.set)
+        self.assertEqual(result, not self.set)
+
+    def test_empty_isdisjoint(self):
+        result = self.set.isdisjoint(empty_set)
+        self.assertEqual(result, True)
+
+    def test_isdisjoint_empty(self):
+        result = empty_set.isdisjoint(self.set)
+        self.assertEqual(result, True)
+
     def test_self_symmetric_difference(self):
         result = self.set ^ self.set
         self.assertEqual(result, empty_set)
@@ -879,6 +905,22 @@
         result = self.set & set([8])
         self.assertEqual(result, empty_set)
 
+    def test_isdisjoint_subset(self):
+        result = self.set.isdisjoint(set((2, 4)))
+        self.assertEqual(result, False)
+
+    def test_isdisjoint_superset(self):
+        result = self.set.isdisjoint(set([2, 4, 6, 8]))
+        self.assertEqual(result, False)
+
+    def test_isdisjoint_overlap(self):
+        result = self.set.isdisjoint(set([3, 4, 5]))
+        self.assertEqual(result, False)
+
+    def test_isdisjoint_non_overlap(self):
+        result = self.set.isdisjoint(set([8]))
+        self.assertEqual(result, True)
+
     def test_sym_difference_subset(self):
         result = self.set ^ set((2, 4))
         self.assertEqual(result, set([6]))
@@ -1497,11 +1539,14 @@
     def test_inline_methods(self):
         s = set('november')
         for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
-            for meth in (s.union, s.intersection, s.difference, s.symmetric_difference):
+            for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
                 for g in (G, I, Ig, L, R):
                     expected = meth(data)
                     actual = meth(G(data))
-                    self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
+                    if isinstance(expected, bool):
+                        self.assertEqual(actual, expected)
+                    else:
+                        self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
                 self.assertRaises(TypeError, meth, X(s))
                 self.assertRaises(TypeError, meth, N(s))
                 self.assertRaises(ZeroDivisionError, meth, E(s))
diff --git a/Misc/developers.txt b/Misc/developers.txt
index 32c1c46..7fdfb33 100644
--- a/Misc/developers.txt
+++ b/Misc/developers.txt
@@ -17,6 +17,9 @@
 Permissions History
 -------------------
 
+- Amaury Forgeot d'Arc was given SVN access on 9 November 2007 by MvL,
+  for general contributions to Python.
+
 - Christian Heimes was given SVN access on 31 October 2007 by MvL,
   for general contributions to Python.
 
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index a26b572..85709a9 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -51,6 +51,10 @@
 	PyObject *data[BLOCKLEN];
 } block;
 
+#define MAXFREEBLOCKS 10
+static int numfreeblocks = 0;
+static block *freeblocks[MAXFREEBLOCKS];
+
 static block *
 newblock(block *leftlink, block *rightlink, int len) {
 	block *b;
@@ -66,16 +70,32 @@
 				"cannot add more blocks to the deque");
 		return NULL;
 	}
-	b = PyMem_Malloc(sizeof(block));
-	if (b == NULL) {
-		PyErr_NoMemory();
-		return NULL;
+	if (numfreeblocks) {
+		numfreeblocks -= 1;
+		b = freeblocks[numfreeblocks];
+	} else {
+		b = PyMem_Malloc(sizeof(block));
+		if (b == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
 	}
 	b->leftlink = leftlink;
 	b->rightlink = rightlink;
 	return b;
 }
 
+void
+freeblock(block *b)
+{
+	if (numfreeblocks < MAXFREEBLOCKS) {
+		freeblocks[numfreeblocks] = b;
+		numfreeblocks++;
+	} else {
+		PyMem_Free(b);
+	}
+}
+
 typedef struct {
 	PyObject_HEAD
 	block *leftblock;
@@ -161,7 +181,7 @@
 		} else {
 			prevblock = deque->rightblock->leftlink;
 			assert(deque->leftblock != deque->rightblock);
-			PyMem_Free(deque->rightblock);
+			freeblock(deque->rightblock);
 			prevblock->rightlink = NULL;
 			deque->rightblock = prevblock;
 			deque->rightindex = BLOCKLEN - 1;
@@ -198,7 +218,7 @@
 		} else {
 			assert(deque->leftblock != deque->rightblock);
 			prevblock = deque->leftblock->rightlink;
-			PyMem_Free(deque->leftblock);
+			freeblock(deque->leftblock);
 			assert(prevblock != NULL);
 			prevblock->leftlink = NULL;
 			deque->leftblock = prevblock;
@@ -559,7 +579,7 @@
 	if (deque->leftblock != NULL) {
 		deque_clear(deque);
 		assert(deque->leftblock != NULL);
-		PyMem_Free(deque->leftblock);
+		freeblock(deque->leftblock);
 	}
 	deque->leftblock = NULL;
 	deque->rightblock = NULL;
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 30ba461..a0fc217 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1099,6 +1099,60 @@
 	{0}
 };
 
+PyDoc_STRVAR(getter_doc,
+	     "Descriptor to change the getter on a property.");
+
+PyObject *
+property_getter(PyObject *self, PyObject *getter)
+{
+	Py_XDECREF(((propertyobject *)self)->prop_get);
+	if (getter == Py_None)
+		getter = NULL;
+	Py_XINCREF(getter);
+	((propertyobject *)self)->prop_get = getter;
+	Py_INCREF(self);
+	return self;
+}
+
+PyDoc_STRVAR(setter_doc,
+	     "Descriptor to change the setter on a property.\n");
+
+PyObject *
+property_setter(PyObject *self, PyObject *setter)
+{
+	Py_XDECREF(((propertyobject *)self)->prop_set);
+	if (setter == Py_None)
+		setter = NULL;
+	Py_XINCREF(setter);
+	((propertyobject *)self)->prop_set = setter;
+	Py_INCREF(self);
+	return self;
+}
+
+PyDoc_STRVAR(deleter_doc,
+	     "Descriptor to change the deleter on a property.");
+
+PyObject *
+property_deleter(PyObject *self, PyObject *deleter)
+{
+	Py_XDECREF(((propertyobject *)self)->prop_del);
+	if (deleter == Py_None)
+		deleter = NULL;
+	Py_XINCREF(deleter);
+	((propertyobject *)self)->prop_del = deleter;
+	Py_INCREF(self);
+	return self;
+}
+
+
+
+static PyMethodDef property_methods[] = {
+	{"getter", property_getter, METH_O, getter_doc},
+	{"setter", property_setter, METH_O, setter_doc},
+	{"deleter", property_deleter, METH_O, deleter_doc},
+	{0}
+};
+
 
 static void
 property_dealloc(PyObject *self)
@@ -1251,7 +1305,7 @@
 	0,					/* tp_weaklistoffset */
 	0,					/* tp_iter */
 	0,					/* tp_iternext */
-	0,					/* tp_methods */
+	property_methods,			/* tp_methods */
 	property_members,			/* tp_members */
 	0,					/* tp_getset */
 	0,					/* tp_base */
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 4230125..7bff7d8 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1175,6 +1175,25 @@
 	if (d == NULL)
 		return NULL;
 
+	if (PyDict_CheckExact(d) && PyDict_CheckExact(seq)) {
+		PyDictObject *mp = (PyDictObject *)d;
+		PyObject *oldvalue;
+		Py_ssize_t pos = 0;
+		PyObject *key;
+		long hash;
+
+		if (dictresize(mp, PySet_GET_SIZE(seq)))
+			return NULL;
+
+		while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
+			Py_INCREF(key);
+			Py_INCREF(value);
+			if (insertdict(mp, key, hash, value))
+				return NULL;
+		}
+		return d;
+	}
+
 	if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) {
 		PyDictObject *mp = (PyDictObject *)d;
 		Py_ssize_t pos = 0;
@@ -1199,19 +1218,24 @@
 		return NULL;
 	}
 
-	for (;;) {
-		key = PyIter_Next(it);
-		if (key == NULL) {
-			if (PyErr_Occurred())
+	if (PyDict_CheckExact(d)) {
+		while ((key = PyIter_Next(it)) != NULL) {
+			status = PyDict_SetItem(d, key, value);
+			Py_DECREF(key);
+			if (status < 0)
 				goto Fail;
-			break;
 		}
-		status = PyObject_SetItem(d, key, value);
-		Py_DECREF(key);
-		if (status < 0)
-			goto Fail;
+	} else {
+		while ((key = PyIter_Next(it)) != NULL) {
+			status = PyObject_SetItem(d, key, value);
+			Py_DECREF(key);
+			if (status < 0)
+				goto Fail;
+		}
 	}
 
+	if (PyErr_Occurred())
+		goto Fail;
 	Py_DECREF(it);
 	return d;
 
diff --git a/Objects/setobject.c b/Objects/setobject.c
index ba7d2c4..f6ea441 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1314,6 +1314,73 @@
 	return (PyObject *)so;
 }
 
+static PyObject *
+set_isdisjoint(PySetObject *so, PyObject *other)
+{
+	PyObject *key, *it, *tmp;
+
+	if ((PyObject *)so == other) {
+		if (PySet_GET_SIZE(so) == 0)
+			Py_RETURN_TRUE;
+		else
+			Py_RETURN_FALSE;
+	}
+
+	if (PyAnySet_CheckExact(other)) {		
+		Py_ssize_t pos = 0;
+		setentry *entry;
+
+		if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+			tmp = (PyObject *)so;
+			so = (PySetObject *)other;
+			other = tmp;
+		}
+		while (set_next((PySetObject *)other, &pos, &entry)) {
+			int rv = set_contains_entry(so, entry);
+			if (rv == -1)
+				return NULL;
+			if (rv)
+				Py_RETURN_FALSE;
+		}
+		Py_RETURN_TRUE;
+	}
+
+	it = PyObject_GetIter(other);
+	if (it == NULL)
+		return NULL;
+
+	while ((key = PyIter_Next(it)) != NULL) {
+		int rv;
+		setentry entry;
+		long hash = PyObject_Hash(key);
+
+		if (hash == -1) {
+			Py_DECREF(key);
+			Py_DECREF(it);
+			return NULL;
+		}
+		entry.hash = hash;
+		entry.key = key;
+		rv = set_contains_entry(so, &entry);
+		Py_DECREF(key);
+		if (rv == -1) {
+			Py_DECREF(it);
+			return NULL;
+		}
+		if (rv) {
+			Py_DECREF(it);
+			Py_RETURN_FALSE;
+		}
+	}
+	Py_DECREF(it);
+	if (PyErr_Occurred())
+		return NULL;
+	Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if two sets have a null intersection.");
+
 static int
 set_difference_update_internal(PySetObject *so, PyObject *other)
 {
@@ -1839,6 +1906,8 @@
 	 intersection_doc},
 	{"intersection_update",(PyCFunction)set_intersection_update,	METH_O,
 	 intersection_update_doc},
+	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
+	 isdisjoint_doc},
 	{"issubset",	(PyCFunction)set_issubset,	METH_O,
 	 issubset_doc},
 	{"issuperset",	(PyCFunction)set_issuperset,	METH_O,
@@ -1960,6 +2029,8 @@
 	 difference_doc},
 	{"intersection",(PyCFunction)set_intersection,	METH_O,
 	 intersection_doc},
+	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
+	 isdisjoint_doc},
 	{"issubset",	(PyCFunction)set_issubset,	METH_O,
 	 issubset_doc},
 	{"issuperset",	(PyCFunction)set_issuperset,	METH_O,
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 8761477..2e729ea 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -611,6 +611,7 @@
 	if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) {
 		PyErr_SetString(PyExc_OverflowError,
 			"bytes object is too large to make repr");
+                return NULL;
 	}
 	v = PyUnicode_FromUnicode(NULL, newsize);
 	if (v == NULL) {
diff --git a/Python/ceval.c b/Python/ceval.c
index c0e0993..b42444d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2011,7 +2011,18 @@
 		PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
 		case JUMP_ABSOLUTE:
 			JUMPTO(oparg);
+#if FAST_LOOPS
+			/* Enabling this path speeds-up all while and for-loops by bypassing
+                           the per-loop checks for signals.  By default, this should be turned-off
+                           because it prevents detection of a control-break in tight loops like
+                           "while 1: pass".  Compile with this option turned-on when you need
+                           the speed-up and do not need break checking inside tight loops (ones
+                           that contain only instructions ending with goto fast_next_opcode). 
+                        */
+			goto fast_next_opcode;
+#else
 			continue;
+#endif
 
 		case GET_ITER:
 			/* before: [obj]; after [getiter(obj)] */
diff --git a/Python/marshal.c b/Python/marshal.c
index a40aecc..3e106c2 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -147,7 +147,7 @@
 	else if (v == Py_True) {
 	        w_byte(TYPE_TRUE, p);
 	}
-	else if (PyLong_Check(v)) {
+	else if (PyLong_CheckExact(v)) {
 		long x = PyLong_AsLong(v);
 		if ((x == -1)  && PyErr_Occurred()) {
 			PyLongObject *ob = (PyLongObject *)v;
@@ -175,7 +175,7 @@
 			}
 		}
 	}
-	else if (PyFloat_Check(v)) {
+	else if (PyFloat_CheckExact(v)) {
 		if (p->version > 1) {
 			unsigned char buf[8];
 			if (_PyFloat_Pack8(PyFloat_AsDouble(v), 
@@ -196,7 +196,7 @@
 		}
 	}
 #ifndef WITHOUT_COMPLEX
-	else if (PyComplex_Check(v)) {
+	else if (PyComplex_CheckExact(v)) {
 		if (p->version > 1) {
 			unsigned char buf[8];
 			if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
@@ -228,7 +228,7 @@
 		}
 	}
 #endif
-	else if (PyString_Check(v)) {
+	else if (PyString_CheckExact(v)) {
 		w_byte(TYPE_STRING, p);
 		n = PyString_GET_SIZE(v);
 		if (n > INT_MAX) {
@@ -240,7 +240,7 @@
 		w_long((long)n, p);
 		w_string(PyString_AS_STRING(v), (int)n, p);
 	}
-	else if (PyUnicode_Check(v)) {
+	else if (PyUnicode_CheckExact(v)) {
 	        PyObject *utf8;
 		utf8 = PyUnicode_AsUTF8String(v);
 		if (utf8 == NULL) {
@@ -259,7 +259,7 @@
 		w_string(PyString_AS_STRING(utf8), (int)n, p);
 		Py_DECREF(utf8);
 	}
-	else if (PyTuple_Check(v)) {
+	else if (PyTuple_CheckExact(v)) {
 		w_byte(TYPE_TUPLE, p);
 		n = PyTuple_Size(v);
 		w_long((long)n, p);
@@ -267,7 +267,7 @@
 			w_object(PyTuple_GET_ITEM(v, i), p);
 		}
 	}
-	else if (PyList_Check(v)) {
+	else if (PyList_CheckExact(v)) {
 		w_byte(TYPE_LIST, p);
 		n = PyList_GET_SIZE(v);
 		w_long((long)n, p);
@@ -275,7 +275,7 @@
 			w_object(PyList_GET_ITEM(v, i), p);
 		}
 	}
-	else if (PyDict_Check(v)) {
+	else if (PyDict_CheckExact(v)) {
 		Py_ssize_t pos;
 		PyObject *key, *value;
 		w_byte(TYPE_DICT, p);
@@ -287,7 +287,7 @@
 		}
 		w_object((PyObject *)NULL, p);
 	}
-	else if (PyAnySet_Check(v)) {
+	else if (PyAnySet_CheckExact(v)) {
 		PyObject *value, *it;
 
 		if (PyObject_TypeCheck(v, &PySet_Type))