In writing some XML parsing code, I received the warning:
FutureWarning: The behavior of this method will change in future versions. Use specific \'len(elem
This answer addresses the FutureWarning specifically.
When lxml was first written, the lxml.etree._Element
was considered falsey if it had no children.
As a result, this can happen:
>>> from lxml import etree
>>>
>>> root = etree.fromstring('Hello
')
>>> print root
>>> print "root is not Falsey" if root else "root is Falsey"
:1: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead.
root is not Falsey
>>> # that's odd, a warning
>>> h1 = root.find('.//h1')
>>> print h1
>>> print "h1 is not Falsey" if h1 else "h1 is Falsey"
h1 is Falsey
>>> # huh, that is weird! In most of python, an object is rarely False
>>> # we did see a warning though, didn't we?
>>> # let's see how the different elements output
>>> print "root is not None" if root is not None else "root is None"
root is not None
>>> print "h1 is not None" if h1 is not None else "h1 is None"
h1 is not None
>>> print "Length of root is ", len(root)
Length of root is 1
>>> print "Length of h1 is ", len(h1)
Length of h1 is 0
>>> # now to look for something that's not there!
>>> h2 = root.find('.//h2')
>>> print h2
None
>>> print "h2 is not Falsey" if h2 else "h2 is Falsey"
h2 is Falsey
>>> print "h2 is not None" if h2 is not None else "h2 is None"
h2 is None
>>> print "Length of h2 is ", len(h2)
Traceback (most recent call last):
File "", line 1, in
TypeError: object of type 'NoneType' has no len()
Length of h2 is >>>
lxml has been promising for 7+ years that this change is going to happen (after going through several versions) but has never followed through on the threat, no doubt because of how central lxml is and fears it would break a lot of existing code.
However, to be both explicit and sure you don't make a mistake, never use if obj
or if not obj
if that object has a type of lxml.etree._Element
.
Instead, use one of the following checks:
obj = root.find('.//tag')
if obj is not None:
print "Object exists"
if obj is None:
print "Object does not exist/was not found"
if len(obj): # warning: if obj is None (no match found) TypeError
print "Object has children"
if not len(obj): # warning: if obj is None (no match found) TypeError
print "Object does not have children"