>>> from lxml import objectify
>>> from StringIO import StringIO
>>> f = StringIO("<root>data</root>")
>>> tree = objectify.parse(f)
>>> type(tree)
<type 'lxml.etree._ElementTree'>
>>> tree.find('root')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 1944, in lxml.etree._ElementTree.find (src/lxml/lxml.etree.c:45105)
TypeError: find() takes exactly one argument (2 given)
>>> tree.find()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 1926, in lxml.etree._ElementTree.find (src/lxml/lxml.etree.c:44970)
TypeError: find() takes at least 1 positional argument (0 given)
>>> print tree.find.__doc__
find(self, path, namespaces=None)
Finds the first toplevel element with given tag. Same as
``tree.getroot().find(path)``.
The optional ``namespaces`` argument accepts a
prefix-to-namespace mapping that allows the usage of XPath
prefixes in the path expression.
Note that tree.getroot().find works and find works on _ElementTree instances created by etree.parse.
Tha main question: how can the same method raise these two mutually exclusive exceptions? Also, while I can use tree.getroot().find, the shorter form would be preferred if it worked as documented, so I’m curious, is it a lxml bug?
We solve this mystery by looking at the corresponding source (long live OSS):
"lxml.etree.pyx", line 1926is the first and"lxml.etree.pyx", line 1944the last line of the sniplet, so there are in fact two differentfindmethods. Apparently objectify constructs some different objects (and thus this is a bug in lxml) that do not accept thenamespacesparameter. If you uselxml.etree.parseto parse yourStringIOobject, the API works just fine.