PEP 8, section by section

PEP 8 Programming Recommendations: is None, Bare except, Lambdas and Other Habits

PEP 8, section by section · · Published 2026-10-27

A cluttered bicycle workshop with a wheel on a truing stand, spare parts on the bench and tools hanging on a pegboard
A bicycle workshop with a wheel truing stand and tools on a pegboard. Photo: Foxtod, CC0.

The last major section of PEP 8 is different from the rest. Instead of spaces and line lengths, it collects habits that make Python code more correct and easier to reason about. Several of them are checked by linters; all of them are worth understanding, because the reasons matter more than the rule.

All examples below were run with Python 3.13.

Comparisons to None and other singletons

"Comparisons to singletons like None should always be done with is or is not, never the equality operators." The reason is that == calls the object's __eq__ method, which a class can define however it likes, while is checks identity and cannot be overridden:

class Anything:
    def __eq__(self, other):
        return True


value = Anything()
print(value == None)
print(value is None)
True
False

pycodestyle reports == None as E711 and comparisons with True or False as E712. PEP 8 also prefers if foo is not None: to if not foo is None: (E714), and if x not in y to if not x in y (E713): the two forms behave identically, but the first reads like the sentence it means.

Truthiness, and when not to rely on it

For sequences, PEP 8 recommends using the fact that empty ones are false: if not seq: rather than if len(seq) == 0:. Likewise, do not compare Booleans to True or False: write if greeting:, not if greeting == True:, and certainly not if greeting is True:, which the guide calls worse.

The same section adds a warning in the other direction: beware of writing if x when you really mean if x is not None. A parameter that defaults to None may receive a value that is itself false:

count = 0
if count:
    print("set")
if count is not None:
    print("count was provided")
count was provided

Zero, an empty string or an empty list are real values. If the question is "was an argument passed?", test against None.

Name functions with def, not lambda

"Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier." A lambda's only advantage is that it can be written inside a larger expression; once you assign it to a name, that advantage is gone, and you lose a useful name in tracebacks and in the function's representation:

square = lambda x: x * x


def cube(x):
    return x ** 3


print(square.__name__, cube.__name__)
<lambda> cube

pycodestyle reports the assignment as E731. Lambdas remain perfectly idiomatic as arguments, for example sorted(rows, key=lambda row: row.date).

Exceptions: specific, small and chained

PEP 8 has several recommendations about exceptions, and they work together.

def lookup(table, key):
    try:
        value = table[key]
    except KeyError:
        return None
    else:
        return value.upper()


print(lookup({"a": "x"}, "a"), lookup({}, "b"))
X None

If value.upper() raised a KeyError of its own, it would not be mistaken for a missing key.

Do not return from finally

PEP 8 discourages return, break or continue inside a finally block when they would jump out of it, because they silently cancel any exception in flight:

def risky():
    try:
        1 / 0
    finally:
        return 42


print(risky())
42

The ZeroDivisionError simply disappears. PEP 765, implemented in Python 3.14, makes the compiler emit a SyntaxWarning for this pattern.

Be consistent in return statements

"Either all return statements in a function should return an expression, or none of them should." If one path returns a value, the others should say return None explicitly, and a function that can fall off the end should end with an explicit return. A reader then knows that None is a deliberate result, not a forgotten branch. pylint reports violations as inconsistent-return-statements.

Prefer the explicit method

Annotations

The section ends with style rules for function and variable annotations: follow PEP 484 syntax, put a single space after the colon and none before it, and spaces around = when an annotated name has a default. Our guide to type hints covers the rest.

Where tools help

The checker on our home page reports E711, E712, E713, E714, E721, E722 and E731. Inconsistent returns, overly broad try blocks and the misuse of truthiness need a linter with more semantic analysis, such as pylint, or a human reviewer; our code review checklist includes them.

Sources