ElementMaker as class variables are interpreted as abstract methods

Bug #1706256 reported by Hynek Schlawack
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
lxml
Triaged
Undecided
Unassigned

Bug Description

So this is kind of a fun one:

>>> import abc

>>> from lxml.builder import ElementMaker

>>> EM = ElementMaker()

>>> EM.foo()
<Element foo at 0x11066a388>

>>> class C(metaclass=abc.ABCMeta):
... x = EM

>>> C()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class C with abstract methods x
Can't instantiate abstract class C with abstract methods x

Details:

Python : sys.version_info(major=3, minor=6, micro=1, releaselevel='final', serial=0)
lxml.etree : (3, 8, 0, 0)
libxml used : (2, 9, 4)
libxml compiled : (2, 9, 4)
libxslt used : (1, 1, 29)
libxslt compiled : (1, 1, 29)

Let me know if you need more information. :)

Revision history for this message
scoder (scoder) wrote :

Yes, a lovely one. Thanks for sharing. ;)

The reason is in ABCMeta.__new__():

        abstracts = {name
                     for name, value in namespace.items()
                     if getattr(value, "__isabstractmethod__", False)}

Calling getattr() on the ElementMaker will not raise an AttributeError, but return a partial(ElementMaker) that creates "__isabstractmethod__" tags. That partial object resolves to true in the code abode and ABCMeta considers that enough to assume it's an actual abstract method. :)

I'd rather not restrict the (valid) tag names that ElementMaker is allowed to create - imagine a user wants to write an XML serialiser for Python class definitions. That could actually benefit from an XML tag name "__isabstractmethod__".

In short - I'm not sure if this is worth fixing. What do you think?

Changed in lxml:
status: New → Triaged
Revision history for this message
Hynek Schlawack (hyneks) wrote :

Hm I would suggest to document it and leave it be.

Ivan Levkivskyi mentioned to me that he's rewriting ABCMeta in C so the bug should dissolve eventually: https://twitter.com/ILevkivskyi/status/889880285583724544

But ATM it's confusing af and Google brings up nothing.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.