This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: collections.namedtuple generates code causing PyChecker warnings
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.1, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: mbessonov, ncoghlan, rhettinger
Priority: low Keywords:

Created on 2009-02-21 09:24 by mbessonov, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg82562 - (view) Author: Mikhail Bessonov (mbessonov) Date: 2009-02-21 09:24
The first argument of some methods generated by collections.namedtuple 
differs from 'self'. It upsets a number of code checkers, notably 
PyChecker, because in most cases it is indeed an error. As a result, 
the code using collections.namedtuple does not pass PyChecker, which is 
a commit or release requirement in many projects.

The solution would be to rename the first argument of each method to 
'self'.

A sample 2-line program demonstrating the error is provided below.

import collections
DocRecord = collections.namedtuple('DocRecord', 'id, date, name, desc',
		verbose = True)

Here's the PyChecker output. Methods that cause trouble are 'def _asdict
(t):', etc.

E:\src\mini-crawler>E:\Python26\python.exe E:\Python26\Lib\site-packages
\pychecker\checker.py test.py 
class DocRecord(tuple):
        'DocRecord(id, date, name, desc)' 

        __slots__ = () 

        _fields = ('id', 'date', 'name', 'desc') 

        def __new__(cls, id, date, name, desc):
            return tuple.__new__(cls, (id, date, name, desc)) 

        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new DocRecord object from a sequence or iterable'
            result = new(cls, iterable)
            if len(result) != 4:
                raise TypeError('Expected 4 arguments, got %d' % len
(result))
            return result 

        def __repr__(self):
            return 'DocRecord(id=%r, date=%r, name=%r, desc=%r)' % self 

        def _asdict(t):
            'Return a new dict which maps field names to their values'
            return {'id': t[0], 'date': t[1], 'name': t[2], 'desc': t
[3]} 

        def _replace(self, **kwds):
            'Return a new DocRecord object replacing specified fields 
with new values'
            result = self._make(map(kwds.pop, ('id', 'date', 'name', 
'desc'), self))
            if kwds:
                raise ValueError('Got unexpected field names: %r' % 
kwds.keys())
            return result 

        def __getnewargs__(self):
            return tuple(self) 

        id = property(itemgetter(0))
        date = property(itemgetter(1))
        name = property(itemgetter(2))
        desc = property(itemgetter(3))


Warnings...

<string>:22: self is not first method argument
msg82581 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-02-21 21:04
Will look at this one.  Am initially disinclined to change _asdict()
because I like its compact presentation.
msg82884 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-02-27 23:26
Completely unrelated to the topic at hand, but that command line can be
written more concisely as:

E:\Python26\python.exe -m pychecker.checker test.py 

(pychecker was actually the number 1 use case when it came to justifying
the expansion of -m to modules inside packages)

As for the actual topic of the bug report... using 't' for tuple
(instead of the more common 'self') seems like a perfectly reasonable
name for the first argument to _asdict(). Expanding it to 'self' doesn't
really improve readability all that much - it just makes the self
references take up more visual space relative to the attribute names.

def _asdict(self):
  'Return a new dict which maps field names to their values'
  return {'id': self[0], 'date': self[1], 'name': self[2], 'desc': self
[3]}

Pychecker and friends are probably going to want to recognise namedtuple
instances and silence this warning by default anyway (since even if it
does get changed, there will still be plenty of Python installations out
there which will still generate the warning).
msg83065 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-03-03 07:51
Fixed in r70106 and r70121 as part of converting _asdict() to return an
OrderedDictionary.

Leaving 2.6 and 3.0 as-is.
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49586
2009-03-03 07:51:14rhettingersetstatus: open -> closed
resolution: fixed
messages: + msg83065
versions: + Python 3.1, Python 2.7, - Python 2.6
2009-02-27 23:26:46ncoghlansetnosy: + ncoghlan
messages: + msg82884
2009-02-21 21:04:29rhettingersetpriority: low
messages: + msg82581
2009-02-21 13:40:08benjamin.petersonsetassignee: rhettinger
nosy: + rhettinger
2009-02-21 09:24:51mbessonovcreate