[lxml-dev] [PATCH] 1.3 Fatal Python error: deallocating None

David M. Grimes dgrimes at navisite.com
Wed Jun 27 21:53:16 CEST 2007


All -

I have identified a bug with the new attrib.pop() method in lxml-1.3  
There is a piece of code in etree.pyx (line 1483) related to using the 
provided default if the key lookup fails.  The issue is that the 
returned value (from PyTuple_GET_ITEM) is a borrowed reference.

I was using it as such:

  v = elt.attrib.get(k, None)

And eventually (after several iterations of my parsing loop while 
processing various documents) I would get this error:

 Fatal Python error: deallocating None


I was able to create a trivial test case to reproduce:

import lxml.etree as etree

xml = '''\
<?xml version="1.0"?>
<xml/>'''

for i in range(10000):
    et = etree.fromstring(xml)
    et.attrib.pop('x', None)



And the patched code replaces the pop() method in etree.pyx with:

    def pop(self, key, *default):
        if python.PyTuple_GET_SIZE(default) > 1:
            raise TypeError, "pop expected at most 2 arguments, got %d" % \
                  (python.PyTuple_GET_SIZE(default)+1)
        result = _getAttributeValue(self._element, key, None)
        if result is None:
            if python.PyTuple_GET_SIZE(default) == 0:
                raise KeyError, key
            else:
                result = python.PyTuple_GET_ITEM(default, 0)
                python.Py_INCREF(result)
        else:
            _delAttribute(self._element, key)

        return result


This solves the issue for me, and should not introduce any memory leaks, 
as the returned object in the defaulted path should be INCREF'd.

Thanks,

 --Dave

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://codespeak.net/pipermail/lxml-dev/attachments/20070627/0139c2a1/attachment.htm 


More information about the lxml-dev mailing list