No Quality Assurance (# noqa) is a computer programming directive by which a programmer can instruct errors to be ignored for a given line. The NOQA syntax is used in the Python programming language to instruct code inspection tools such as pycodestyle
, pyflakes
, and mccabe
to ignore errors can be directed to ignore specific errors.
The # noqa
syntax was originally used as # nopep8
to indicate that Flake should skip pep8 warnings for a particular line. Evolution to accommodate ignoring other, non-style-based warnings, lead to the more general # noqa
syntax. Simply put; the # noqa
directive means Don’t worry about errors generated by this line of code.
History & Evolution
The # noqa
directive lends itself to several use-cases including broad directives, specific error codes, and even multiple error codes. From the Flake8 documentation:
files that contain this line are skipped:
# flake8: noqa
- Lines that contain a
# noqa
comment at the end will not issue warnings. - You can ignore specific errors on a line with
# noqa: <error>
, e.g.,# noqa: E234
. - Multiple codes can be given, separated by a comma. The
noqa
token is case insensitive, the colon before the list of codes is required otherwise the part afternoqa
is ignored
Examples
Given its history, it seems fitting to illustrate Flake8 usage of the # noqa
directive. To get started, simply install the package as such:
$ pip install flake8
Watching the console output during installation, you might note the following dependencies being installed:
Succesfully installed flake8-x.x.x mccabe-x.x.x pycodestyle-x.x.x pyflakes-x.x.x
After which flake can be run against any module or directory when specified as an argument like this:
$ flake project $ flake project/module $ flake project/module/submodule
Let’s now consider an example of poorly-written Python code such that Flake8 might be used to generate some warnings. The following code contains 8 errors, can you spot them?
import os def foo(): pass def foo(): pass x=5 print("46 equals 2 = ", 46 == 2)
In this very contrived example, there are some immediately obvious issues. For one, the foo function is defined twice. The others are more subtle however and might not jump out immediately. That’s where code inspection tools come in handy. By running the $ flake8 file.py
command the following output is produced:
file.py:1:1: F401 'os' imported but unused file.py:6:1: W293 blank line contains whitespace file.py:7:1: E302 expected 2 blank lines, found 1 file.py:7:1: F811 redefinition of unused 'foo' from line 4 file.py:9:1: W293 blank line contains whitespace file.py:10:1: E305 expected 2 blank lines after class or function definition, found 1 file.py:10:2: E225 missing whitespace around operator file.py:12:33: W292 no newline at end of file
To illustrate the usage of the # noqa
operator, consider the code from above again—but this time with general and specific # noqa
declarations:
import os # noqa: F401 used for comfort only def foo(): pass def foo(): # noqa pass x=5 # noqa: E225 print("46 equals 2 = ", 46 == 2)
In this example, three unique # noqa
directives have been declared. The new output when running the $ flake8 new_file.py
command is as follows:
newfile.py:6:1: W293 blank line contains whitespace newfile.py:9:1: W293 blank line contains whitespace newfile.py:10:1: E305 expected 2 blank lines after class or function definition, found 1 newfile.py:10:4: E261 at least two spaces before inline comment newfile.py:12:33: W292 no newline at end of file
The # noqa
directive removed warnings for the lines in which it was included! In this extremely contrived example, it’s difficult to imagine practical uses of such directives. However, flake (and other common code inspection tools) can be useful in the followings cases:
- Including a module just for the purposes of documentation
- Ignoring line-formatting for the construction of strings
- Ignoring line-length errors if preferred (not recommended)
- Project-required actions before module-level imports
- Other crazy sh*t that only your project requires
Flake8 also supports pre-commit hooking to ensure that all code has been inspected prior to version control commits. See more here.
The examples from this article are available on GitHub.
IDE Support
Flake8, Pylint, and similar tools aren’t always accommodated by popular IDEs such as IntelliJ and VisualStudio. However, the popularity of these tools has directed the development of IDE-specific code-inspection tools that share many of the same features.
For example, Jetbrains’ PyCharm contains a code-inspection toolset that allows for use of the # noqa
syntax alongside their more novel syntax systems. You can use the # noqa directive to specify both flake8
and pycodestyle
error codes. In addition, Many IDEs like PyCharm allow configuration within their own settings frameworks to limit warning levels, warning types, and even the presentation of warnings.
Discussion
Code inspection tools are useful in helping to ensure efficiency and interoperability. Just because you know how something works doesn’t mean the next developer will be able to discern such. Ensuring code conforms—as closely as is practically allowable—to common convention helps harbor interoperability.
The #noqa directive is particularly useful in informing code inspectors to ignore specific lines. This allows developers to do things that might not make sense to a code inspector, but make sense for the project. The flake8 module will provide access to these tools as will most modern IDEs like PyCharm.