What Happens When You Run Flake8¶
Given Flake8 3.0’s new organization and structure, it might be a bit much
for some people to understand what happens from when you call
flake8 on the
command-line to when it completes. This section aims to give you something of
a technical overview of what exactly happens.
The exact way that we end up in our
main function for Flake8 depends on
how you invoke it. If you do something like:
Then your shell looks up where
flake8 the executable lives and executes
it. In almost every case, this is a tiny python script generated by
setuptools using the console script entry points that Flake8 declares
setup.py. This might look something like:
#!/path/to/python<version> # EASY-INSTALL-ENTRY-SCRIPT: 'flake8==3.0.0','console_scripts','flake8' __requires__ = 'flake8==3.0.0' import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.exit( load_entry_point('flake8==3.0.0', 'console_scripts', 'flake8')() )
If instead you invoke it like:
python -m flake8
Then you’re relying on Python to find
flake8.__main__ and run that. In
both cases, however, you end up in
flake8.main.cli.main(). This is the
primary way that users will end up starting Flake8. This function creates an
When we create our
Application instance, we record the start time and parse
our command-line arguments so we can configure the verbosity of Flake8’s
logging. For the most part, every path then calls
run() which in turn calls:
Our Git hook, however, runs these individually.
initialize() loads all of our
plugins, registers the options for those plugins, parses the
command-line arguments, makes our formatter (as selected by the user), makes
StyleGuide and finally makes our
file checker manager.
Running Our Checks¶
run_checks() then creates an
flake8.checker.FileChecker for each file to be checked
after aggregating all of the files that are not excluded and match the
provided file-patterns. Then, if we’re on a system that supports
flake8 --jobs is either
a number greater than 1, we will begin processing the files in subprocesses.
Otherwise, we’ll run the checks in parallel.
After we start running the checks, we start aggregating the reported violations in the main process. After the checks are done running, we record the end time.
Next, the application takes the violations from the file checker manager, and
feeds them through the
relies on a
DecisionEngine instance to determine
whether the particular error code is selected or ignored and then
appropriately sends it to the formatter (or not).
Finally, if the user has asked to see benchmarks (i.e.,
--benchmark) then we print the benchmarks.
run() has finished, we then
exit() which looks at how
many errors were reported and whether the user specified
--exit-zero and exits with the appropriate exit code.