1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
==================================
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.
Invocation
==========
The exact way that we end up in our ``main`` function for Flake8 depends on
how you invoke it. If you do something like:
.. prompt:: bash
flake8
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
in its :file:`setup.py`. This might look something like:
.. code-block:: python
#!/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:
.. prompt:: bash
python -m flake8
Then you're relying on Python to find :mod:`flake8.__main__` and run that. In
both cases, however, you end up in :func:`flake8.main.cli.main`. This is the
primary way that users will end up starting Flake8. This function creates an
instance of |Application|.
Application Logic
=================
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
:meth:`~flake8.main.application.Application.run` which in turn calls:
- :meth:`~flake8.main.application.Application.initialize`
- :meth:`~flake8.main.application.Application.run_checks`
- :meth:`~flake8.main.application.Application.report_errors`
- :meth:`~flake8.main.application.Application.report_benchmarks`
Our Git hook, however, runs these individually.
Application Initialization
--------------------------
:meth:`~flake8.main.application.Application.initialize` loads all of our
:term:`plugin`\ s, registers the options for those plugins, parses the
command-line arguments, makes our formatter (as selected by the user), makes
our :class:`~flake8.style_guide.StyleGuide` and finally makes our
:class:`file checker manager <flake8.checker.Manager>`.
Running Our Checks
------------------
:meth:`~flake8.main.application.Application.run_checks` then creates an
instance of :class:`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
:mod:`multiprocessing` **and** :option:`flake8 --jobs` is either ``auto`` or
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
:term:`violation`\ s in the main process. After the checks are done running,
we record the end time.
Reporting Violations
--------------------
Next, the application takes the violations from the file checker manager, and
feeds them through the :class:`~flake8.style_guide.StyleGuide`. This
relies on a :class:`~flake8.style_guide.DecisionEngine` instance to determine
whether the particular :term:`error code` is selected or ignored and then
appropriately sends it to the formatter (or not).
Reporting Benchmarks
--------------------
Finally, if the user has asked to see benchmarks (i.e., :option:`flake8
--benchmark`) then we print the benchmarks.
Exiting
=======
Once :meth:`~flake8.main.application.Application.run` has finished, we then
call :meth:`~flake8.main.application.Application.exit` which looks at how
many errors were reported and whether the user specified :option:`flake8
--exit-zero` and exits with the appropriate exit code.
.. Replacements
.. |Application| replace:: :class:`~flake8.main.application.Application`
|