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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
.. _configuration:
====================
Configuring Flake8
====================
Once you have learned how to :ref:`invoke <invocation>` |Flake8|, you will soon
want to learn how to configure it so you do not have to specify the same
options every time you use it.
This section will show you how to make
.. prompt:: bash
flake8
Remember that you want to specify certain options without writing
.. prompt:: bash
flake8 --select E123,W456 --enable-extensions H111
Configuration Locations
=======================
|Flake8| supports storing its configuration in your project in one of
``setup.cfg``, ``tox.ini``, or ``.flake8``.
Values set at the command line have highest priority, then those in the
project configuration file, and finally there are the defaults. However,
there are additional command line options which can alter this.
Project Configuration
---------------------
|Flake8| is written with the understanding that people organize projects into
sub-directories. Let's take for example |Flake8|'s own project structure
.. code::
flake8
├── docs
│ ├── build
│ └── source
│ ├── _static
│ ├── _templates
│ ├── dev
│ ├── internal
│ └── user
├── flake8
│ ├── formatting
│ ├── main
│ ├── options
│ └── plugins
└── tests
├── fixtures
│ └── config_files
├── integration
└── unit
In the top-level ``flake8`` directory (which contains ``docs``, ``flake8``,
and ``tests``) there's also ``tox.ini`` and ``setup.cfg`` files. In our case,
we keep our |Flake8| configuration in ``tox.ini``. Regardless of whether you
keep your config in ``.flake8``, ``setup.cfg``, or ``tox.ini`` we expect you
to use INI to configure |Flake8| (since each of these files already uses INI
as a format). This means that any |Flake8| configuration you wish to set needs
to be in the ``flake8`` section, which means it needs to start like so:
.. code-block:: ini
[flake8]
Each command-line option that you want to specify in your config file can
be named in either of two ways:
#. Using underscores (``_``) instead of hyphens (``-``)
#. Simply using hyphens (without the leading hyphens)
.. note::
Not every |Flake8| command-line option can be specified in the
configuration file. See :ref:`our list of options <options-list>` to
determine which options will be parsed from the configuration files.
Let's actually look at |Flake8|'s own configuration section:
.. code-block:: ini
[flake8]
ignore = D203
exclude = .git,__pycache__,docs/source/conf.py,old,build,dist
max-complexity = 10
This is equivalent to:
.. prompt:: bash
flake8 --ignore D203 \
--exclude .git,__pycache__,docs/source/conf.py,old,build,dist \
--max-complexity 10
In our case, if we wanted to, we could also do
.. code-block:: ini
[flake8]
ignore = D203
exclude =
.git,
__pycache__,
docs/source/conf.py,
old,
build,
dist
max-complexity = 10
This allows us to add comments for why we're excluding items, e.g.
.. code-block:: ini
[flake8]
ignore = D203
exclude =
# No need to traverse our git directory
.git,
# There's no value in checking cache directories
__pycache__,
# The conf file is mostly autogenerated, ignore it
docs/source/conf.py,
# The old directory contains Flake8 2.0
old,
# This contains our built documentation
build,
# This contains builds of flake8 that we don't want to check
dist
max-complexity = 10
.. note::
Following the recommended settings for
`Python's configparser <https://docs.python.org/3/library/configparser.html#customizing-parser-behaviour>`_,
|Flake8| does not support inline comments for any of the keys. So while
this is fine:
.. code-block:: ini
[flake8]
per-file-ignores =
# imported but unused
__init__.py: F401
this is not:
.. code-block:: ini
[flake8]
per-file-ignores =
__init__.py: F401 # imported but unused
.. note::
If you're using Python 2, you will notice that we download the
:mod:`configparser` backport from PyPI. That backport enables us to
support this behaviour on all supported versions of Python.
Please do **not** open issues about this dependency to |Flake8|.
.. note::
You can also specify ``--max-complexity`` as ``max_complexity = 10``.
This is also useful if you have a long list of error codes to ignore. Let's
look at a portion of a project's Flake8 configuration in their ``tox.ini``:
.. code-block:: ini
[flake8]
# it's not a bug that we aren't using all of hacking, ignore:
# F812: list comprehension redefines ...
# H101: Use TODO(NAME)
# H202: assertRaises Exception too broad
# H233: Python 3.x incompatible use of print operator
# H301: one import per line
# H306: imports not in alphabetical order (time, os)
# H401: docstring should not start with a space
# H403: multi line docstrings should end on a new line
# H404: multi line docstring should start without a leading new line
# H405: multi line docstring summary not separated with an empty line
# H501: Do not use self.__dict__ for string formatting
ignore = F812,H101,H202,H233,H301,H306,H401,H403,H404,H405,H501
They use the comments to describe the check but they could also write this as:
.. code-block:: ini
[flake8]
# it's not a bug that we aren't using all of hacking
ignore =
# F812: list comprehension redefines ...
F812,
# H101: Use TODO(NAME)
H101,
# H202: assertRaises Exception too broad
H202,
# H233: Python 3.x incompatible use of print operator
H233,
# H301: one import per line
H301,
# H306: imports not in alphabetical order (time, os)
H306,
# H401: docstring should not start with a space
H401,
# H403: multi line docstrings should end on a new line
H403,
# H404: multi line docstring should start without a leading new line
H404,
# H405: multi line docstring summary not separated with an empty line
H405,
# H501: Do not use self.__dict__ for string formatting
H501
Or they could use each comment to describe **why** they've ignored the check.
|Flake8| knows how to parse these lists and will appropriately handle
these situations.
Using Local Plugins
-------------------
.. versionadded:: 3.5.0
|Flake8| allows users to write plugins that live locally in a project. These
plugins do not need to use setuptools or any of the other overhead associated
with plugins distributed on PyPI. To use these plugins, users must specify
them in their configuration file (i.e., ``.flake8``, ``setup.cfg``, or
``tox.ini``). This must be configured in a separate INI section named
``flake8:local-plugins``.
Users may configure plugins that check source code, i.e., ``extension``
plugins, and plugins that report errors, i.e., ``report`` plugins.
An example configuration might look like:
.. code-block:: ini
[flake8:local-plugins]
extension =
MC1 = project.flake8.checkers:MyChecker1
MC2 = project.flake8.checkers:MyChecker2
report =
MR1 = project.flake8.reporters:MyReporter1
MR2 = project.flake8.reporters:MyReporter2
|Flake8| will also, however, allow for commas to separate the plugins for
example:
.. code-block:: ini
[flake8:local-plugins]
extension =
MC1 = project.flake8.checkers:MyChecker1,
MC2 = project.flake8.checkers:MyChecker2
report =
MR1 = project.flake8.reporters:MyReporter1,
MR2 = project.flake8.reporters:MyReporter2
These configurations will allow you to select your own custom reporter plugin
that you've designed or will utilize your new check classes.
If your package is installed in the same virtualenv that |Flake8| will run
from, and your local plugins are part of that package, you're all set; |Flake8|
will be able to import your local plugins. However, if you are working on a
project that isn't set up as an installable package, or |Flake8| doesn't run
from the same virtualenv your code runs in, you may need to tell |Flake8| where
to import your local plugins from. You can do this via the ``paths`` option in
the ``local-plugins`` section of your config:
.. code-block:: ini
[flake8:local-plugins]
extension =
MC1 = myflake8plugin:MyChecker1
paths =
./path/to
Relative paths will be interpreted relative to the config file. Multiple paths
can be listed (comma separated just like ``exclude``) as needed. If your local
plugins have any dependencies, it's up to you to ensure they are installed in
whatever Python environment |Flake8| runs in.
.. note::
These plugins otherwise follow the same guidelines as regular plugins.
|