QName can't ingest bytearray parameters
| Affects | Status | Importance | Assigned to | Milestone | |
|---|---|---|---|---|---|
| lxml |
Confirmed
|
Low
|
Unassigned | ||
Bug Description
Trying to fix up typing on a codebase, types-lxml specs `_Element.tag` as `str | bytes | bytearray | QName`, which seems correct -- even if anything but `str` requires the `tag` to be set manually after the fact. I figured I could use `QName` to normalize the tag name, however while it works perfectly for an str, bytes, or a QName:
>>> QName("
'foo'
>>> QName(b"
'foo'
>>> QName(QName(
'foo'
bytearray input fails:
>>> QName(bytearray
Traceback (most recent call last):
File "<python-
File "src/lxml/
File "src/lxml/
ValueError: Invalid tag name "bytearray(b'foo')"
even though it's possible to set `_Element.tag` to a bytearray:
>>> e = Element('x')
>>> e.tag = bytearray(b'x')
>>> e.tag
bytearray(
so there are edge cases where this can fail at runtime. The stubs are both helpful and frustrating here, because they surface this edge case and result in a type error when writing `QName(e.tag)`. However if one finds out that `QName(_Element)` is also valid, and happen to have this condition happen at runtime, everything typechecks but results in an error:
>>> QName(e)
Traceback (most recent call last):
File "<python-
QName(e)
~~~~~^^^
File "src/lxml/
ValueError: Invalid input tag of type <class 'bytearray'>
I think it would make sense for `QName(bytearray)` to be valid resolving these concerns (then the stubs can be updated to match).
Python : sys.version_
lxml.etree : (6, 0, 2, 0)
libxml used : (2, 14, 6)
libxml compiled : (2, 14, 6)
libxslt used : (1, 1, 43)
libxslt compiled : (1, 1, 43)

That looks like a relict from the times when bytearray didn't exist. It should be allowed everywhere where bytes is allowed.
This should be implemented in the respective input conversion/ validation functions in "apihelpers.pxi". They should probably just copy the value into a bytes object if there isn't an obvious quicker way to handle them.
Happy to receive a PR.