]> granicus.if.org Git - python/commitdiff
Merged revisions 58886-58929 via svnmerge from
authorGuido van Rossum <guido@python.org>
Sat, 10 Nov 2007 23:39:45 +0000 (23:39 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 10 Nov 2007 23:39:45 +0000 (23:39 +0000)
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.
........

16 files changed:
Doc/library/marshal.rst
Doc/library/stdtypes.rst
Doc/tutorial/introduction.rst
Lib/test/regrtest.py
Lib/test/test_descr.py
Lib/test/test_dict.py
Lib/test/test_marshal.py
Lib/test/test_set.py
Misc/developers.txt
Modules/_collectionsmodule.c
Objects/descrobject.c
Objects/dictobject.c
Objects/setobject.c
Objects/stringobject.c
Python/ceval.c
Python/marshal.c

index 0cf69b4ff9f3bcce5981384025cb712fe82ca347..bc431843d97488dc8d0bc54b06717c30a2c6e96a 100644 (file)
@@ -44,12 +44,6 @@ and dictionaries are only supported as long as the values contained therein are
 themselves supported; and recursive lists and dictionaries should not be written
 (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
index 9073bca763f06aa2e74f399db6c758f374a6e364..d6a853bc69adeaf2cd03d3a8df8b49038fc208b5 100644 (file)
@@ -1418,6 +1418,13 @@ operations:
 
    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
 
index 30adac97489e97df9e195224f50e82559004662c..4226ffdde819a2b6e9aaffd16d38bcc4e7bdbfcc 100644 (file)
@@ -507,8 +507,9 @@ list or clear it entirely::
 
 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::
index cd92511af5952761cd05fa379b0d8de0f348af9a..3a24b223a7a8703f46102cf43b2df55ef6c0fc44 100755 (executable)
@@ -588,10 +588,9 @@ def runtest_inner(test, generate, verbose, quiet,
                 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()
index 961369f757cc23c7922aaa3ab41cbc9799fe4771..1ea93bb9ab7b4a3fca1a7a7e4ac239c0a4cdc064 100644 (file)
@@ -1984,6 +1984,71 @@ def properties():
             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...")
 
index 89c127a29de944185a6c70b14a5882773d18ee06..56ce722033aadcd6d151ccb1e557797a0ca1e20e 100644 (file)
@@ -236,6 +236,10 @@ class DictTest(unittest.TestCase):
 
         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})
index 1e3520f97a19d8349631e2a037e17da1c5c6a3ba..fb70cede0e565518716c321e9bc9e038b57a041e 100644 (file)
@@ -188,6 +188,17 @@ class BugsTestCase(unittest.TestCase):
         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,
index 86a563686713486c0bbae21a502f1cb6f4beab6f..ba5801d772835cf5bb4eb2c38619534bc1e2db3a 100644 (file)
@@ -102,6 +102,20 @@ class TestJointOps(unittest.TestCase):
             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 @@ class TestBasicOps(unittest.TestCase):
         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 @@ class TestBinaryOps(unittest.TestCase):
         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 @@ class TestVariousIteratorArgs(unittest.TestCase):
     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))
index 32c1c46579a3291935d19dc55e15296b4f24af03..7fdfb33ff902f0504f5042ef0f2568ed651785b5 100644 (file)
@@ -17,6 +17,9 @@ the format to accommodate documentation needs as they arise.
 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.
 
index a26b572e83f0398c4173da9642d258648bddf1af..85709a9c992ba7a81af5dd57599b89a550402870 100644 (file)
@@ -51,6 +51,10 @@ typedef struct BLOCK {
        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 @@ newblock(block *leftlink, block *rightlink, int len) {
                                "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 @@ deque_pop(dequeobject *deque, PyObject *unused)
                } 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 @@ deque_popleft(dequeobject *deque, PyObject *unused)
                } 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 @@ deque_dealloc(dequeobject *deque)
        if (deque->leftblock != NULL) {
                deque_clear(deque);
                assert(deque->leftblock != NULL);
-               PyMem_Free(deque->leftblock);
+               freeblock(deque->leftblock);
        }
        deque->leftblock = NULL;
        deque->rightblock = NULL;
index 30ba4618b9ac0d4211bf714d8baf715151cbcec3..a0fc2170a4d96689ffdeb6ed75c1bd1d16e197af 100644 (file)
@@ -1099,6 +1099,60 @@ static PyMemberDef property_members[] = {
        {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 @@ PyTypeObject PyProperty_Type = {
        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 */
index 423012581f6949c1f59c8a3d73518166b390f95b..7bff7d8153ecf7f0d5e1c83f27666b84305778c4 100644 (file)
@@ -1175,6 +1175,25 @@ dict_fromkeys(PyObject *cls, PyObject *args)
        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 @@ dict_fromkeys(PyObject *cls, PyObject *args)
                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;
+               }
+       } else {
+               while ((key = PyIter_Next(it)) != NULL) {
+                       status = PyObject_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;
        }
 
+       if (PyErr_Occurred())
+               goto Fail;
        Py_DECREF(it);
        return d;
 
index ba7d2c4763ac525e8dd9655b340f7b7ed572e391..f6ea441785b4147e3108ff7d43756c8b48cb7e53 100644 (file)
@@ -1314,6 +1314,73 @@ set_iand(PySetObject *so, PyObject *other)
        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 @@ static PyMethodDef set_methods[] = {
         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 @@ static PyMethodDef frozenset_methods[] = {
         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,
index 8761477eec63d38347c7598e60023a856a86a7ce..2e729ea8219ff281e5df8bd4440ad919f93261d8 100644 (file)
@@ -611,6 +611,7 @@ PyString_Repr(PyObject *obj, int smartquotes)
        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) {
index c0e0993cf505679c45776ce93e4ae1c1256b78c6..b42444da82db882821ee1e9c2cd946a25ed2ee6a 100644 (file)
@@ -2011,7 +2011,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                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)] */
index a40aecc90f3e46ed36298ad79be714fe0d8b8e50..3e106c21d4960c40c1d7b5e25ae5ee06450ab7a4 100644 (file)
@@ -147,7 +147,7 @@ w_object(PyObject *v, WFILE *p)
        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 @@ w_object(PyObject *v, WFILE *p)
                        }
                }
        }
-       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 @@ w_object(PyObject *v, WFILE *p)
                }
        }
 #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 @@ w_object(PyObject *v, WFILE *p)
                }
        }
 #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_object(PyObject *v, WFILE *p)
                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_object(PyObject *v, WFILE *p)
                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(PyObject *v, WFILE *p)
                        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(PyObject *v, WFILE *p)
                        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 *v, WFILE *p)
                }
                w_object((PyObject *)NULL, p);
        }
-       else if (PyAnySet_Check(v)) {
+       else if (PyAnySet_CheckExact(v)) {
                PyObject *value, *it;
 
                if (PyObject_TypeCheck(v, &PySet_Type))