Search code examples
pythonlistpython-2.7nonetype

Declared list raises NoneType exception


I have a snippet from someone else's python module that is raising an exception (AttributeError: 'NoneType' object has no attribute 'append'). The snippet is:

def generateFragments(self):
    tr = self.deviceTransform()
    if tr is None:
        return
    pts = np.empty((2,len(self.data['x'])))
    pts[0] = self.data['x']
    pts[1] = self.data['y']
    pts = fn.transformCoordinates(tr, pts)
    self.fragments = []
    pts = np.clip(pts, -2**30, 2**30) ## prevent Qt segmentation fault.
                                      ## Still won't be able to render correctly, though.
    for i in xrange(len(self.data)):
        rec = self.data[i]
        pos = QtCore.QPointF(pts[0,i], pts[1,i])
        x,y,w,h = rec['fragCoords']
        rect = QtCore.QRectF(y, x, h, w)
        self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))

And the exception message is:

[14:35:59]  Ignored exception:

    |==============================>>
    |  Traceback (most recent call last):
    |    File "/usr/lib/pymodules/python2.7/pyqtgraph/debug.py", line 35, in w
    |      func(*args, **kwds)
    |    File "/usr/lib/pymodules/python2.7/pyqtgraph/graphicsItems/ScatterPlotItem.py", line 714, in paint
    |      self.generateFragments()
    |    File "/usr/lib/pymodules/python2.7/pyqtgraph/graphicsItems/ScatterPlotItem.py", line 685, in generateFragments
    |      self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))
    |  AttributeError: 'NoneType' object has no attribute 'append'
    |  
    |==============================<<

This isn't a "fix my error" question but a "how is this possible" question. A couple of lines above, self.fragments is declared as an empty list. From that point onwards, the only modification of self.fragments is to call append(). How could the type have possibly changed? Is there a possible failure in the append operation that might change the type of the list to NoneType?


Solution

  • The 2 possibilities coming to my mind are:

    • concurrency (as per @ekhumoro's comment).
    • the class is defining a __getattribute__ method that short circuits the usual attribute retrieval mechanism.