NOQA: Simple PEP8 Warning Suppression

noqa python

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 after noqa 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:

  1. Including a module just for the purposes of documentation
  2. Ignoring line-formatting for the construction of strings
  3. Ignoring line-length errors if preferred (not recommended)
  4. Project-required actions before module-level imports
  5. 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.

Zαck West
Full-Stack Software Engineer with 10+ years of experience. Expertise in developing distributed systems, implementing object-oriented models with a focus on semantic clarity, driving development with TDD, enhancing interfaces through thoughtful visual design, and developing deep learning agents.