tostring() ignores tag attribute

Bug #1780950 reported by James Pic
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
lxml
Won't Fix
Undecided
Unassigned

Bug Description

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

Test script:

from lxml import etree

class Component(etree.ElementBase):
    pass

class Div(Component):
    tag = 'div'

class Col(Div):
    def __init__(self, l=None):
        self.l = l
        super().__init__()

    def _init(self):
        super()._init()
        if 'class' not in self.attrib:
            self.attrib['class'] = 'col'
        else:
            self.attrib['class'] += ' col'

        if self.l:
            self.attrib['class'] += ' l{}'.format(self.l)

el = Col(l=2)
el.tag = 'div'
print('el repr', el)
print('expected: ', b'<div class="col l2"/>')
print('result: ', etree.tostring(el))

Result:

el repr <Element div at 0x7fe6923ada48>
expected: b'<div class="col l2"/>'
result: b'<Col class="col l2"/>'

As you can see, tostring enforces the class name instead of using the tag attribute, like repr does.

Revision history for this message
scoder (scoder) wrote :

Element classes are not relevant for serialisation. As documented, all state must be stored in the tree, not in the element classes. If you set "self.tag" from your class, you will get the expected result.

Changed in lxml:
status: New → Won't Fix
Revision history for this message
James Pic (jpic) wrote :

What about: repr output is incorrect, and setting tag should raise an exception since it's useless ?

Revision history for this message
scoder (scoder) wrote :

It could be considered acceptable to duplicate the code to read the tag name in a couple of more places, including "__repr__()", rather than resorting to the simple "self.tag". PR welcome.

I don't under your comment regarding an exception when setting the tag. What do you mean here?

Revision history for this message
James Pic (jpic) wrote :

I think the tag attribute should be read only, if we can't change it ?

It's really too bad, Python almost had a perfect component based HTML refactoring pattern like React...

Revision history for this message
scoder (scoder) wrote :

The tag property is writable, but you cannot override it in subclasses (and why would you do that?).

Can't you use a factory function instead of the "Col" class in your example?

Revision history for this message
James Pic (jpic) wrote : Re: [Bug 1780950] Re: tostring() ignores tag attribute

Just because I wanted to use inheritance I guess. We can still use lxml but
i thought it would be cool to start from existing lxml components

But right now we're making a function based poc, thanks for your reply,
will keep you in such if you see fit.

Best regards

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.