summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2012-06-10 01:46:45 (GMT)
committerRaymond Hettinger <python@rcn.com>2012-06-10 01:46:45 (GMT)
commit80ed4d47746ba48109c7c0f49877102521af93c8 (patch)
tree92b1b10a1e706c967d3a073cc58741bce3e506cf
parent75963643b178f9d72d3b6bb02d136d67c9cc6d3e (diff)
downloadcpython-80ed4d47746ba48109c7c0f49877102521af93c8.zip
cpython-80ed4d47746ba48109c7c0f49877102521af93c8.tar.gz
cpython-80ed4d47746ba48109c7c0f49877102521af93c8.tar.bz2
Minor reformatting (wrap fat lines, etc.) and create an __main__ file
-rw-r--r--Lib/collections/__init__.py66
-rw-r--r--Lib/collections/__main__.py38
2 files changed, 53 insertions, 51 deletions
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
index b1c82b4..355c0c1 100644
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -315,10 +315,10 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
"""
- # Parse and validate the field names. Validation serves two purposes,
- # generating informative error messages and preventing template injection attacks.
+ # Validate the field names. At the user's option, either generate an error
+ # message or automatically replace the field name with a valid name.
if isinstance(field_names, str):
- field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
+ field_names = field_names.replace(',', ' ').split()
field_names = list(map(str, field_names))
if rename:
seen = set()
@@ -333,15 +333,19 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
seen.add(name)
for name in [typename] + field_names:
if not all(c.isalnum() or c=='_' for c in name):
- raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name)
+ raise ValueError('Type names and field names can only contain '
+ 'alphanumeric characters and underscores: %r' % name)
if _iskeyword(name):
- raise ValueError('Type names and field names cannot be a keyword: %r' % name)
+ raise ValueError('Type names and field names cannot be a '
+ 'keyword: %r' % name)
if name[0].isdigit():
- raise ValueError('Type names and field names cannot start with a number: %r' % name)
+ raise ValueError('Type names and field names cannot start with '
+ 'a number: %r' % name)
seen = set()
for name in field_names:
if name.startswith('_') and not rename:
- raise ValueError('Field names cannot start with an underscore: %r' % name)
+ raise ValueError('Field names cannot start with an underscore: '
+ '%r' % name)
if name in seen:
raise ValueError('Encountered duplicate field name: %r' % name)
seen.add(name)
@@ -352,13 +356,14 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
field_names = tuple(field_names),
num_fields = len(field_names),
arg_list = repr(tuple(field_names)).replace("'", "")[1:-1],
- repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names),
+ repr_fmt = ', '.join(_repr_template.format(name=name)
+ for name in field_names),
field_defs = '\n'.join(_field_template.format(index=index, name=name)
for index, name in enumerate(field_names))
)
- # Execute the template string in a temporary namespace and
- # support tracing utilities by setting a value for frame.f_globals['__name__']
+ # Execute the template string in a temporary namespace and support
+ # tracing utilities by setting a value for frame.f_globals['__name__']
namespace = dict(__name__='namedtuple_%s' % typename)
try:
exec(class_definition, namespace)
@@ -1122,44 +1127,3 @@ class UserString(Sequence):
return self.__class__(self.data.translate(*args))
def upper(self): return self.__class__(self.data.upper())
def zfill(self, width): return self.__class__(self.data.zfill(width))
-
-
-
-################################################################################
-### Simple tests
-################################################################################
-
-if __name__ == '__main__':
- # verify that instances can be pickled
- from pickle import loads, dumps
- Point = namedtuple('Point', 'x, y', True)
- p = Point(x=10, y=20)
- assert p == loads(dumps(p))
-
- # test and demonstrate ability to override methods
- class Point(namedtuple('Point', 'x y')):
- __slots__ = ()
- @property
- def hypot(self):
- return (self.x ** 2 + self.y ** 2) ** 0.5
- def __str__(self):
- return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
-
- for p in Point(3, 4), Point(14, 5/7.):
- print (p)
-
- class Point(namedtuple('Point', 'x y')):
- 'Point class with optimized _make() and _replace() without error-checking'
- __slots__ = ()
- _make = classmethod(tuple.__new__)
- def _replace(self, _map=map, **kwds):
- return self._make(_map(kwds.get, ('x', 'y'), self))
-
- print(Point(11, 22)._replace(x=100))
-
- Point3D = namedtuple('Point3D', Point._fields + ('z',))
- print(Point3D.__doc__)
-
- import doctest
- TestResults = namedtuple('TestResults', 'failed attempted')
- print(TestResults(*doctest.testmod()))
diff --git a/Lib/collections/__main__.py b/Lib/collections/__main__.py
new file mode 100644
index 0000000..763e38e
--- /dev/null
+++ b/Lib/collections/__main__.py
@@ -0,0 +1,38 @@
+################################################################################
+### Simple tests
+################################################################################
+
+# verify that instances can be pickled
+from collections import namedtuple
+from pickle import loads, dumps
+Point = namedtuple('Point', 'x, y', True)
+p = Point(x=10, y=20)
+assert p == loads(dumps(p))
+
+# test and demonstrate ability to override methods
+class Point(namedtuple('Point', 'x y')):
+ __slots__ = ()
+ @property
+ def hypot(self):
+ return (self.x ** 2 + self.y ** 2) ** 0.5
+ def __str__(self):
+ return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
+
+for p in Point(3, 4), Point(14, 5/7.):
+ print (p)
+
+class Point(namedtuple('Point', 'x y')):
+ 'Point class with optimized _make() and _replace() without error-checking'
+ __slots__ = ()
+ _make = classmethod(tuple.__new__)
+ def _replace(self, _map=map, **kwds):
+ return self._make(_map(kwds.get, ('x', 'y'), self))
+
+print(Point(11, 22)._replace(x=100))
+
+Point3D = namedtuple('Point3D', Point._fields + ('z',))
+print(Point3D.__doc__)
+
+import doctest, collections
+TestResults = namedtuple('TestResults', 'failed attempted')
+print(TestResults(*doctest.testmod(collections)))