summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-11-16 00:35:22 (GMT)
committerGuido van Rossum <guido@python.org>2007-11-16 00:35:22 (GMT)
commit3d392eb3273aefeca2741aee9f0e31e3b79b1043 (patch)
tree7766b1aad797ebe0f8ee5316e561b3f37a45d3ea /Lib
parent5b8b1555de033c0f1646bce5fd130567297da019 (diff)
downloadcpython-3d392eb3273aefeca2741aee9f0e31e3b79b1043.zip
cpython-3d392eb3273aefeca2741aee9f0e31e3b79b1043.tar.gz
cpython-3d392eb3273aefeca2741aee9f0e31e3b79b1043.tar.bz2
Merged revisions 58947-59004 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r58952 | christian.heimes | 2007-11-12 10:58:08 -0800 (Mon, 12 Nov 2007) | 6 lines readline module cleanup fixed indention to tabs use Py_RETURN_NONE macro added more error checks to on_completion_display_matches_hook open question: Does PyList_SetItem(l, i, o) steal a reference to o in the case of an error? ........ r58956 | guido.van.rossum | 2007-11-12 12:06:40 -0800 (Mon, 12 Nov 2007) | 2 lines Add the test from issue 1704621 (the issue itself is already fixed here). ........ r58963 | amaury.forgeotdarc | 2007-11-13 13:54:28 -0800 (Tue, 13 Nov 2007) | 23 lines Merge from py3k branch: Correction for issue1265 (pdb bug with "with" statement). When an unfinished generator-iterator is garbage collected, PyEval_EvalFrameEx is called with a GeneratorExit exception set. This leads to funny results if the sys.settrace function itself makes use of generators. A visible effect is that the settrace function is reset to None. Another is that the eventual "finally" block of the generator is not called. It is necessary to save/restore the exception around the call to the trace function. This happens a lot with py3k: isinstance() of an ABCMeta instance runs def __instancecheck__(cls, instance): """Override for isinstance(instance, cls).""" return any(cls.__subclasscheck__(c) for c in {instance.__class__, type(instance)}) which lets an opened generator expression each time it returns True. Backport candidate, even if the case is less frequent in 2.5. ........ r58968 | georg.brandl | 2007-11-14 05:59:09 -0800 (Wed, 14 Nov 2007) | 2 lines Remove dead link from random docs. ........ r58971 | raymond.hettinger | 2007-11-14 14:56:16 -0800 (Wed, 14 Nov 2007) | 1 line Make __fields__ read-only. Suggested by Issac Morland ........ r58972 | raymond.hettinger | 2007-11-14 15:02:30 -0800 (Wed, 14 Nov 2007) | 1 line Add test for __fields__ being read-only ........ r58975 | raymond.hettinger | 2007-11-14 18:44:53 -0800 (Wed, 14 Nov 2007) | 6 lines Accept Issac Morland's suggestion for __replace__ to allow multiple replacements (suprisingly, this simplifies the signature, improves clarity, and is comparably fast). Update the docs to reflect a previous change to the function name. Add an example to the docs showing how to override the default __repr__ method. ........ r58976 | raymond.hettinger | 2007-11-14 18:55:42 -0800 (Wed, 14 Nov 2007) | 1 line Small improvement to the implementation of __replace__(). ........ r58977 | raymond.hettinger | 2007-11-14 18:58:20 -0800 (Wed, 14 Nov 2007) | 1 line Fixup example in docs. ........ r58978 | raymond.hettinger | 2007-11-14 19:16:09 -0800 (Wed, 14 Nov 2007) | 1 line Example of multiple replacements. ........ r58998 | raymond.hettinger | 2007-11-15 14:39:34 -0800 (Thu, 15 Nov 2007) | 1 line Add example for use cases requiring default values. ........ r59000 | bill.janssen | 2007-11-15 15:03:03 -0800 (Thu, 15 Nov 2007) | 1 line add the certificate for the Python SVN repository for testing SSL ........ r59004 | guido.van.rossum | 2007-11-15 16:24:44 -0800 (Thu, 15 Nov 2007) | 8 lines A patch from issue 1378 by roudkerk: Currently on Windows set_error() make use of a large array which maps socket error numbers to error messages. This patch removes that array and just lets PyErr_SetExcFromWindowsErr() generate the message by using the Win32 function FormatMessage(). ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/collections.py14
-rw-r--r--Lib/test/seq_tests.py7
-rw-r--r--Lib/test/test_collections.py10
3 files changed, 25 insertions, 6 deletions
diff --git a/Lib/collections.py b/Lib/collections.py
index 90ed776..7b23948 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -30,7 +30,7 @@ def namedtuple(typename, field_names, verbose=False):
11
>>> Point(**d) # convert from a dictionary
Point(x=11, y=22)
- >>> p.__replace__('x', 100) # __replace__() is like str.replace() but targets a named field
+ >>> p.__replace__(x=100) # __replace__() is like str.replace() but targets named fields
Point(x=100, y=22)
"""
@@ -60,7 +60,7 @@ def namedtuple(typename, field_names, verbose=False):
template = '''class %(typename)s(tuple):
'%(typename)s(%(argtxt)s)'
__slots__ = ()
- __fields__ = %(field_names)r
+ __fields__ = property(lambda self: %(field_names)r)
def __new__(cls, %(argtxt)s):
return tuple.__new__(cls, (%(argtxt)s))
def __repr__(self):
@@ -68,9 +68,9 @@ def namedtuple(typename, field_names, verbose=False):
def __asdict__(self, dict=dict, zip=zip):
'Return a new dict mapping field names to their values'
return dict(zip(%(field_names)r, self))
- def __replace__(self, field, value, dict=dict, zip=zip):
- 'Return a new %(typename)s object replacing one field with a new value'
- return %(typename)s(**dict(list(zip(%(field_names)r, self)) + [(field, value)])) \n''' % locals()
+ def __replace__(self, **kwds):
+ 'Return a new %(typename)s object replacing specified fields with new values'
+ return %(typename)s(**dict(zip(%(field_names)r, self) + kwds.items())) \n''' % locals()
for i, name in enumerate(field_names):
template += ' %s = property(itemgetter(%d))\n' % (name, i)
if verbose:
@@ -103,6 +103,10 @@ if __name__ == '__main__':
p = Point(x=10, y=20)
assert p == loads(dumps(p))
+ # test and demonstrate ability to override methods
+ Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
+ print p
+
import doctest
TestResults = namedtuple('TestResults', 'failed attempted')
print(TestResults(*doctest.testmod()))
diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py
index eb6d141..ebd6157 100644
--- a/Lib/test/seq_tests.py
+++ b/Lib/test/seq_tests.py
@@ -304,6 +304,13 @@ class CommonTest(unittest.TestCase):
self.assertEqual(self.type2test(s)*(-4), self.type2test([]))
self.assertEqual(id(s), id(s*1))
+ def test_bigrepeat(self):
+ x = self.type2test([0])
+ x *= 2**16
+ self.assertRaises(MemoryError, x.__mul__, 2**16)
+ if hasattr(x, '__imul__'):
+ self.assertRaises(MemoryError, x.__imul__, 2**16)
+
def test_subscript(self):
a = self.type2test([10, 11])
self.assertEqual(a.__getitem__(0), 10)
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 86b47de..0243134 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -48,9 +48,17 @@ class TestNamedTuple(unittest.TestCase):
self.assert_('__dict__' not in dir(p)) # verify instance has no dict
self.assert_('__weakref__' not in dir(p))
self.assertEqual(p.__fields__, ('x', 'y')) # test __fields__ attribute
- self.assertEqual(p.__replace__('x', 1), (1, 22)) # test __replace__ method
+ self.assertEqual(p.__replace__(x=1), (1, 22)) # test __replace__ method
self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method
+ # Verify that __fields__ is read-only
+ try:
+ p.__fields__ = ('F1' ,'F2')
+ except AttributeError:
+ pass
+ else:
+ self.fail('The __fields__ attribute needs to be read-only')
+
# verify that field string can have commas
Point = namedtuple('Point', 'x, y')
p = Point(x=11, y=22)