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:
Georg Brandl 2008-06-10 19:20:26 +00:00
parent e932c5c813
commit c28e1fa71f
13 changed files with 277 additions and 57 deletions

View 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))

View 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)

View 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

View 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

View 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:

View 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):

View 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)))

View 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)

View 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():

View 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):

View 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},

View 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)
{
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 */
};

View 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