Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a86f2c0

Browse files
committed
Merged revisions 69466,69480 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r69466 | raymond.hettinger | 2009-02-09 12:39:41 -0600 (Mon, 09 Feb 2009) | 3 lines Issue 5171: itertools.product docstring missing 'repeat' argument ........ r69480 | raymond.hettinger | 2009-02-09 19:24:05 -0600 (Mon, 09 Feb 2009) | 1 line Issue 1818: collections.namedtuple() to support automatic renaming of invalid fieldnames. ........
1 parent 3a409e9 commit a86f2c0

5 files changed

Lines changed: 39 additions & 3 deletions

File tree

Doc/library/collections.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ Named tuples assign meaning to each position in a tuple and allow for more reada
597597
self-documenting code. They can be used wherever regular tuples are used, and
598598
they add the ability to access fields by name instead of position index.
599599

600-
.. function:: namedtuple(typename, field_names, [verbose])
600+
.. function:: namedtuple(typename, field_names, [verbose], [rename])
601601

602602
Returns a new tuple subclass named *typename*. The new subclass is used to
603603
create tuple-like objects that have fields accessible by attribute lookup as
@@ -615,11 +615,19 @@ they add the ability to access fields by name instead of position index.
615615
a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*,
616616
or *raise*.
617617

618+
If *rename* is true, invalid fieldnames are automatically replaced
619+
with positional names. For example, ``['abc', 'def', 'ghi', 'abc']`` is
620+
converted to ``['abc', '_2', 'ghi', '_4']``, eliminating the keyword
621+
``def`` and the duplicate fieldname ``abc``.
622+
618623
If *verbose* is true, the class definition is printed just before being built.
619624

620625
Named tuple instances do not have per-instance dictionaries, so they are
621626
lightweight and require no more memory than regular tuples.
622627

628+
.. versionchanged:: 2.7
629+
added support for *rename*.
630+
623631
Example:
624632

625633
.. doctest::

Lib/collections.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
### namedtuple
1919
################################################################################
2020

21-
def namedtuple(typename, field_names, verbose=False):
21+
def namedtuple(typename, field_names, verbose=False, rename=False):
2222
"""Returns a new subclass of tuple with named fields.
2323
2424
>>> Point = namedtuple('Point', 'x y')
@@ -47,6 +47,16 @@ def namedtuple(typename, field_names, verbose=False):
4747
if isinstance(field_names, str):
4848
field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
4949
field_names = tuple(map(str, field_names))
50+
if rename:
51+
names = list(field_names)
52+
seen = set()
53+
for i, name in enumerate(names):
54+
if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
55+
or not name or name[0].isdigit() or name.startswith('_')
56+
or name in seen):
57+
names[i] = '_%d' % (i+1)
58+
seen.add(name)
59+
field_names = tuple(names)
5060
for name in (typename,) + field_names:
5161
if not all(c.isalnum() or c=='_' for c in name):
5262
raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
@@ -56,7 +66,7 @@ def namedtuple(typename, field_names, verbose=False):
5666
raise ValueError('Type names and field names cannot start with a number: %r' % name)
5767
seen_names = set()
5868
for name in field_names:
59-
if name.startswith('_'):
69+
if name.startswith('_') and not rename:
6070
raise ValueError('Field names cannot start with an underscore: %r' % name)
6171
if name in seen_names:
6272
raise ValueError('Encountered duplicate field name: %r' % name)

Lib/test/test_collections.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ def test_factory(self):
4747
self.assertRaises(TypeError, Point._make, [11]) # catch too few args
4848
self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
4949

50+
def test_name_fixer(self):
51+
for spec, renamed in [
52+
[('efg', 'g%hi'), ('efg', '_2')], # field with non-alpha char
53+
[('abc', 'class'), ('abc', '_2')], # field has keyword
54+
[('8efg', '9ghi'), ('_1', '_2')], # field starts with digit
55+
[('abc', '_efg'), ('abc', '_2')], # field with leading underscore
56+
[('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_3', 'ghi')], # duplicate field
57+
[('abc', '', 'x'), ('abc', '_2', 'x')], # fieldname is a space
58+
]:
59+
self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
60+
5061
def test_instance(self):
5162
Point = namedtuple('Point', 'x y')
5263
p = Point(11, 22)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ Library
170170
- Issue #5122: Synchronize tk load failure check to prevent a potential
171171
deadlock.
172172

173+
- Issue #1818: collections.namedtuple() now supports a keyword argument
174+
'rename' which lets invalid fieldnames be automatically converted to
175+
positional names in the form, _1, _2, ...
176+
173177
- Issue #4890: Handle empty text search pattern in Tkinter.Text.search.
174178

175179
- Issue #4512 (part 2): Promote ``ZipImporter._get_filename()`` to be a

Modules/itertoolsmodule.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,9 @@ For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\
17911791
The leftmost iterators are in the outermost for-loop, so the output tuples\n\
17921792
cycle in a manner similar to an odometer (with the rightmost element changing\n\
17931793
on every iteration).\n\n\
1794+
To compute the product of an iterable with itself, specify the number\n\
1795+
of repetitions with the optional repeat keyword argument. For example,\n\
1796+
product(A, repeat=4) means the same as product(A, A, A, A).\n\n\
17941797
product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\
17951798
product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");
17961799

0 commit comments

Comments
 (0)