Re: segfault when using etree.CustomElementClassLookup
Stefan Behnel <stefan_ml <at> behnel.de>
2008-06-04 12:38:30 GMT
Hi Martijn,
Martijn Faassen wrote:
> I just ran into a segfault with lxml (2.0.6). The problem is as follows:
>
> from lxml import etree
>
> class Lookup(etree.CustomElementClassLookup):
> def __init__(self):
> pass
Yep, you didn't call the __init__() method of the super class here, so the
internal lookup function call isn't set up. I replaced that with a __cinit__()
now that always sets it to the default lookup scheme, so that it won't
segfault anymore even if people forget the obvious. ;)
A patch is attached and it's generally easy to work around this by writing
correct code, so there won't be a 2.0.7 right away.
BTW, this:
> parser.setElementClassLookup(lookup)
is correctly spelled
> parser.set_element_class_lookup(lookup)
since lxml 2.0, following PEP 8 naming conventions. However, I didn't dare to
remove the original method, since I figured that it would break tons of code
for no major reason. At least the examples should reflect the new name
everywhere now, so maybe I can remove it in lxml 3.0. ;)
Stefan
Index: src/lxml/classlookup.pxi
===================================================================
--- src/lxml/classlookup.pxi (revision 55464)
+++ src/lxml/classlookup.pxi (working copy)
@@ -86,6 +86,10 @@
"""
cdef readonly ElementClassLookup fallback
cdef _element_class_lookup_function _fallback_function
+ def __cinit__(self):
+ # fall back to default lookup
+ self._fallback_function = _lookupDefaultElementClass
+
def __init__(self, ElementClassLookup fallback=None):
if fallback is not None:
self._setFallback(fallback)
@@ -133,8 +137,10 @@
cdef readonly object comment_class
cdef readonly object pi_class
cdef readonly object entity_class
+ def __cinit__(self):
+ self._lookup_function = _lookupDefaultElementClass
+
def __init__(self, element=None, comment=None, pi=None, entity=None):
- self._lookup_function = _lookupDefaultElementClass
if element is None:
self.element_class = _Element
elif issubclass(element, ElementBase):
@@ -213,6 +219,9 @@
cdef object _pytag
cdef char* _c_ns
cdef char* _c_name
+ def __cinit__(self):
+ self._lookup_function = _attribute_class_lookup
+
def __init__(self, attribute_name, class_mapping,
ElementClassLookup fallback=None):
self._pytag = _getNsTag(attribute_name)
@@ -225,7 +234,6 @@
self._class_mapping = dict(class_mapping)
FallbackElementClassLookup.__init__(self, fallback)
- self._lookup_function = _attribute_class_lookup
cdef object _attribute_class_lookup(state, _Document doc, xmlNode* c_node):
cdef AttributeBasedElementClassLookup lookup
@@ -245,8 +253,7 @@
"""ParserBasedElementClassLookup(self, fallback=None)
Element class lookup based on the XML parser.
"""
- def __init__(self, ElementClassLookup fallback=None):
- FallbackElementClassLookup.__init__(self, fallback)
+ def __cinit__(self):
self._lookup_function = _parser_class_lookup
cdef object _parser_class_lookup(state, _Document doc, xmlNode* c_node):
@@ -272,8 +279,7 @@
If you return None from this method, the fallback will be called.
"""
- def __init__(self, ElementClassLookup fallback=None):
- FallbackElementClassLookup.__init__(self, fallback)
+ def __cinit__(self):
self._lookup_function = _custom_class_lookup
def lookup(self, type, doc, namespace, name):
Index: src/lxml/lxml.pyclasslookup.pyx
===================================================================
--- src/lxml/lxml.pyclasslookup.pyx (revision 55464)
+++ src/lxml/lxml.pyclasslookup.pyx (working copy)
@@ -311,8 +311,7 @@
If you return None from this method, the fallback will be called.
"""
- def __init__(self, ElementClassLookup fallback=None):
- FallbackElementClassLookup.__init__(self, fallback)
+ def __cinit__(self):
self._lookup_function = _lookup_class
def lookup(self, doc, element):
_______________________________________________
lxml-dev mailing list
lxml-dev <at> codespeak.net
http://codespeak.net/mailman/listinfo/lxml-dev