Commit 27d11a39 authored by Raymond Hettinger's avatar Raymond Hettinger

Wrap fat lines and improve some variable names.

parent f1d72393
...@@ -308,35 +308,37 @@ def namedtuple(typename, field_names, verbose=False, rename=False): ...@@ -308,35 +308,37 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
""" """
# Parse and validate the field names. Validation serves two purposes, # Validate the field names. At the user's option, either generate an error
# generating informative error messages and preventing template injection attacks. # message or automatically replace the field name with a valid name.
if isinstance(field_names, basestring): if isinstance(field_names, basestring):
field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas field_names = field_names.replace(',', ' ').split()
field_names = tuple(map(str, field_names)) field_names = map(str, field_names)
if rename: if rename:
names = list(field_names)
seen = set() seen = set()
for i, name in enumerate(names): for index, name in enumerate(field_names):
if (not all(c.isalnum() or c=='_' for c in name) if (not all(c.isalnum() or c=='_' for c in name)
or _iskeyword(name) or _iskeyword(name)
or not name or not name
or name[0].isdigit() or name[0].isdigit()
or name.startswith('_') or name.startswith('_')
or name in seen): or name in seen):
names[i] = '_%d' % i field_names[index] = '_%d' % index
seen.add(name) seen.add(name)
field_names = tuple(names) for name in [typename] + field_names:
for name in (typename,) + field_names:
if not all(c.isalnum() or c=='_' for c in name): 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): 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(): 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() seen = set()
for name in field_names: for name in field_names:
if name.startswith('_') and not rename: 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: if name in seen:
raise ValueError('Encountered duplicate field name: %r' % name) raise ValueError('Encountered duplicate field name: %r' % name)
seen.add(name) seen.add(name)
...@@ -347,21 +349,22 @@ def namedtuple(typename, field_names, verbose=False, rename=False): ...@@ -347,21 +349,22 @@ def namedtuple(typename, field_names, verbose=False, rename=False):
field_names = tuple(field_names), field_names = tuple(field_names),
num_fields = len(field_names), num_fields = len(field_names),
arg_list = repr(tuple(field_names)).replace("'", "")[1:-1], 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) field_defs = '\n'.join(_field_template.format(index=index, name=name)
for index, name in enumerate(field_names)) for index, name in enumerate(field_names))
) )
if verbose: if verbose:
print class_definition print class_definition
# Execute the template string in a temporary namespace and # Execute the template string in a temporary namespace and support
# support tracing utilities by setting a value for frame.f_globals['__name__'] # tracing utilities by setting a value for frame.f_globals['__name__']
namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
OrderedDict=OrderedDict, _property=property, _tuple=tuple) OrderedDict=OrderedDict, _property=property, _tuple=tuple)
try: try:
exec class_definition in namespace exec class_definition in namespace
except SyntaxError as e: except SyntaxError as e:
raise SyntaxError(e.message + ':\n' + template) raise SyntaxError(e.message + ':\n' + class_definition)
result = namespace[typename] result = namespace[typename]
# For pickling to work, the __module__ variable needs to be set to the frame # For pickling to work, the __module__ variable needs to be set to the frame
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment