FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

bpo-15987: Add ast.AST class richcompare methods by louisom · Pull Request #1368 · python/cpython · GitHub

Repository navigation

bpo-15987: Add ast.AST class richcompare methods - #1368

Closed
louisom wants to merge 13 commits into
python:masterfrom
louisom:bpo-15987-compare-ast-nodes
Closed

louisom wants to merge 13 commits into
python:masterfrom
louisom:bpo-15987-compare-ast-nodes

Conversation

louisom commented May 1, 2017 •
edited by vstinner
Loading

Copy link
Copy Markdown
Contributor

This will not compare with attributes, but fields and types.

https://bugs.python.org/issue15987

serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I don't know whether it is good idea to implement the comparison of AST nodes, but added technical comments to the implementation.

Comment thread Lib/ast.py Outdated

def ast_eq_compare(a, b):
if type(a) != type(b):
return False

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
return NotImplemented

This will allow other classes implement the comparison with AST nodes.

Comment thread Lib/ast.py Outdated
if type(a) != type(b):
return False
if type(a) not in _NODES:
return a == b

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Isn't this recursive?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We may recursive to a builtin-type value, then can return compare fast.

Comment thread Lib/ast.py Outdated

ret = True
for field in a._fields:
af = vars(a)[field]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why not getattr?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Thanks for point out.

Comment thread Lib/ast.py Outdated
if type(a) not in _NODES:
return a == b

ret = True

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Actually this isn't needed. See below.

Comment thread Lib/ast.py Outdated
if len(af) != len(bf):
return False
for i, j in zip(af, bf):
ret &= ast_eq_compare(i, j)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Fail fast.

if i != j:
    return False

But stop, why not compare just lists?

if af != bf:
    return False

louisom May 2, 2017 •
edited
Loading

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

No, you can't simply compare these, _ast.KEYWORDS's fields value will be builtin-type or [_ast.KEYWORDS] (e.g. [<_ast.Expr object at 0x7f06659c8468>]), since the compare method doesn't hook up yet, you can't simply compare a list with _ast.KEYWORDS.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Thus we will need to recursively to compare the items.

Comment thread Lib/ast.py Outdated

for n in _NODES:
n.__eq__ = ast_eq_compare
n.__ne__ = ast_ne_compare

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This isn't needed. The default implementation falls back to __eq__

Comment thread Lib/ast.py Outdated


for n in _NODES:
n.__eq__ = ast_eq_compare

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why not patch just the base class?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@serhiy-storchaka You are right, I thought is was difficult or not possible when implementing a top-down richcompare, but I'm wrong.

re-implement the richcompare inside the AST_type

Comment thread Lib/ast.py Outdated

# Add EQ and NE compare to _ast Nodes
_NODES = [vars(_ast)[k] for k in filter(
lambda x: not x.startswith('_') and x not in ('AST' 'PyCF_ONLY_AST'), vars(_ast))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

'ASTPyCF_ONLY_AST' is the single literal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Change to ('AST', 'PyCF_ONLY_AST')

Comment thread Lib/ast.py Outdated


# Add EQ and NE compare to _ast Nodes
_NODES = [vars(_ast)[k] for k in filter(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Don't use filter and lambda. Use just if in the list comprehension.

Comment thread Lib/ast.py Outdated


# Add EQ and NE compare to _ast Nodes
_NODES = [vars(_ast)[k] for k in filter(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Rather than calling vars() multiple times just iterate vars(_ast).items().

brettcannon added the type-feature A feature request or enhancement label May 1, 2017

louisom commented May 2, 2017

Copy link
Copy Markdown
Contributor Author

I'm not sure why travis failed on clang and gcc, my local build run pass the test.

louisom commented May 2, 2017

Copy link
Copy Markdown
Contributor Author

@Haypo point out that I shouldn't change Python/Python-ast.c, it should be generated by asdl_c.py

louisom changed the title bpo-15987: Add AST nodes eq & ne compare methods bpo-15987: Add ast.AST class richcompare methods May 2, 2017

Copy link
Copy Markdown
Contributor

hi, this PR has been open for some time and the discussion in https://bugs.python.org/issue15987 is inconclusive.
Please can the team review this BPO

Copy link
Copy Markdown
Member

cc @methane

Copy link
Copy Markdown
Member

@louisom: Can you rebase this PR on master?

Copy link
Copy Markdown
Contributor

@vstinner the original branch no longer exists, GH shows it as "unknown repository", but it means the branch or the user no longer exist.

The only way to merge this would be to recreate the patch elsewhere.

Copy link
Copy Markdown
Member

@vstinner the original branch no longer exists, GH shows it as "unknown repository", but it means the branch or the user no longer exist.

https://github.com/louisom user still exists. I understand that he deleted its fork of CPython.

It's possible to download this PR as a patch using the URL:
https://patch-diff.githubusercontent.com/raw/python/cpython/pull/1368.patch

Is there someone interested to convert this old PR into a newer PR?

flavianh commented Jul 20, 2019 •
edited
Loading

Copy link
Copy Markdown

@vstinner I can try!

Copy link
Copy Markdown

@vstinner Recreated at #14970

Copy link
Copy Markdown
Contributor

Closing this pull request as it has been recreated under a different pull request.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants


Back | FazBrowse Home | New Git URL