diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/collections.py | 14 | ||||
-rw-r--r-- | Lib/test/test_collections.py | 26 |
2 files changed, 23 insertions, 17 deletions
diff --git a/Lib/collections.py b/Lib/collections.py index 6a28553..242de60 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -1,13 +1,13 @@ -__all__ = ['deque', 'defaultdict', 'NamedTuple'] +__all__ = ['deque', 'defaultdict', 'named_tuple'] from _collections import deque, defaultdict from operator import itemgetter as _itemgetter import sys as _sys -def NamedTuple(typename, field_names, verbose=False): +def named_tuple(typename, field_names, verbose=False): """Returns a new subclass of tuple with named fields. - >>> Point = NamedTuple('Point', 'x y') + >>> Point = named_tuple('Point', 'x y') >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords @@ -36,6 +36,10 @@ def NamedTuple(typename, field_names, verbose=False): raise ValueError('Type names and field names can only contain alphanumeric characters and underscores') if any(name.startswith('__') and name.endswith('__') for name in field_names): raise ValueError('Field names cannot start and end with double underscores') + if any(name[:1].isdigit() for name in field_names): + raise ValueError('Field names cannot start with a number') + if len(field_names) != len(set(field_names)): + raise ValueError('Encountered duplicate field name') # Create and fill-in the class template argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes @@ -83,10 +87,10 @@ def NamedTuple(typename, field_names, verbose=False): if __name__ == '__main__': # verify that instances can be pickled from cPickle import loads, dumps - Point = NamedTuple('Point', 'x, y', True) + Point = named_tuple('Point', 'x, y', True) p = Point(x=10, y=20) assert p == loads(dumps(p)) import doctest - TestResults = NamedTuple('TestResults', 'failed attempted') + TestResults = named_tuple('TestResults', 'failed attempted') print TestResults(*doctest.testmod()) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index c260bc7..1af20ca 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,23 +1,25 @@ import unittest from test import test_support -from collections import NamedTuple +from collections import named_tuple class TestNamedTuple(unittest.TestCase): def test_factory(self): - Point = NamedTuple('Point', 'x y') + Point = named_tuple('Point', 'x y') self.assertEqual(Point.__name__, 'Point') self.assertEqual(Point.__doc__, 'Point(x, y)') self.assertEqual(Point.__slots__, ()) self.assertEqual(Point.__module__, __name__) self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertRaises(ValueError, NamedTuple, 'abc%', 'def ghi') - self.assertRaises(ValueError, NamedTuple, 'abc', 'def g%hi') - self.assertRaises(ValueError, NamedTuple, 'abc', '__def__ ghi') - NamedTuple('Point0', 'x1 y2') # Verify that numbers are allowed in names + self.assertRaises(ValueError, named_tuple, 'abc%', 'def ghi') + self.assertRaises(ValueError, named_tuple, 'abc', 'def g%hi') + self.assertRaises(ValueError, named_tuple, 'abc', '__def__ ghi') + self.assertRaises(ValueError, named_tuple, 'abc', 'def def ghi') + self.assertRaises(ValueError, named_tuple, 'abc', '8def 9ghi') + named_tuple('Point0', 'x1 y2') # Verify that numbers are allowed in names def test_instance(self): - Point = NamedTuple('Point', 'x y') + Point = named_tuple('Point', 'x y') p = Point(11, 22) self.assertEqual(p, Point(x=11, y=22)) self.assertEqual(p, Point(11, y=22)) @@ -36,17 +38,17 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method # verify that field string can have commas - Point = NamedTuple('Point', 'x, y') + Point = named_tuple('Point', 'x, y') p = Point(x=11, y=22) self.assertEqual(repr(p), 'Point(x=11, y=22)') # verify that fieldspec can be a non-string sequence - Point = NamedTuple('Point', ('x', 'y')) + Point = named_tuple('Point', ('x', 'y')) p = Point(x=11, y=22) self.assertEqual(repr(p), 'Point(x=11, y=22)') def test_tupleness(self): - Point = NamedTuple('Point', 'x y') + Point = named_tuple('Point', 'x y') p = Point(11, 22) self.assert_(isinstance(p, tuple)) @@ -66,9 +68,9 @@ class TestNamedTuple(unittest.TestCase): def test_odd_sizes(self): - Zero = NamedTuple('Zero', '') + Zero = named_tuple('Zero', '') self.assertEqual(Zero(), ()) - Dot = NamedTuple('Dot', 'd') + Dot = named_tuple('Dot', 'd') self.assertEqual(Dot(1), (1,)) def test_main(verbose=None): |