Skip to content

ast.compare fails if fields or attributes are missing at runtime #121210

Closed
@picnixz

Description

@picnixz

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

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions