mirror of https://github.com/python/cpython
Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r64002 | travis.oliphant | 2008-06-07 00:33:21 +0200 (Sat, 07 Jun 2008) | 1 line Add long double check support to configure test. ........ r64003 | travis.oliphant | 2008-06-07 00:39:47 +0200 (Sat, 07 Jun 2008) | 1 line Remove locking part of new buffer protocol. ........ r64012 | facundo.batista | 2008-06-07 15:36:36 +0200 (Sat, 07 Jun 2008) | 4 lines Finished bug #2451. Fixed the retrying part to make it more robust. ........ r64036 | georg.brandl | 2008-06-08 10:54:40 +0200 (Sun, 08 Jun 2008) | 2 lines #3028: tokenize passes the physical line. ........ r64037 | georg.brandl | 2008-06-08 10:59:38 +0200 (Sun, 08 Jun 2008) | 2 lines Argh, I read it wrong. Reverted 64036 and added a clarifying remark. ........ r64047 | raymond.hettinger | 2008-06-09 03:28:30 +0200 (Mon, 09 Jun 2008) | 1 line Issue3065: Fixed pickling of named tuples. Added tests. ........ r64050 | raymond.hettinger | 2008-06-09 08:54:45 +0200 (Mon, 09 Jun 2008) | 1 line Issue #2138: Add math.factorial(). ........ r64051 | raymond.hettinger | 2008-06-09 10:33:37 +0200 (Mon, 09 Jun 2008) | 1 line Let set.union() and set.update() accept multiple inputs. ........ r64052 | raymond.hettinger | 2008-06-09 11:29:17 +0200 (Mon, 09 Jun 2008) | 1 line Address double-rounding scenarios by setting all variables to long doubles. ........ r64054 | raymond.hettinger | 2008-06-09 13:24:47 +0200 (Mon, 09 Jun 2008) | 1 line Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds. ........ r64055 | raymond.hettinger | 2008-06-09 15:07:27 +0200 (Mon, 09 Jun 2008) | 1 line Let set.intersection() and set.intersection_update() take multiple input arguments. ........ r64066 | robert.schuppenies | 2008-06-10 12:10:31 +0200 (Tue, 10 Jun 2008) | 2 lines Issue 3048: Fixed sys.getsizeof for unicode objects. ........ r64071 | thomas.heller | 2008-06-10 16:07:12 +0200 (Tue, 10 Jun 2008) | 3 lines NEWS entry for: Add an optional 'offset' parameter to byref, defaulting to zero. ........
This commit is contained in:
parent
e932c5c813
commit
c28e1fa71f
|
@ -519,6 +519,9 @@ Example:
|
|||
if kwds:
|
||||
raise ValueError('Got unexpected field names: %r' % kwds.keys())
|
||||
return result
|
||||
<BLANKLINE>
|
||||
def __getnewargs__(self):
|
||||
return tuple(self)
|
||||
<BLANKLINE>
|
||||
x = property(itemgetter(0))
|
||||
y = property(itemgetter(1))
|
||||
|
|
|
@ -41,6 +41,10 @@ Number-theoretic and representation functions:
|
|||
|
||||
Return the absolute value of *x*.
|
||||
|
||||
.. function:: factorial(x)
|
||||
|
||||
Return *x* factorial. Raises :exc:`ValueError` if *x* is not intergral or
|
||||
is negative.
|
||||
|
||||
.. function:: floor(x)
|
||||
|
||||
|
|
|
@ -1501,16 +1501,22 @@ The constructors for both classes work the same:
|
|||
Test whether the set is a true superset of *other*, that is, ``set >=
|
||||
other and set != other``.
|
||||
|
||||
.. method:: union(other)
|
||||
set | other
|
||||
.. method:: union(other, ...)
|
||||
set | other | ...
|
||||
|
||||
Return a new set with elements from both sets.
|
||||
|
||||
.. method:: intersection(other)
|
||||
set & other
|
||||
.. versionchanged:: 2.6
|
||||
Accepts multiple input iterables.
|
||||
|
||||
.. method:: intersection(other, ...)
|
||||
set & other & ...
|
||||
|
||||
Return a new set with elements common to both sets.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
Accepts multiple input iterables.
|
||||
|
||||
.. method:: difference(other)
|
||||
set - other
|
||||
|
||||
|
@ -1562,16 +1568,22 @@ The constructors for both classes work the same:
|
|||
The following table lists operations available for :class:`set` that do not
|
||||
apply to immutable instances of :class:`frozenset`:
|
||||
|
||||
.. method:: update(other)
|
||||
set |= other
|
||||
.. method:: update(other, ...)
|
||||
set |= other | ...
|
||||
|
||||
Update the set, adding elements from *other*.
|
||||
|
||||
.. method:: intersection_update(other)
|
||||
set &= other
|
||||
.. versionchanged:: 2.6
|
||||
Accepts multiple input iterables.
|
||||
|
||||
.. method:: intersection_update(other, ...)
|
||||
set &= other & ...
|
||||
|
||||
Update the set, keeping only elements found in it and *other*.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
Accepts multiple input iterables.
|
||||
|
||||
.. method:: difference_update(other)
|
||||
set -= other
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
:mod:`tokenize` --- Tokenizer for Python source
|
||||
===============================================
|
||||
|
||||
|
@ -15,7 +14,6 @@ colorizers for on-screen displays.
|
|||
|
||||
The primary entry point is a :term:`generator`:
|
||||
|
||||
|
||||
.. function:: tokenize(readline)
|
||||
|
||||
The :func:`tokenize` generator requires one argument, *readline*, which
|
||||
|
@ -28,11 +26,11 @@ The primary entry point is a :term:`generator`:
|
|||
token string; a 2-tuple ``(srow, scol)`` of ints specifying the row and
|
||||
column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of
|
||||
ints specifying the row and column where the token ends in the source; and
|
||||
the line on which the token was found. The line passed is the *logical*
|
||||
line; continuation lines are included.
|
||||
the line on which the token was found. The line passed (the last tuple item)
|
||||
is the *logical* line; continuation lines are included.
|
||||
|
||||
tokenize determines the source encoding of the file by looking for a utf-8
|
||||
bom or encoding cookie, according to :pep:`263`.
|
||||
:func:`tokenize` determines the source encoding of the file by looking for a
|
||||
UTF-8 BOM or encoding cookie, according to :pep:`263`.
|
||||
|
||||
|
||||
All constants from the :mod:`token` module are also exported from
|
||||
|
|
|
@ -87,7 +87,9 @@ def namedtuple(typename, field_names, verbose=False):
|
|||
result = self._make(map(kwds.pop, %(field_names)r, self))
|
||||
if kwds:
|
||||
raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
|
||||
return result \n\n''' % locals()
|
||||
return result \n
|
||||
def __getnewargs__(self):
|
||||
return tuple(self) \n\n''' % locals()
|
||||
for i, name in enumerate(field_names):
|
||||
template += ' %s = property(itemgetter(%d))\n' % (name, i)
|
||||
if verbose:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import unittest, doctest
|
||||
from test import support
|
||||
from collections import namedtuple
|
||||
import pickle, copy
|
||||
from collections import Hashable, Iterable, Iterator
|
||||
from collections import Sized, Container, Callable
|
||||
from collections import Set, MutableSet
|
||||
|
@ -10,6 +11,7 @@ from collections import Mapping, MutableMapping
|
|||
from collections import Sequence, MutableSequence
|
||||
from collections import ByteString
|
||||
|
||||
TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
|
||||
|
||||
class TestNamedTuple(unittest.TestCase):
|
||||
|
||||
|
@ -111,7 +113,7 @@ class TestNamedTuple(unittest.TestCase):
|
|||
self.assertEqual(Dot(1)._replace(d=999), (999,))
|
||||
self.assertEqual(Dot(1)._fields, ('d',))
|
||||
|
||||
# n = 10000
|
||||
# n = 5000
|
||||
n = 254 # SyntaxError: more than 255 arguments:
|
||||
import string, random
|
||||
names = list(set(''.join([random.choice(string.ascii_letters)
|
||||
|
@ -134,6 +136,23 @@ class TestNamedTuple(unittest.TestCase):
|
|||
self.assertEqual(b2, tuple(b2_expected))
|
||||
self.assertEqual(b._fields, tuple(names))
|
||||
|
||||
def test_pickle(self):
|
||||
p = TestNT(x=10, y=20, z=30)
|
||||
for module in (pickle,):
|
||||
loads = getattr(module, 'loads')
|
||||
dumps = getattr(module, 'dumps')
|
||||
for protocol in -1, 0, 1, 2:
|
||||
q = loads(dumps(p, protocol))
|
||||
self.assertEqual(p, q)
|
||||
self.assertEqual(p._fields, q._fields)
|
||||
|
||||
def test_copy(self):
|
||||
p = TestNT(x=10, y=20, z=30)
|
||||
for copier in copy.copy, copy.deepcopy:
|
||||
q = copier(p)
|
||||
self.assertEqual(p, q)
|
||||
self.assertEqual(p._fields, q._fields)
|
||||
|
||||
class TestOneTrickPonyABCs(unittest.TestCase):
|
||||
|
||||
def test_Hashable(self):
|
||||
|
|
|
@ -6,6 +6,7 @@ import unittest
|
|||
import math
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
|
||||
eps = 1E-05
|
||||
NAN = float('nan')
|
||||
|
@ -274,6 +275,20 @@ class MathTests(unittest.TestCase):
|
|||
self.ftest('fabs(0)', math.fabs(0), 0)
|
||||
self.ftest('fabs(1)', math.fabs(1), 1)
|
||||
|
||||
def testFactorial(self):
|
||||
def fact(n):
|
||||
result = 1
|
||||
for i in range(1, int(n)+1):
|
||||
result *= i
|
||||
return result
|
||||
values = list(range(10)) + [50, 100, 500]
|
||||
random.shuffle(values)
|
||||
for x in range(10):
|
||||
for cast in (int, float):
|
||||
self.assertEqual(math.factorial(cast(x)), fact(x), (x, fact(x), math.factorial(x)))
|
||||
self.assertRaises(ValueError, math.factorial, -1)
|
||||
self.assertRaises(ValueError, math.factorial, math.pi)
|
||||
|
||||
def testFloor(self):
|
||||
self.assertRaises(TypeError, math.floor)
|
||||
self.assertEquals(int, type(math.floor(0.5)))
|
||||
|
|
|
@ -79,6 +79,7 @@ class TestJointOps(unittest.TestCase):
|
|||
self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
|
||||
self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
|
||||
self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
|
||||
self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
|
||||
|
||||
def test_or(self):
|
||||
i = self.s.union(self.otherword)
|
||||
|
@ -103,6 +104,7 @@ class TestJointOps(unittest.TestCase):
|
|||
self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
|
||||
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('cbcf'), C('bag')), set('b'))
|
||||
|
||||
def test_isdisjoint(self):
|
||||
def f(s1, s2):
|
||||
|
@ -410,6 +412,12 @@ class TestSet(TestJointOps):
|
|||
s = self.thetype('abcba')
|
||||
self.assertEqual(s.update(C(p)), None)
|
||||
self.assertEqual(s, set(q))
|
||||
for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
|
||||
q = 'ahi'
|
||||
for C in set, frozenset, dict.fromkeys, str, list, tuple:
|
||||
s = self.thetype('abcba')
|
||||
self.assertEqual(s.update(C(p), C(q)), None)
|
||||
self.assertEqual(s, set(s) | set(p) | set(q))
|
||||
|
||||
def test_ior(self):
|
||||
self.s |= set(self.otherword)
|
||||
|
@ -431,6 +439,11 @@ class TestSet(TestJointOps):
|
|||
s = self.thetype('abcba')
|
||||
self.assertEqual(s.intersection_update(C(p)), None)
|
||||
self.assertEqual(s, set(q))
|
||||
ss = 'abcba'
|
||||
s = self.thetype(ss)
|
||||
t = 'cbc'
|
||||
self.assertEqual(s.intersection_update(C(p), C(t)), None)
|
||||
self.assertEqual(s, set('abcba')&set(p)&set(t))
|
||||
|
||||
def test_iand(self):
|
||||
self.s &= set(self.otherword)
|
||||
|
|
|
@ -386,11 +386,14 @@ class SizeofTest(unittest.TestCase):
|
|||
self.file.close()
|
||||
test.support.unlink(test.support.TESTFN)
|
||||
|
||||
def check_sizeof(self, o, size):
|
||||
def check_sizeof(self, o, size, size2=None):
|
||||
"""Check size of o. Possible are size and optionally size2)."""
|
||||
result = sys.getsizeof(o)
|
||||
msg = 'wrong size for %s: got %d, expected %d' \
|
||||
% (type(o), result, size)
|
||||
self.assertEqual(result, size, msg)
|
||||
msg = 'wrong size for %s: got %d, expected ' % (type(o), result)
|
||||
if (size2 != None) and (result != size):
|
||||
self.assertEqual(result, size2, msg + str(size2))
|
||||
else:
|
||||
self.assertEqual(result, size, msg + str(size))
|
||||
|
||||
def align(self, value):
|
||||
mod = value % self.p
|
||||
|
@ -486,6 +489,24 @@ class SizeofTest(unittest.TestCase):
|
|||
# list
|
||||
self.check_sizeof([], h + l + p + l)
|
||||
self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
|
||||
# unicode
|
||||
import math
|
||||
usize = math.log(sys.maxunicode + 1, 2) / 8
|
||||
samples = ['', '1'*100]
|
||||
# we need to test for both sizes, because we don't know if the string
|
||||
# has been cached
|
||||
for s in samples:
|
||||
basicsize = h + l + p + l + l + p + usize * (len(s) + 1)
|
||||
defenc = bytes(s, 'ascii')
|
||||
self.check_sizeof(s, basicsize,
|
||||
size2=basicsize + sys.getsizeof(defenc))
|
||||
# trigger caching encoded version as bytes object
|
||||
try:
|
||||
getattr(sys, s)
|
||||
except AttributeError:
|
||||
pass
|
||||
finally:
|
||||
self.check_sizeof(s, basicsize + sys.getsizeof(defenc))
|
||||
|
||||
h += l
|
||||
# long
|
||||
|
@ -495,9 +516,6 @@ class SizeofTest(unittest.TestCase):
|
|||
self.check_sizeof(32768, h + self.align(2) + 2)
|
||||
self.check_sizeof(32768*32768-1, h + self.align(2) + 2)
|
||||
self.check_sizeof(32768*32768, h + self.align(2) + 4)
|
||||
# XXX add Unicode support
|
||||
# self.check_sizeof('', h + l + self.align(i + 1))
|
||||
# self.check_sizeof('abc', h + l + self.align(i + 1) + 3)
|
||||
|
||||
|
||||
def test_main():
|
||||
|
|
|
@ -11,19 +11,25 @@ import os
|
|||
import mimetools
|
||||
|
||||
|
||||
def _urlopen_with_retry(host, *args, **kwargs):
|
||||
# Connecting to remote hosts is flaky. Make it more robust
|
||||
# by retrying the connection several times.
|
||||
def _retry_thrice(func, exc, *args, **kwargs):
|
||||
for i in range(3):
|
||||
try:
|
||||
return urllib2.urlopen(host, *args, **kwargs)
|
||||
except urllib2.URLError as e:
|
||||
return func(*args, **kwargs)
|
||||
except exc as e:
|
||||
last_exc = e
|
||||
continue
|
||||
except:
|
||||
raise
|
||||
raise last_exc
|
||||
|
||||
def _wrap_with_retry_thrice(func, exc):
|
||||
def wrapped(*args, **kwargs):
|
||||
return _retry_thrice(func, exc, *args, **kwargs)
|
||||
return wrapped
|
||||
|
||||
# Connecting to remote hosts is flaky. Make it more robust by retrying
|
||||
# the connection several times.
|
||||
_urlopen_with_retry = _wrap_with_retry_thrice(urllib2.urlopen, urllib2.URLError)
|
||||
|
||||
|
||||
class AuthTests(unittest.TestCase):
|
||||
|
@ -114,7 +120,7 @@ class OtherNetworkTests(unittest.TestCase):
|
|||
'file:'+sanepathname2url(os.path.abspath(TESTFN)),
|
||||
('file:///nonsensename/etc/passwd', None, urllib2.URLError),
|
||||
]
|
||||
self._test_urls(urls, self._extra_handlers(), urllib2.urlopen)
|
||||
self._test_urls(urls, self._extra_handlers(), retry=True)
|
||||
finally:
|
||||
os.remove(TESTFN)
|
||||
|
||||
|
@ -146,13 +152,15 @@ class OtherNetworkTests(unittest.TestCase):
|
|||
|
||||
## self._test_urls(urls, self._extra_handlers()+[bauth, dauth])
|
||||
|
||||
def _test_urls(self, urls, handlers, urlopen=_urlopen_with_retry):
|
||||
def _test_urls(self, urls, handlers, retry=True):
|
||||
import socket
|
||||
import time
|
||||
import logging
|
||||
debug = logging.getLogger("test_urllib2").debug
|
||||
|
||||
urllib2.install_opener(urllib2.build_opener(*handlers))
|
||||
urlopen = urllib2.build_opener(*handlers).open
|
||||
if retry:
|
||||
urlopen = _wrap_with_retry_thrice(urlopen, urllib2.URLError)
|
||||
|
||||
for url in urls:
|
||||
if isinstance(url, tuple):
|
||||
|
|
|
@ -567,6 +567,54 @@ PyDoc_STRVAR(math_sum_doc,
|
|||
Return an accurate floating point sum of values in the iterable.\n\
|
||||
Assumes IEEE-754 floating point arithmetic.");
|
||||
|
||||
static PyObject *
|
||||
math_factorial(PyObject *self, PyObject *arg)
|
||||
{
|
||||
long i, x;
|
||||
PyObject *result, *iobj, *newresult;
|
||||
|
||||
if (PyFloat_Check(arg)) {
|
||||
double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
|
||||
if (dx != floor(dx)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"factorial() only accepts integral values");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
x = PyLong_AsLong(arg);
|
||||
if (x == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
if (x < 0) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"factorial() not defined for negative values");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = (PyObject *)PyLong_FromLong(1);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
for (i=1 ; i<=x ; i++) {
|
||||
iobj = (PyObject *)PyLong_FromLong(i);
|
||||
if (iobj == NULL)
|
||||
goto error;
|
||||
newresult = PyNumber_Multiply(result, iobj);
|
||||
Py_DECREF(iobj);
|
||||
if (newresult == NULL)
|
||||
goto error;
|
||||
Py_DECREF(result);
|
||||
result = newresult;
|
||||
}
|
||||
return result;
|
||||
|
||||
error:
|
||||
Py_DECREF(result);
|
||||
Py_XDECREF(iobj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_factorial_doc, "Return n!");
|
||||
|
||||
static PyObject *
|
||||
math_trunc(PyObject *self, PyObject *number)
|
||||
{
|
||||
|
@ -1022,6 +1070,7 @@ static PyMethodDef math_methods[] = {
|
|||
{"degrees", math_degrees, METH_O, math_degrees_doc},
|
||||
{"exp", math_exp, METH_O, math_exp_doc},
|
||||
{"fabs", math_fabs, METH_O, math_fabs_doc},
|
||||
{"factorial", math_factorial, METH_O, math_factorial_doc},
|
||||
{"floor", math_floor, METH_O, math_floor_doc},
|
||||
{"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
|
||||
{"frexp", math_frexp, METH_O, math_frexp_doc},
|
||||
|
|
|
@ -959,15 +959,20 @@ set_update_internal(PySetObject *so, PyObject *other)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
set_update(PySetObject *so, PyObject *other)
|
||||
set_update(PySetObject *so, PyObject *args)
|
||||
{
|
||||
if (set_update_internal(so, other) == -1)
|
||||
return NULL;
|
||||
Py_ssize_t i;
|
||||
|
||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
||||
PyObject *other = PyTuple_GET_ITEM(args, i);
|
||||
if (set_update_internal(so, other) == -1)
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(update_doc,
|
||||
"Update a set with the union of itself and another.");
|
||||
"Update a set with the union of itself and others.");
|
||||
|
||||
static PyObject *
|
||||
make_new_set(PyTypeObject *type, PyObject *iterable)
|
||||
|
@ -1148,9 +1153,42 @@ set_clear(PySetObject *so)
|
|||
PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
|
||||
|
||||
static PyObject *
|
||||
set_union(PySetObject *so, PyObject *other)
|
||||
set_union(PySetObject *so, PyObject *args)
|
||||
{
|
||||
PySetObject *result;
|
||||
PyObject *other;
|
||||
Py_ssize_t i;
|
||||
|
||||
result = (PySetObject *)set_copy(so);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
||||
other = PyTuple_GET_ITEM(args, i);
|
||||
if ((PyObject *)so == other)
|
||||
return (PyObject *)result;
|
||||
if (set_update_internal(result, other) == -1) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(union_doc,
|
||||
"Return the union of sets as a new set.\n\
|
||||
\n\
|
||||
(i.e. all elements that are in either set.)");
|
||||
|
||||
static PyObject *
|
||||
set_or(PySetObject *so, PyObject *other)
|
||||
{
|
||||
PySetObject *result;
|
||||
|
||||
if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
result = (PySetObject *)set_copy(so);
|
||||
if (result == NULL)
|
||||
|
@ -1164,21 +1202,6 @@ set_union(PySetObject *so, PyObject *other)
|
|||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(union_doc,
|
||||
"Return the union of two sets as a new set.\n\
|
||||
\n\
|
||||
(i.e. all elements that are in either set.)");
|
||||
|
||||
static PyObject *
|
||||
set_or(PySetObject *so, PyObject *other)
|
||||
{
|
||||
if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
return set_union(so, other);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_ior(PySetObject *so, PyObject *other)
|
||||
{
|
||||
|
@ -1275,6 +1298,26 @@ set_intersection(PySetObject *so, PyObject *other)
|
|||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_intersection_multi(PySetObject *so, PyObject *args)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyObject *result = (PyObject *)so;
|
||||
|
||||
Py_INCREF(so);
|
||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
||||
PyObject *other = PyTuple_GET_ITEM(args, i);
|
||||
PyObject *newresult = set_intersection((PySetObject *)result, other);
|
||||
if (newresult == NULL) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
result = newresult;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(intersection_doc,
|
||||
"Return the intersection of two sets as a new set.\n\
|
||||
\n\
|
||||
|
@ -1293,6 +1336,19 @@ set_intersection_update(PySetObject *so, PyObject *other)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_intersection_update_multi(PySetObject *so, PyObject *args)
|
||||
{
|
||||
PyObject *tmp;
|
||||
|
||||
tmp = set_intersection_multi(so, args);
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
set_swap_bodies(so, (PySetObject *)tmp);
|
||||
Py_DECREF(tmp);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(intersection_update_doc,
|
||||
"Update a set with the intersection of itself and another.");
|
||||
|
||||
|
@ -1911,9 +1967,9 @@ static PyMethodDef set_methods[] = {
|
|||
difference_doc},
|
||||
{"difference_update", (PyCFunction)set_difference_update, METH_O,
|
||||
difference_update_doc},
|
||||
{"intersection",(PyCFunction)set_intersection, METH_O,
|
||||
{"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
|
||||
intersection_doc},
|
||||
{"intersection_update",(PyCFunction)set_intersection_update, METH_O,
|
||||
{"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
|
||||
intersection_update_doc},
|
||||
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||
isdisjoint_doc},
|
||||
|
@ -1935,9 +1991,9 @@ static PyMethodDef set_methods[] = {
|
|||
{"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
|
||||
test_c_api_doc},
|
||||
#endif
|
||||
{"union", (PyCFunction)set_union, METH_O,
|
||||
{"union", (PyCFunction)set_union, METH_VARARGS,
|
||||
union_doc},
|
||||
{"update", (PyCFunction)set_update, METH_O,
|
||||
{"update", (PyCFunction)set_update, METH_VARARGS,
|
||||
update_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
@ -2036,7 +2092,7 @@ static PyMethodDef frozenset_methods[] = {
|
|||
copy_doc},
|
||||
{"difference", (PyCFunction)set_difference, METH_O,
|
||||
difference_doc},
|
||||
{"intersection",(PyCFunction)set_intersection, METH_O,
|
||||
{"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
|
||||
intersection_doc},
|
||||
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
|
||||
isdisjoint_doc},
|
||||
|
@ -2048,7 +2104,7 @@ static PyMethodDef frozenset_methods[] = {
|
|||
reduce_doc},
|
||||
{"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
|
||||
symmetric_difference_doc},
|
||||
{"union", (PyCFunction)set_union, METH_O,
|
||||
{"union", (PyCFunction)set_union, METH_VARARGS,
|
||||
union_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
|
|
@ -8300,6 +8300,28 @@ PyDoc_STRVAR(p_format__doc__,
|
|||
\n\
|
||||
");
|
||||
|
||||
static PyObject *
|
||||
unicode__sizeof__(PyUnicodeObject *v)
|
||||
{
|
||||
PyObject *res = NULL, *defsize = NULL;
|
||||
|
||||
res = PyLong_FromSsize_t(sizeof(PyUnicodeObject) +
|
||||
sizeof(Py_UNICODE) * (v->length + 1));
|
||||
if (v->defenc) {
|
||||
defsize = PyObject_CallMethod(v->defenc, "__sizeof__", NULL);
|
||||
if (defsize == NULL) {
|
||||
Py_DECREF(res);
|
||||
return NULL;
|
||||
}
|
||||
res = PyNumber_Add(res, defsize);
|
||||
Py_DECREF(defsize);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(sizeof__doc__,
|
||||
"S.__sizeof__() -> size of S in memory, in bytes");
|
||||
|
||||
static PyObject *
|
||||
unicode_getnewargs(PyUnicodeObject *v)
|
||||
{
|
||||
|
@ -8357,6 +8379,7 @@ static PyMethodDef unicode_methods[] = {
|
|||
{"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
|
||||
{"maketrans", (PyCFunction) unicode_maketrans,
|
||||
METH_VARARGS | METH_STATIC, maketrans__doc__},
|
||||
{"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
|
||||
#if 0
|
||||
{"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue