Visitors

Contains detailed technical documentation about how to write a visitor.

See also

Visitor is a well-known software engineering pattern: https://en.wikipedia.org/wiki/Visitor_pattern

Each visitor might work with one or many violations. Multiple visitors might work with the same violation.

graph TD V1[Visitor 1] --> EA[Violation A] V1[Visitor 1] --> EB[Violation B] V2[Visitor 2] --> EA[Violation A] V2[Visitor 2] --> EC[Violation C] V3[Visitor 3] --> EZ[Violation WPS]

Visitor relation with violations.

Visitors API

classDiagram BaseVisitor <|-- BaseFilenameVisitor BaseVisitor <|-- BaseNodeVisitor BaseVisitor <|-- BaseTokenVisitor NodeVisitor <|-- BaseNodeVisitor Protocol <|-- ConfigurationOptions

BaseNodeVisitor

Allows to store violations while traversing node tree.

BaseFilenameVisitor

Abstract base class that allows to visit and check module file names.

BaseTokenVisitor

Allows to check tokenize sequences.

The decision relies on what parameters you need for the task. It is highly unlikely that you will need two parameters at the same time. See Tutorial for more information about choosing a correct base class.

Conventions

Then you will have to write logic for your visitor. We follow these conventions:

  • Public visitor methods start with visit_, then comes the name of a token or node to be visited

  • All other methods and attributes should be protected

  • We try to separate as much logic from visit_ methods as possible, so they only route for callbacks that actually execute the checks

  • We place repeating logic into logic/ package to be able to reuse it

There are different examples of visitors in this project already.

Reference

class BaseVisitor(options, filename='stdin')[source]

Bases: object

Abstract base class for different types of visitors.

options

contains the options objects passed and parsed by flake8.

filename

filename passed by flake8, each visitor has a file name.

violations

list of violations

for the specific visitor.
classmethod from_checker(checker)[source]

Constructs visitor instance from the checker.

Each unique visitor class should know how to construct itself from the checker instance.

Generally speaking, each visitor class needs to eject required parameters from checker and then run its constructor with these parameters.

Return type:

BaseVisitor

add_violation(violation)[source]

Adds violation to the visitor.

Return type:

None

abstract run()[source]

Runs a visitor.

Each visitor should know what exactly it needs to do when it was told to run.

Return type:

None

class BaseNodeVisitor(options, tree, **kwargs)[source]

Bases: NodeVisitor, BaseVisitor

Allows to store violations while traversing node tree.

This class should be used as a base class for all ast based checkers. Method visit() is defined in NodeVisitor class.

tree

ast tree to be checked.

classmethod from_checker(checker)[source]

Constructs visitor instance from the checker.

Return type:

BaseNodeVisitor

visit(tree)[source]

Visits a node.

Modified version of ast.NodeVisitor.visit method. We need this to modify how visitors route.

Why? Because python3.8 now uses visit_Constant instead of old methods like visit_Num, visit_Str, visit_Bytes, etc.

Some classes do redefine this method to catch all nodes. This is valid.

Return type:

None

run()[source]

Recursively visits all ast nodes. Then executes post hook.

Return type:

None

class BaseFilenameVisitor(options, filename='stdin')[source]

Bases: BaseVisitor

Abstract base class that allows to visit and check module file names.

Has visit_filename() method that should be defined in subclasses.

stem

the last part of the filename. Does not contain extension.

stem: str
abstract visit_filename()[source]

Checks module file names.

Return type:

None

run()[source]

Checks module’s filename.

Skips modules that are checked as piped output. Since these modules are checked as a stdin input. And do not have names.

Return type:

None

class BaseTokenVisitor(options, file_tokens, **kwargs)[source]

Bases: BaseVisitor

Allows to check tokenize sequences.

file_tokens

tokenize.TokenInfo sequence to be checked.

classmethod from_checker(checker)[source]

Constructs tokenize based visitor instance from the checker.

Return type:

BaseTokenVisitor

visit(token)[source]

Runs custom defined handlers in a visitor for each specific token type.

Uses .exact_type property to fetch the token name. So, you have to be extra careful with tokens like -> and other operators, since they might resolve in just OP name.

Does nothing if handler for any token type is not defined.

Inspired by NodeVisitor class. :rtype: None

run()[source]

Visits all token types that have a handler method.

Return type:

None