mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
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. ........
This commit is contained in:
parent
06cfe95237
commit
58da931da9
16 changed files with 349 additions and 39 deletions
|
@ -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
|
themselves supported; and recursive lists and dictionaries should not be written
|
||||||
(they will cause infinite loops).
|
(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::
|
.. warning::
|
||||||
|
|
||||||
On machines where C's ``long int`` type has more than 32 bits (such as the
|
On machines where C's ``long int`` type has more than 32 bits (such as the
|
||||||
|
|
|
@ -1418,6 +1418,13 @@ operations:
|
||||||
|
|
||||||
Test *x* for non-membership in *s*.
|
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)
|
.. method:: set.issubset(other)
|
||||||
set <= other
|
set <= other
|
||||||
|
|
||||||
|
|
|
@ -507,8 +507,9 @@ list or clear it entirely::
|
||||||
|
|
||||||
The built-in function :func:`len` also applies to lists::
|
The built-in function :func:`len` also applies to lists::
|
||||||
|
|
||||||
|
>>> a = ['a', 'b', 'c', 'd']
|
||||||
>>> len(a)
|
>>> len(a)
|
||||||
8
|
4
|
||||||
|
|
||||||
It is possible to nest lists (create lists containing other lists), for
|
It is possible to nest lists (create lists containing other lists), for
|
||||||
example::
|
example::
|
||||||
|
|
|
@ -588,10 +588,9 @@ def runtest_inner(test, generate, verbose, quiet,
|
||||||
abstest = 'test.' + test
|
abstest = 'test.' + test
|
||||||
the_package = __import__(abstest, globals(), locals(), [])
|
the_package = __import__(abstest, globals(), locals(), [])
|
||||||
the_module = getattr(the_package, test)
|
the_module = getattr(the_package, test)
|
||||||
# Most tests run to completion simply as a side-effect of
|
# Old tests run to completion simply as a side-effect of
|
||||||
# being imported. For the benefit of tests that can't run
|
# being imported. For tests based on unittest or doctest,
|
||||||
# that way (like test_threaded_import), explicitly invoke
|
# explicitly invoke their test_main() function (if it exists).
|
||||||
# their test_main() function (if it exists).
|
|
||||||
indirect_test = getattr(the_module, "test_main", None)
|
indirect_test = getattr(the_module, "test_main", None)
|
||||||
if indirect_test is not None:
|
if indirect_test is not None:
|
||||||
indirect_test()
|
indirect_test()
|
||||||
|
|
|
@ -1984,6 +1984,71 @@ def properties():
|
||||||
p = property(_testcapi.test_with_docstring)
|
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():
|
def supers():
|
||||||
if verbose: print("Testing super...")
|
if verbose: print("Testing super...")
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,10 @@ class DictTest(unittest.TestCase):
|
||||||
|
|
||||||
self.assertRaises(Exc, baddict2.fromkeys, [1])
|
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):
|
def test_copy(self):
|
||||||
d = {1:1, 2:2, 3:3}
|
d = {1:1, 2:2, 3:3}
|
||||||
self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
|
self.assertEqual(d.copy(), {1:1, 2:2, 3:3})
|
||||||
|
|
|
@ -188,6 +188,17 @@ class BugsTestCase(unittest.TestCase):
|
||||||
last.append([0])
|
last.append([0])
|
||||||
self.assertRaises(ValueError, marshal.dumps, head)
|
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():
|
def test_main():
|
||||||
test_support.run_unittest(IntTestCase,
|
test_support.run_unittest(IntTestCase,
|
||||||
FloatTestCase,
|
FloatTestCase,
|
||||||
|
|
|
@ -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('ccb')), set('bc'))
|
||||||
self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
|
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):
|
def test_and(self):
|
||||||
i = self.s.intersection(self.otherword)
|
i = self.s.intersection(self.otherword)
|
||||||
self.assertEqual(self.s & set(self.otherword), i)
|
self.assertEqual(self.s & set(self.otherword), i)
|
||||||
|
@ -701,6 +715,18 @@ class TestBasicOps(unittest.TestCase):
|
||||||
result = empty_set & self.set
|
result = empty_set & self.set
|
||||||
self.assertEqual(result, empty_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):
|
def test_self_symmetric_difference(self):
|
||||||
result = self.set ^ self.set
|
result = self.set ^ self.set
|
||||||
self.assertEqual(result, empty_set)
|
self.assertEqual(result, empty_set)
|
||||||
|
@ -879,6 +905,22 @@ class TestBinaryOps(unittest.TestCase):
|
||||||
result = self.set & set([8])
|
result = self.set & set([8])
|
||||||
self.assertEqual(result, empty_set)
|
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):
|
def test_sym_difference_subset(self):
|
||||||
result = self.set ^ set((2, 4))
|
result = self.set ^ set((2, 4))
|
||||||
self.assertEqual(result, set([6]))
|
self.assertEqual(result, set([6]))
|
||||||
|
@ -1497,11 +1539,14 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
def test_inline_methods(self):
|
def test_inline_methods(self):
|
||||||
s = set('november')
|
s = set('november')
|
||||||
for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
|
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):
|
for g in (G, I, Ig, L, R):
|
||||||
expected = meth(data)
|
expected = meth(data)
|
||||||
actual = meth(G(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, X(s))
|
||||||
self.assertRaises(TypeError, meth, N(s))
|
self.assertRaises(TypeError, meth, N(s))
|
||||||
self.assertRaises(ZeroDivisionError, meth, E(s))
|
self.assertRaises(ZeroDivisionError, meth, E(s))
|
||||||
|
|
|
@ -17,6 +17,9 @@ the format to accommodate documentation needs as they arise.
|
||||||
Permissions History
|
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,
|
- Christian Heimes was given SVN access on 31 October 2007 by MvL,
|
||||||
for general contributions to Python.
|
for general contributions to Python.
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,10 @@ typedef struct BLOCK {
|
||||||
PyObject *data[BLOCKLEN];
|
PyObject *data[BLOCKLEN];
|
||||||
} block;
|
} block;
|
||||||
|
|
||||||
|
#define MAXFREEBLOCKS 10
|
||||||
|
static int numfreeblocks = 0;
|
||||||
|
static block *freeblocks[MAXFREEBLOCKS];
|
||||||
|
|
||||||
static block *
|
static block *
|
||||||
newblock(block *leftlink, block *rightlink, int len) {
|
newblock(block *leftlink, block *rightlink, int len) {
|
||||||
block *b;
|
block *b;
|
||||||
|
@ -66,16 +70,32 @@ newblock(block *leftlink, block *rightlink, int len) {
|
||||||
"cannot add more blocks to the deque");
|
"cannot add more blocks to the deque");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
b = PyMem_Malloc(sizeof(block));
|
if (numfreeblocks) {
|
||||||
if (b == NULL) {
|
numfreeblocks -= 1;
|
||||||
PyErr_NoMemory();
|
b = freeblocks[numfreeblocks];
|
||||||
return NULL;
|
} else {
|
||||||
|
b = PyMem_Malloc(sizeof(block));
|
||||||
|
if (b == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b->leftlink = leftlink;
|
b->leftlink = leftlink;
|
||||||
b->rightlink = rightlink;
|
b->rightlink = rightlink;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freeblock(block *b)
|
||||||
|
{
|
||||||
|
if (numfreeblocks < MAXFREEBLOCKS) {
|
||||||
|
freeblocks[numfreeblocks] = b;
|
||||||
|
numfreeblocks++;
|
||||||
|
} else {
|
||||||
|
PyMem_Free(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
block *leftblock;
|
block *leftblock;
|
||||||
|
@ -161,7 +181,7 @@ deque_pop(dequeobject *deque, PyObject *unused)
|
||||||
} else {
|
} else {
|
||||||
prevblock = deque->rightblock->leftlink;
|
prevblock = deque->rightblock->leftlink;
|
||||||
assert(deque->leftblock != deque->rightblock);
|
assert(deque->leftblock != deque->rightblock);
|
||||||
PyMem_Free(deque->rightblock);
|
freeblock(deque->rightblock);
|
||||||
prevblock->rightlink = NULL;
|
prevblock->rightlink = NULL;
|
||||||
deque->rightblock = prevblock;
|
deque->rightblock = prevblock;
|
||||||
deque->rightindex = BLOCKLEN - 1;
|
deque->rightindex = BLOCKLEN - 1;
|
||||||
|
@ -198,7 +218,7 @@ deque_popleft(dequeobject *deque, PyObject *unused)
|
||||||
} else {
|
} else {
|
||||||
assert(deque->leftblock != deque->rightblock);
|
assert(deque->leftblock != deque->rightblock);
|
||||||
prevblock = deque->leftblock->rightlink;
|
prevblock = deque->leftblock->rightlink;
|
||||||
PyMem_Free(deque->leftblock);
|
freeblock(deque->leftblock);
|
||||||
assert(prevblock != NULL);
|
assert(prevblock != NULL);
|
||||||
prevblock->leftlink = NULL;
|
prevblock->leftlink = NULL;
|
||||||
deque->leftblock = prevblock;
|
deque->leftblock = prevblock;
|
||||||
|
@ -559,7 +579,7 @@ deque_dealloc(dequeobject *deque)
|
||||||
if (deque->leftblock != NULL) {
|
if (deque->leftblock != NULL) {
|
||||||
deque_clear(deque);
|
deque_clear(deque);
|
||||||
assert(deque->leftblock != NULL);
|
assert(deque->leftblock != NULL);
|
||||||
PyMem_Free(deque->leftblock);
|
freeblock(deque->leftblock);
|
||||||
}
|
}
|
||||||
deque->leftblock = NULL;
|
deque->leftblock = NULL;
|
||||||
deque->rightblock = NULL;
|
deque->rightblock = NULL;
|
||||||
|
|
|
@ -1099,6 +1099,60 @@ static PyMemberDef property_members[] = {
|
||||||
{0}
|
{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
|
static void
|
||||||
property_dealloc(PyObject *self)
|
property_dealloc(PyObject *self)
|
||||||
|
@ -1251,7 +1305,7 @@ PyTypeObject PyProperty_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
0, /* tp_iter */
|
0, /* tp_iter */
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
property_methods, /* tp_methods */
|
||||||
property_members, /* tp_members */
|
property_members, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
|
|
|
@ -1175,6 +1175,25 @@ dict_fromkeys(PyObject *cls, PyObject *args)
|
||||||
if (d == NULL)
|
if (d == NULL)
|
||||||
return 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)) {
|
if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) {
|
||||||
PyDictObject *mp = (PyDictObject *)d;
|
PyDictObject *mp = (PyDictObject *)d;
|
||||||
Py_ssize_t pos = 0;
|
Py_ssize_t pos = 0;
|
||||||
|
@ -1199,19 +1218,24 @@ dict_fromkeys(PyObject *cls, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
if (PyDict_CheckExact(d)) {
|
||||||
key = PyIter_Next(it);
|
while ((key = PyIter_Next(it)) != NULL) {
|
||||||
if (key == NULL) {
|
status = PyDict_SetItem(d, key, value);
|
||||||
if (PyErr_Occurred())
|
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;
|
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);
|
Py_DECREF(it);
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
|
|
|
@ -1314,6 +1314,73 @@ set_iand(PySetObject *so, PyObject *other)
|
||||||
return (PyObject *)so;
|
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
|
static int
|
||||||
set_difference_update_internal(PySetObject *so, PyObject *other)
|
set_difference_update_internal(PySetObject *so, PyObject *other)
|
||||||
{
|
{
|
||||||
|
@ -1839,6 +1906,8 @@ static PyMethodDef set_methods[] = {
|
||||||
intersection_doc},
|
intersection_doc},
|
||||||
{"intersection_update",(PyCFunction)set_intersection_update, METH_O,
|
{"intersection_update",(PyCFunction)set_intersection_update, METH_O,
|
||||||
intersection_update_doc},
|
intersection_update_doc},
|
||||||
|
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||||
|
isdisjoint_doc},
|
||||||
{"issubset", (PyCFunction)set_issubset, METH_O,
|
{"issubset", (PyCFunction)set_issubset, METH_O,
|
||||||
issubset_doc},
|
issubset_doc},
|
||||||
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
||||||
|
@ -1960,6 +2029,8 @@ static PyMethodDef frozenset_methods[] = {
|
||||||
difference_doc},
|
difference_doc},
|
||||||
{"intersection",(PyCFunction)set_intersection, METH_O,
|
{"intersection",(PyCFunction)set_intersection, METH_O,
|
||||||
intersection_doc},
|
intersection_doc},
|
||||||
|
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||||
|
isdisjoint_doc},
|
||||||
{"issubset", (PyCFunction)set_issubset, METH_O,
|
{"issubset", (PyCFunction)set_issubset, METH_O,
|
||||||
issubset_doc},
|
issubset_doc},
|
||||||
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
{"issuperset", (PyCFunction)set_issuperset, METH_O,
|
||||||
|
|
|
@ -611,6 +611,7 @@ PyString_Repr(PyObject *obj, int smartquotes)
|
||||||
if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) {
|
if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
"bytes object is too large to make repr");
|
"bytes object is too large to make repr");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
v = PyUnicode_FromUnicode(NULL, newsize);
|
v = PyUnicode_FromUnicode(NULL, newsize);
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
|
|
|
@ -2011,7 +2011,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
|
PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
|
||||||
case JUMP_ABSOLUTE:
|
case JUMP_ABSOLUTE:
|
||||||
JUMPTO(oparg);
|
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;
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
case GET_ITER:
|
case GET_ITER:
|
||||||
/* before: [obj]; after [getiter(obj)] */
|
/* before: [obj]; after [getiter(obj)] */
|
||||||
|
|
|
@ -147,7 +147,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
else if (v == Py_True) {
|
else if (v == Py_True) {
|
||||||
w_byte(TYPE_TRUE, p);
|
w_byte(TYPE_TRUE, p);
|
||||||
}
|
}
|
||||||
else if (PyLong_Check(v)) {
|
else if (PyLong_CheckExact(v)) {
|
||||||
long x = PyLong_AsLong(v);
|
long x = PyLong_AsLong(v);
|
||||||
if ((x == -1) && PyErr_Occurred()) {
|
if ((x == -1) && PyErr_Occurred()) {
|
||||||
PyLongObject *ob = (PyLongObject *)v;
|
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) {
|
if (p->version > 1) {
|
||||||
unsigned char buf[8];
|
unsigned char buf[8];
|
||||||
if (_PyFloat_Pack8(PyFloat_AsDouble(v),
|
if (_PyFloat_Pack8(PyFloat_AsDouble(v),
|
||||||
|
@ -196,7 +196,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef WITHOUT_COMPLEX
|
#ifndef WITHOUT_COMPLEX
|
||||||
else if (PyComplex_Check(v)) {
|
else if (PyComplex_CheckExact(v)) {
|
||||||
if (p->version > 1) {
|
if (p->version > 1) {
|
||||||
unsigned char buf[8];
|
unsigned char buf[8];
|
||||||
if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
|
if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
|
||||||
|
@ -228,7 +228,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (PyString_Check(v)) {
|
else if (PyString_CheckExact(v)) {
|
||||||
w_byte(TYPE_STRING, p);
|
w_byte(TYPE_STRING, p);
|
||||||
n = PyString_GET_SIZE(v);
|
n = PyString_GET_SIZE(v);
|
||||||
if (n > INT_MAX) {
|
if (n > INT_MAX) {
|
||||||
|
@ -240,7 +240,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
w_long((long)n, p);
|
w_long((long)n, p);
|
||||||
w_string(PyString_AS_STRING(v), (int)n, p);
|
w_string(PyString_AS_STRING(v), (int)n, p);
|
||||||
}
|
}
|
||||||
else if (PyUnicode_Check(v)) {
|
else if (PyUnicode_CheckExact(v)) {
|
||||||
PyObject *utf8;
|
PyObject *utf8;
|
||||||
utf8 = PyUnicode_AsUTF8String(v);
|
utf8 = PyUnicode_AsUTF8String(v);
|
||||||
if (utf8 == NULL) {
|
if (utf8 == NULL) {
|
||||||
|
@ -259,7 +259,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
w_string(PyString_AS_STRING(utf8), (int)n, p);
|
w_string(PyString_AS_STRING(utf8), (int)n, p);
|
||||||
Py_DECREF(utf8);
|
Py_DECREF(utf8);
|
||||||
}
|
}
|
||||||
else if (PyTuple_Check(v)) {
|
else if (PyTuple_CheckExact(v)) {
|
||||||
w_byte(TYPE_TUPLE, p);
|
w_byte(TYPE_TUPLE, p);
|
||||||
n = PyTuple_Size(v);
|
n = PyTuple_Size(v);
|
||||||
w_long((long)n, p);
|
w_long((long)n, p);
|
||||||
|
@ -267,7 +267,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
w_object(PyTuple_GET_ITEM(v, i), p);
|
w_object(PyTuple_GET_ITEM(v, i), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PyList_Check(v)) {
|
else if (PyList_CheckExact(v)) {
|
||||||
w_byte(TYPE_LIST, p);
|
w_byte(TYPE_LIST, p);
|
||||||
n = PyList_GET_SIZE(v);
|
n = PyList_GET_SIZE(v);
|
||||||
w_long((long)n, p);
|
w_long((long)n, p);
|
||||||
|
@ -275,7 +275,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
w_object(PyList_GET_ITEM(v, i), p);
|
w_object(PyList_GET_ITEM(v, i), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (PyDict_Check(v)) {
|
else if (PyDict_CheckExact(v)) {
|
||||||
Py_ssize_t pos;
|
Py_ssize_t pos;
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
w_byte(TYPE_DICT, p);
|
w_byte(TYPE_DICT, p);
|
||||||
|
@ -287,7 +287,7 @@ w_object(PyObject *v, WFILE *p)
|
||||||
}
|
}
|
||||||
w_object((PyObject *)NULL, p);
|
w_object((PyObject *)NULL, p);
|
||||||
}
|
}
|
||||||
else if (PyAnySet_Check(v)) {
|
else if (PyAnySet_CheckExact(v)) {
|
||||||
PyObject *value, *it;
|
PyObject *value, *it;
|
||||||
|
|
||||||
if (PyObject_TypeCheck(v, &PySet_Type))
|
if (PyObject_TypeCheck(v, &PySet_Type))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue