This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: SystemError when set Element.attrib to non-dict
Type: behavior Stage: resolved
Components: Extension Modules, XML Versions: Python 3.9
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: eli.bendersky, scoder, serhiy.storchaka
Priority: normal Keywords:

Created on 2020-02-03 10:19 by serhiy.storchaka, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg361279 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-02-03 10:19
The C implementation raises a SystemError after setting Element.attrib to non-dict.

>>> from xml.etree import ElementTree as ET
>>> e = ET.Element('a')
>>> e.attrib = 1
>>> e.get('x')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: Objects/dictobject.c:1438: bad argument to internal function
>>> e.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: Objects/dictobject.c:2732: bad argument to internal function
>>> e.keys()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: Objects/dictobject.c:2712: bad argument to internal function

The only valid non-dict value is None (although it is an implementation detail).

>>> e.attrib = None
>>> e.get('x')
>>> e.items()
[]
>>> e.keys()
[]

The Python implementation raises an AttributeError (even for None).

>>> import sys
>>> sys.modules['_elementtree'] = None
>>> from xml.etree import ElementTree as ET
>>> e = ET.Element('a')
>>> e.attrib = 1
>>> e.get('x')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython3.8/Lib/xml/etree/ElementTree.py", line 358, in get
    return self.attrib.get(key, default)
AttributeError: 'int' object has no attribute 'get'
>>> e.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython3.8/Lib/xml/etree/ElementTree.py", line 388, in items
    return self.attrib.items()
AttributeError: 'int' object has no attribute 'items'
>>> e.keys()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython3.8/Lib/xml/etree/ElementTree.py", line 377, in keys
    return self.attrib.keys()
AttributeError: 'int' object has no attribute 'keys'

Other way to trigger an error is via __setstate__().
msg361418 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2020-02-05 08:53
I agree that SystemError is the wrong response. Whether it needs to be AttributeError – probably fine to consider this an implementation detail. TypeError also seems ok in at least some of the cases. I think we should widen the code to expect some kind of Mapping (instead of strictly a dict), and if we don't find that on access, a TypeError seems just as good as an AttributeError from Python.

I'm unsure if we should restrict assignments to ".attrib". It's probably enough to allow "None" assignments to say "no attributes allowed", Everything else can be handled by some kind of Mapping object. But then, why not just use the Mapping protocol on access and leave errors to that stage?
msg364790 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-03-22 09:21
Fixed by issue39822. e.attrib = 1 now raises a TypeError.
History
Date User Action Args
2022-04-11 14:59:26adminsetgithub: 83719
2020-03-22 09:21:37serhiy.storchakasetstatus: open -> closed
versions: - Python 2.7, Python 3.7, Python 3.8
messages: + msg364790

resolution: out of date
stage: needs patch -> resolved
2020-02-05 08:53:11scodersetmessages: + msg361418
stage: needs patch
2020-02-03 10:19:15serhiy.storchakacreate