-
-
Notifications
You must be signed in to change notification settings - Fork 818
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor[lang]: remove VyperNode
__hash__()
and __eq__()
implemen…
…tations (#4433) it is a performance and correctness footgun for `VyperNode`'s hash and eq implementations to recurse. for instance, two nodes from different source files should never compare equal. several tests rely on the recursive behavior of the eq implementation; a utility function `deepequals()` is added in this PR so that tests can perform the recursive check on AST nodes where needed. nowhere in the compiler itself (`vyper/` directory) is the recursive definition relied on. this commit also slightly refactors the import analyzer so that uses the new hash and eq implementations instead of the previous workaround to avoid recursion (which was to use `id(module_ast)`.
- Loading branch information
1 parent
f444c8f
commit 9b5523e
Showing
7 changed files
with
43 additions
and
30 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from vyper.ast.nodes import VyperNode | ||
|
||
|
||
def deepequals(node: VyperNode, other: VyperNode): | ||
# checks two nodes are recursively equal, ignoring metadata | ||
# like line info. | ||
if not isinstance(other, type(node)): | ||
return False | ||
|
||
if isinstance(node, list): | ||
if len(node) != len(other): | ||
return False | ||
return all(deepequals(a, b) for a, b in zip(node, other)) | ||
|
||
if not isinstance(node, VyperNode): | ||
return node == other | ||
|
||
if getattr(node, "node_id", None) != getattr(other, "node_id", None): | ||
return False | ||
for field_name in (i for i in node.get_fields() if i not in VyperNode.__slots__): | ||
lhs = getattr(node, field_name, None) | ||
rhs = getattr(other, field_name, None) | ||
if not deepequals(lhs, rhs): | ||
return False | ||
return True |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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