8000 gh-60191: Implement ast.compare by isidentical · Pull Request #19211 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-60191: Implement ast.compare #19211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
cfb508f
bpo-15987: Implement ast.compare
isidentical Mar 28, 2020
0441023
unwrap ifs a level
isidentical Mar 31, 2020
9572173
Merge branch 'main' into bpo-15987
AlexWaygood May 11, 2024
52f428e
A few revision to clarify some subtleties of comparing AST objects.
jeremyhylton May 20, 2024
e47fb0b
Merge remote-tracking branch 'upstream/main' into pr_19211
jeremyhylton May 20, 2024
5f37b91
Remove the compare_fields option.
jeremyhylton May 20, 2024
c0bb0e9
Revise docstring and documentation for consistency.
jeremyhylton May 20, 2024
13fbbc9
This PR now describes a feature of 3.14. Revise what's new / news docs.
jeremyhylton May 20, 2024
f8f0747
Update 3.9.rst
jeremyhylton May 20, 2024
deca2da
Remove the compare_types option, which seems unnecessary.
jeremyhylton May 21, 2024
7788744
Update Doc/whatsnew/3.14.rst
jeremyhylton May 21, 2024
05885de
Update Doc/whatsnew/3.14.rst
jeremyhylton May 21, 2024
3b7192e
Remove compare_types from doc. Change ast node to AST.
jeremyhylton May 21, 2024
b9b6c45
Change AST node to AST.
jeremyhylton May 21, 2024
c9aa69e
Merge remote-tracking branch 'upstream/main' into pr_19211
jeremyhylton May 21, 2024
adc2718
Merge branch 'bpo-15987' into pr_19211
jeremyhylton May 21, 2024
0c72337
One more change of "ast nodes" to "ASTs"
jeremyhylton May 21, 2024
6ad21c0
Merge AST comparison into the test for AST validation.
jeremyhylton May 21, 2024
ec8af39
Merge tests for AST parsing and comparison.
jeremyhylton May 21, 2024
c7ea190
Merge branch 'main' into bpo-15987
jeremyhylton May 21, 2024
75ba002
Improve description of compare_attributes arg
jeremyhylton May 21, 2024
5b01405
AP style: Spell out numbers under 10
jeremyhylton May 21, 2024
69be6d2
Improve description of compare_attributes arg
jeremyhylton May 21, 2024
bdd2d66
Improve robustness of compare() in the face of user-modification of AST.
jeremyhylton May 21, 2024
f9d4c39
Update Lib/test/test_ast.py
jeremyhylton May 21, 2024
ed0cddd
Update Lib/test/test_ast.py
jeremyhylton May 21, 2024
2b114a9
Update Lib/test/test_ast.py
jeremyhylton May 21, 2024
4687dc6
Update Lib/test/test_ast.py
jeremyhylton May 21, 2024
455bdb1
whitespace
iritkatriel May 21, 2024
af70707
Merge branch 'main' into bpo-15987
jeremyhylton May 21, 2024
b915d9c
Merge branch 'main' into bpo-15987
jeremyhylton May 21, 2024
ccf410c
Update Doc/library/ast.rst
jeremyhylton May 21, 2024
06988c1
Update Lib/ast.py
jeremyhylton May 21, 2024
0c9da18
Attributes are ints not strings.
jeremyhylton May 21, 2024
6494c23
Explain examples of what are included in attributes.
jeremyhylton May 21, 2024
bf9e403
Update Doc/library/ast.rst
jeremyhylton May 21, 2024
f34dcac
Merge branch 'main' into bpo-15987
jeremyhylton May 21, 2024
d2281f5
Merge branch 'main' into bpo-15987
jeremyhylton May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove the compare_fields option.
The basic functionality here is to compare asts recursively. If
compare_fields is False, then the comparison is not recursive. It just
compares that the top-level AST objects are the same and have the same
attributes. This option doesn't seem interesting enough to offer as a
feature.

Revise the docstring for compare() to explain the options in more detail.
  • Loading branch information
jeremyhylton committed May 20, 2024
commit 5f37b9117950a8cc7c16273b304f53b821b97fbf
25 changes: 16 additions & 9 deletions Lib/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,15 +407,23 @@ def compare(
/,
*,
compare_types=True,
compare_fields=True,
compare_attributes=False,
):
"""
Compares recursively given two ast nodes. If *compare_types* is False, the
field values won't be checked whether they belong to same type or not. If
*compare_fields* is True, members of `_fields` attribute on both node's type
will be checked. If *compare_attributes* is True, members of `_attributes`
attribute on both node's will be compared.
"""Compares recursively given two ast nodes.

There are two options that control how the comparison is done.

compare_types affects how Constant values are compared. If
compare_types is True (default), then Constant values must have
the same type and value to be equal. If compare_type is False,
then Constant values will compare equal if the type Python objects
are equal regardless of type, e.g. 1.0 == 1.

compare_attributes affects whether AST attributes are considered
in the comparison. If compare_attributes is False (default), then
attributes are ignored. Otherwise they must all be equal. This
option is useful to look for asts that are structurally equal but
might differ in whitespace or similar details.
"""

def _compare(a, b):
Expand All @@ -427,7 +435,6 @@ def _compare(a, b):
a,
b,
compare_attributes=compare_attributes,
compare_fields=compare_fields,
compare_types=compare_types,
)
elif isinstance(a, list):
Expand Down Expand Up @@ -471,7 +478,7 @@ def _compare_attributes():
return False
# a and b are guaranteed to have the same type, so they must also
# have identical values for _fields and _attributes.
if compare_fields and not _compare_fields():
if not _compare_fields():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not _compare_fields():
if not _compare_fields(a, b):

return False
if compare_attributes and not _compare_attributes():
return False
Expand Down
6 changes: 0 additions & 6 deletions Lib/test/test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,12 +1170,6 @@ def parse(a, b):
self.assertTrue(ast.compare(a, b, compare_types=False))
self.assertFalse(ast.compare(a, b, compare_types=True))

a, b = parse("1", "2")
self.assertTrue(ast.compare(a, b, compare_fields=False, compare_attributes=False))
self.assertTrue(ast.compare(a, b, compare_fields=False, compare_attributes=True))
self.assertFalse(ast.compare(a, b, compare_fields=True, compare_attributes=False))
self.assertFalse(ast.compare(a, b, compare_fields=True, compare_attributes=True))

def test_positional_only_feature_version(self):
ast.parse('def foo(x, /): ...', feature_version=(3, 8))
ast.parse('def bar(x=1, /): ...', feature_version=(3, 8))
Expand Down
0