Skip to content
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

Proposed changes to pyflakes's traversal code. #816

Open
edreamleo opened this issue Jul 9, 2024 · 1 comment
Open

Proposed changes to pyflakes's traversal code. #816

edreamleo opened this issue Jul 9, 2024 · 1 comment

Comments

@edreamleo
Copy link
Contributor

edreamleo commented Jul 9, 2024

I have spent many happy hours studying pyflakes and its tree traversal methods. This issue proposes several possible simplifications. It's fine with me if you aren't interested.

Overview

All the simplifications follow from these changes:

  • Eliminate the omit and _fieldsOrder kwargs and the _FieldsOrder class.
  • Add/change visitors to specify required traversal order.
  • Rename the visitors so that the visitor's names are the same as the corresponding Ast nodes.

With these changes, Checker.getNodeHandler becomes:

handler = getattr(self, node.__class__.__name__, self.visit)
handler(node)

There is no need for the _nodeHandlers cache because the new code creates no strings.

Only Checker.handleNode calls getNodeHandler so the code above may as well appear in-line.

Other changes

  • Eliminate iter_child_nodes.
  • Add a handleFields method:
def handleFields(self, node, fields):
    """Visit only the *given* children of node in the given order."""
    for field in fields:
        child = getattr(node, field, None)
        if isinstance(child, list):
            for item in child:
                if isinstance(item, ast.AST):
                    self.handleNode(item, node)
        elif isinstance(child, ast.AST):
            self.handleNode(child, node)

def visit(self, node):
    self.visitFields(node._fields)  # Or duplicate the code above to eliminate the call.
  • Add or change visitors to specify the required traversal order. Examples:
def arguments(self, node):
    # Visit all fields except 'defaults' and 'kw_defaults'.
    fields = ('posonlyargs', 'args', 'var arg', 'kwonlyargs', 'kwarg')
    self.handleFields(node, fields)

def DictComp(self, node):
    with self.in_scope(GeneratorScope):
        # Order matters.
        self.handleFields(node, ('generators', 'key', 'value'))
  • Eliminate Checker._unknown_handler. A new unit test would cover its absence.

Summary

These changes are merely suggestions. You can find the prototype code in the five PRs at ekr-fork-pyflakes. I'll happily make any changes you like in a real PR.

Eliminating kwargs invariably simplifies and generalizes code. For example, it would be straightforward to subclass the new traversal code. The new visitors increase the traversal's speed and make explicit the required traversal order of the visitor's children.

Edward

@edreamleo
Copy link
Contributor Author

I am going to close this issue for (justified) lack of interest.

@PyCQA PyCQA deleted a comment Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant