summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-11-10 23:39:45 (GMT)
committerGuido van Rossum <guido@python.org>2007-11-10 23:39:45 (GMT)
commit58da931da9f9e75d36c364895e95a8cf015fa159 (patch)
treeae47e868c67275c5c21d502334fa0cce803b63f4
parent06cfe95237bd92f0b2d1ef1eebc892ae74063809 (diff)
downloadcpython-58da931da9f9e75d36c364895e95a8cf015fa159.zip
cpython-58da931da9f9e75d36c364895e95a8cf015fa159.tar.gz
cpython-58da931da9f9e75d36c364895e95a8cf015fa159.tar.bz2
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. ........
-rw-r--r--Doc/library/marshal.rst6
-rw-r--r--Doc/library/stdtypes.rst7
-rw-r--r--Doc/tutorial/introduction.rst3
-rwxr-xr-xLib/test/regrtest.py7
-rw-r--r--Lib/test/test_descr.py65
-rw-r--r--Lib/test/test_dict.py4
-rw-r--r--Lib/test/test_marshal.py11
-rw-r--r--Lib/test/test_set.py49
-rw-r--r--Misc/developers.txt3
-rw-r--r--Modules/_collectionsmodule.c34
-rw-r--r--Objects/descrobject.c56
-rw-r--r--Objects/dictobject.c42
-rw-r--r--Objects/setobject.c71
-rw-r--r--Objects/stringobject.c1
-rw-r--r--Python/ceval.c11
-rw-r--r--Python/marshal.c18
16 files changed, 349 insertions, 39 deletions
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 @@ 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
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 @@ 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
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 @@ 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::
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 @@ 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()
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 @@ 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...")
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 @@ 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})
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 @@ 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,
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 @@ 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))
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 @@ 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.
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 @@ 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;
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 @@ 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 */
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 @@ 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;
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 @@ 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,
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 @@ 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) {
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 @@ 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)] */
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 @@ 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))