Bug report
Bug description:
ast.compare does not handle the case where attributes or fields are missing at runtime:
>>> import ast >>> a = ast.parse('a').body[0].value >>> del a.id >>> ast.compare(a, a) Traceback (most recent call last): File "<python-input-5>", line 1, in <module> ast.compare(a,a) ~~~~~~~~~~~^^^^^ File "/lib/python/cpython/Lib/ast.py", line 473, in compare if not _compare_fields(a, b): ~~~~~~~~~~~~~~~^^^^^^ File "/lib/python/cpython/Lib/ast.py", line 452, in _compare_fields a_field = getattr(a, field) AttributeError: 'Name' object has no attribute 'id' >>> a = ast.parse('a').body[0].value >>> del a.lineno >>> ast.compare(a, a, compare_attributes=True) Traceback (most recent call last): File "<python-input-8>", line 2, in <module> ast.compare(a, a, compare_attributes=True) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/lib/python/cpython/Lib/ast.py", line 475, in compare if compare_attributes and not _compare_attributes(a, b): ~~~~~~~~~~~~~~~~~~~^^^^^^ File "/lib/python/cpython/Lib/ast.py", line 464, in _compare_attributes a_attr = getattr(a, attr) AttributeError: 'Name' object has no attribute 'lineno'
I suggest making ast.compare ignore a field/attribute if it's missing on both operands (they do compare equal in the sense that they don't have that specific field; not that even without that assumption, we still have an issue with ast.compare(ast.Name('a'), ast.Name('a'), compare_attributes=True)).
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux