aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/ast.py
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2024-07-02 12:53:17 +0200
committerGitHub <noreply@github.com>2024-07-02 16:23:17 +0530
commit15232a0819a2f7e0f448f28f2e6081912d10e7cb (patch)
tree6d8f806342d289b3c131b04fbab7e7d81dd8306d /Lib/ast.py
parent7a807c3efaa83f1e4fb9b791579b47a0a1fd47de (diff)
downloadcpython-15232a0819a2f7e0f448f28f2e6081912d10e7cb.tar.gz
cpython-15232a0819a2f7e0f448f28f2e6081912d10e7cb.zip
gh-121210: handle nodes with missing attributes/fields in `ast.compare` (#121211)
Diffstat (limited to 'Lib/ast.py')
-rw-r--r--Lib/ast.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/Lib/ast.py b/Lib/ast.py
index fb4d21b87d8..a954d4a97d3 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -422,6 +422,8 @@ def compare(
might differ in whitespace or similar details.
"""
+ sentinel = object() # handle the possibility of a missing attribute/field
+
def _compare(a, b):
# Compare two fields on an AST object, which may themselves be
# AST objects, lists of AST objects, or primitive ASDL types
@@ -449,8 +451,14 @@ def compare(
if a._fields != b._fields:
return False
for field in a._fields:
- a_field = getattr(a, field)
- b_field = getattr(b, field)
+ a_field = getattr(a, field, sentinel)
+ b_field = getattr(b, field, sentinel)
+ if a_field is sentinel and b_field is sentinel:
+ # both nodes are missing a field at runtime
+ continue
+ if a_field is sentinel or b_field is sentinel:
+ # one of the node is missing a field
+ return False
if not _compare(a_field, b_field):
return False
else:
@@ -461,8 +469,11 @@ def compare(
return False
# Attributes are always ints.
for attr in a._attributes:
- a_attr = getattr(a, attr)
- b_attr = getattr(b, attr)
+ a_attr = getattr(a, attr, sentinel)
+ b_attr = getattr(b, attr, sentinel)
+ if a_attr is sentinel and b_attr is sentinel:
+ # both nodes are missing an attribute at runtime
+ continue
if a_attr != b_attr:
return False
else: