[Python-checkins] cpython (2.7): Code cleanups

raymond.hettinger python-checkins at python.org
Fri Jun 8 22:24:46 CEST 2012


http://hg.python.org/cpython/rev/aca1a271c4fc
changeset:   77389:aca1a271c4fc
branch:      2.7
parent:      77382:b873afe640e2
user:        Raymond Hettinger <python at rcn.com>
date:        Fri Jun 08 13:24:12 2012 -0700
summary:
  Code cleanups

files:
  Doc/library/collections.rst |   64 ++++++------
  Lib/collections.py          |  117 ++++++++++++++---------
  2 files changed, 105 insertions(+), 76 deletions(-)


diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -601,47 +601,49 @@
 
    >>> Point = namedtuple('Point', ['x', 'y'], verbose=True)
    class Point(tuple):
-           'Point(x, y)'
+       'Point(x, y)'
    <BLANKLINE>
-           __slots__ = ()
+       __slots__ = ()
    <BLANKLINE>
-           _fields = ('x', 'y')
+       _fields = ('x', 'y')
    <BLANKLINE>
-           def __new__(_cls, x, y):
-               'Create a new instance of Point(x, y)'
-               return _tuple.__new__(_cls, (x, y))
+       def __new__(_cls, x, y):
+           'Create a new instance of Point(x, y)'
+           return _tuple.__new__(_cls, (x, y))
    <BLANKLINE>
-           @classmethod
-           def _make(cls, iterable, new=tuple.__new__, len=len):
-               'Make a new Point object from a sequence or iterable'
-               result = new(cls, iterable)
-               if len(result) != 2:
-                   raise TypeError('Expected 2 arguments, got %d' % len(result))
-               return result
+       @classmethod
+       def _make(cls, iterable, new=tuple.__new__, len=len):
+           'Make a new Point object from a sequence or iterable'
+           result = new(cls, iterable)
+           if len(result) != 2:
+               raise TypeError('Expected 2 arguments, got %d' % len(result))
+           return result
    <BLANKLINE>
-           def __repr__(self):
-               'Return a nicely formatted representation string'
-               return 'Point(x=%r, y=%r)' % self
+       def __repr__(self):
+           'Return a nicely formatted representation string'
+           return 'Point(x=%r, y=%r)' % self
    <BLANKLINE>
-           def _asdict(self):
-               'Return a new OrderedDict which maps field names to their values'
-               return OrderedDict(zip(self._fields, self))
+       def _asdict(self):
+           'Return a new OrderedDict which maps field names to their values'
+           return OrderedDict(zip(self._fields, self))
    <BLANKLINE>
-          __dict__ = property(_asdict)
+      __dict__ = property(_asdict)
    <BLANKLINE>
-          def _replace(_self, **kwds):
-               'Return a new Point object replacing specified fields with new values'
-               result = _self._make(map(kwds.pop, ('x', 'y'), _self))
-               if kwds:
-                   raise ValueError('Got unexpected field names: %r' % kwds.keys())
-               return result
+      def _replace(_self, **kwds):
+           'Return a new Point object replacing specified fields with new values'
+           result = _self._make(map(kwds.pop, ('x', 'y'), _self))
+           if kwds:
+               raise ValueError('Got unexpected field names: %r' % kwds.keys())
+           return result
    <BLANKLINE>
-           def __getnewargs__(self):
-               'Return self as a plain tuple.   Used by copy and pickle.'
-               return tuple(self)
+       def __getnewargs__(self):
+           'Return self as a plain tuple.   Used by copy and pickle.'
+           return tuple(self)
    <BLANKLINE>
-           x = _property(_itemgetter(0), doc='Alias for field number 0')
-           y = _property(_itemgetter(1), doc='Alias for field number 1')
+       x = _property(_itemgetter(0), doc='Alias for field number 0')
+   <BLANKLINE>
+       y = _property(_itemgetter(1), doc='Alias for field number 1')
+   <BLANKLINE>
 
    >>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
    >>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
diff --git a/Lib/collections.py b/Lib/collections.py
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -234,10 +234,60 @@
 ### namedtuple
 ################################################################################
 
+_class_template = '''\
+class {typename}(tuple):
+    '{typename}({arg_list})'
+
+    __slots__ = ()
+
+    _fields = {field_names!r}
+
+    def __new__(_cls, {arg_list}):
+        'Create new instance of {typename}({arg_list})'
+        return _tuple.__new__(_cls, ({arg_list}))
+
+    @classmethod
+    def _make(cls, iterable, new=tuple.__new__, len=len):
+        'Make a new {typename} object from a sequence or iterable'
+        result = new(cls, iterable)
+        if len(result) != {num_fields:d}:
+            raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result))
+        return result
+
+    def __repr__(self):
+        'Return a nicely formatted representation string'
+        return '{typename}({repr_fmt})' % self
+
+    def _asdict(self):
+        'Return a new OrderedDict which maps field names to their values'
+        return OrderedDict(zip(self._fields, self))
+
+    __dict__ = property(_asdict)
+
+    def _replace(_self, **kwds):
+        'Return a new {typename} object replacing specified fields with new values'
+        result = _self._make(map(kwds.pop, {field_names!r}, _self))
+        if kwds:
+            raise ValueError('Got unexpected field names: %r' % kwds.keys())
+        return result
+
+    def __getnewargs__(self):
+        'Return self as a plain tuple.  Used by copy and pickle.'
+        return tuple(self)
+
+{field_defs}
+'''
+
+_repr_template = '{name}=%r'
+
+_field_template = '''\
+    {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}')
+'''
+
 def namedtuple(typename, field_names, verbose=False, rename=False):
     """Returns a new subclass of tuple with named fields.
 
-    >>> Point = namedtuple('Point', 'x y')
+    >>> Point = namedtuple('Point', ['x', 'y'])
     >>> Point.__doc__                   # docstring for the new class
     'Point(x, y)'
     >>> p = Point(11, y=22)             # instantiate with positional args or keywords
@@ -267,8 +317,11 @@
         names = list(field_names)
         seen = set()
         for i, name in enumerate(names):
-            if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
-                or not name or name[0].isdigit() or name.startswith('_')
+            if (not all(c.isalnum() or c=='_' for c in name)
+                or _iskeyword(name)
+                or not name
+                or name[0].isdigit()
+                or name.startswith('_')
                 or name in seen):
                 names[i] = '_%d' % i
             seen.add(name)
@@ -280,60 +333,34 @@
             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)
-    seen_names = set()
+    seen = set()
     for name in field_names:
         if name.startswith('_') and not rename:
             raise ValueError('Field names cannot start with an underscore: %r' % name)
-        if name in seen_names:
+        if name in seen:
             raise ValueError('Encountered duplicate field name: %r' % name)
-        seen_names.add(name)
+        seen.add(name)
 
-    # Create and fill-in the class template
-    numfields = len(field_names)
-    argtxt = repr(field_names).replace("'", "")[1:-1]   # tuple repr without parens or quotes
-    reprtxt = ', '.join('%s=%%r' % name for name in field_names)
-    template = '''class %(typename)s(tuple):
-        '%(typename)s(%(argtxt)s)' \n
-        __slots__ = () \n
-        _fields = %(field_names)r \n
-        def __new__(_cls, %(argtxt)s):
-            'Create new instance of %(typename)s(%(argtxt)s)'
-            return _tuple.__new__(_cls, (%(argtxt)s)) \n
-        @classmethod
-        def _make(cls, iterable, new=tuple.__new__, len=len):
-            'Make a new %(typename)s object from a sequence or iterable'
-            result = new(cls, iterable)
-            if len(result) != %(numfields)d:
-                raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
-            return result \n
-        def __repr__(self):
-            'Return a nicely formatted representation string'
-            return '%(typename)s(%(reprtxt)s)' %% self \n
-        def _asdict(self):
-            'Return a new OrderedDict which maps field names to their values'
-            return OrderedDict(zip(self._fields, self)) \n
-        __dict__ = property(_asdict) \n
-        def _replace(_self, **kwds):
-            'Return a new %(typename)s object replacing specified fields with new values'
-            result = _self._make(map(kwds.pop, %(field_names)r, _self))
-            if kwds:
-                raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
-            return result \n
-        def __getnewargs__(self):
-            'Return self as a plain tuple.  Used by copy and pickle.'
-            return tuple(self) \n\n''' % locals()
-    for i, name in enumerate(field_names):
-        template += "        %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i)
+    # Fill-in the class template
+    class_definition = _class_template.format(
+        typename = typename,
+        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),
+        field_defs = '\n'.join(_field_template.format(index=index, name=name)
+                               for index, name in enumerate(field_names))
+    )
     if verbose:
-        print template
+        print class_definition
 
     # Execute the template string in a temporary namespace and
     # support tracing utilities by setting a value for frame.f_globals['__name__']
     namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
                      OrderedDict=OrderedDict, _property=property, _tuple=tuple)
     try:
-        exec template in namespace
-    except SyntaxError, e:
+        exec class_definition in namespace
+    except SyntaxError as e:
         raise SyntaxError(e.message + ':\n' + template)
     result = namespace[typename]
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list