]> granicus.if.org Git - python/commitdiff
Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066...
authorGeorg Brandl <georg@python.org>
Tue, 10 Jun 2008 19:20:26 +0000 (19:20 +0000)
committerGeorg Brandl <georg@python.org>
Tue, 10 Jun 2008 19:20:26 +0000 (19:20 +0000)
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.
........

13 files changed:
Doc/library/collections.rst
Doc/library/math.rst
Doc/library/stdtypes.rst
Doc/library/tokenize.rst
Lib/collections.py
Lib/test/test_collections.py
Lib/test/test_math.py
Lib/test/test_set.py
Lib/test/test_sys.py
Lib/test/test_urllib2net.py
Modules/mathmodule.c
Objects/setobject.c
Objects/unicodeobject.c

index 5035ac907a527c5627f114f96ab9a4eae22789d7..3203ca584a19e9aadcc37e1844064d126028b4f0 100644 (file)
@@ -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))
index 0868e8eb10cf9256c182c1f662c7b5ee7cb481e4..aba6b0e52978d959f3c7b9850f5220bc97fa53a1 100644 (file)
@@ -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)
 
index 09549ada39aafe8e0dc4e588c44ab0157265b148..27c3fb4160b337960e756889cbc579f0af5844aa 100644 (file)
@@ -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
 
index bbe73d00e9a5582997161072e5397182a92fcb24..b2caded0a7a6093f5ac07fc49f41843d95187c16 100644 (file)
@@ -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
index 73fc150e9abfd90b7a08bae251825c6b5188af7d..6d439e526909c53bb45685565f9f4e7ca5304ee4 100644 (file)
@@ -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:
index 4ed0e241655d67e3ded7e90b060abbe07a27afdf..9289afe07269bc19118a2963b75e473fe265fd70 100644 (file)
@@ -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):
index f4c27bb38959a766639bcc5f2b89eb082742a282..1eafebad22276d311a5eda06cbbe80e415bbc4dc 100644 (file)
@@ -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)))
index d05df3f24dec382fa0ea3c58c1d1cf6c3694d764..ed2db18e5a4695346a43ea6d016f475757c68654 100644 (file)
@@ -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)
index e9570e902650c89cc440df5811be7ab0ed8fd6bb..39ed0ad8aff16cac48bcc6d2bd4a9351c2017724 100644 (file)
@@ -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():
index 752406c446b0e7703f91fcae7764df497bb49290..1c4af18d973e7d0d5f2885a45df6b3f78bbe496c 100644 (file)
@@ -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):
index 16c829ac25ce5ce3e6085a47410deb2218e1e63b..f759adab5b52ce6b5464398653ba8180c35cd5e7 100644 (file)
@@ -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},
index f760b6a94b37a5bbef1c590674c48e1bdb4013b5..4456ef49d5083842bcb872461112aecec6e9fa2f 100644 (file)
@@ -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,35 +1153,53 @@ 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;
-       if ((PyObject *)so == other)
-               return (PyObject *)result;
-       if (set_update_internal(result, other) == -1) {
-               Py_DECREF(result);
-               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 two sets as a new set.\n\
+ "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;
        }
-       return set_union(so, other);
+
+       result = (PySetObject *)set_copy(so);
+       if (result == NULL)
+               return NULL;
+       if ((PyObject *)so == other)
+               return (PyObject *)result;
+       if (set_update_internal(result, other) == -1) {
+               Py_DECREF(result);
+               return NULL;
+       }
+       return (PyObject *)result;
 }
 
 static PyObject *
@@ -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 */
 };
index 5cd9eb9f48d5eabdcee4443fae3473bb49410c8e..db907d6a0e02b89b66e108cfd28f674eac370220 100644 (file)
@@ -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