Your patch fixes those two problems. I found one more in __getitem__. With the following patch, my code runs clean. (insofar as python can valgrind clean.) -nld Index: src/lxml/etree.pyx =================================================================== --- src/lxml/etree.pyx (revision 23162) +++ src/lxml/etree.pyx (working copy) @@ -775,16 +775,18 @@ def __getitem__(self, key): cdef xmlNs* c_ns - cdef char* result + cdef char* cresult ns, tag = _getNsTag(key) if ns is None: - result = tree.xmlGetNoNsProp(self._c_node, tag) + cresult = tree.xmlGetNoNsProp(self._c_node, tag) else: - result = tree.xmlGetNsProp(self._c_node, tag, ns) - if result is NULL: + cresult = tree.xmlGetNsProp(self._c_node, tag, ns) + if cresult is NULL: # XXX free namespace that is not in use..? raise KeyError, key - return funicode(result) + result = funicode(cresult) + tree.xmlFree(cresult) + return result def __len__(self): cdef int c @@ -855,7 +857,11 @@ result = tree.xmlGetNoNsProp(self._c_node, tag) else: result = tree.xmlGetNsProp(self._c_node, tag, ns) - return result is not NULL + if result is not NULL: + tree.xmlFree(result) + return True + else: + return False def __contains__(self, key): cdef xmlNs* c_ns @@ -865,7 +871,11 @@ result = tree.xmlGetNoNsProp(self._c_node, tag) else: result = tree.xmlGetNsProp(self._c_node, tag, ns) - return result is not NULL + if result is not NULL: + tree.xmlFree(result) + return True + else: + return False cdef _Attrib _attribFactory(_Document doc, xmlNode* c_node): cdef _Attrib result