possibly-used-before-assignment / E0606ΒΆ
Message emitted:
Possibly using variable %r before assignment
Description:
Emitted when a local variable is accessed before its assignment took place in both branches of an if/else switch.
Problematic code:
def check_lunchbox(items: list[str]):
if not items:
empty = True
print(empty) # [possibly-used-before-assignment]
Correct code:
def check_lunchbox(items: list[str]):
empty = False
if not items:
empty = True
print(empty)
Additional details:
You can use assert_never
to mark exhaustive choices:
from typing import assert_never
def handle_date_suffix(suffix):
if suffix == "d":
...
elif suffix == "m":
...
elif suffix == "y":
...
else:
assert_never(suffix)
if suffix in "dmy":
handle_date_suffix(suffix)
Or, instead of assert_never(), you can call a function with a return annotation of Never or NoReturn. Unlike in the general case, where by design pylint ignores type annotations and does its own static analysis, here, pylint treats these special annotations like a disable comment.
Pylint currently allows repeating the same test like this, even though this lets some error cases through, as pylint does not assess the intervening code:
if guarded():
var = 1
# what if code here affects the result of guarded()?
if guarded():
print(var)
But this exception is limited to the repeating the exact same test. This warns:
if guarded():
var = 1
if guarded() or other_condition:
print(var) # [possibly-used-before-assignment]
If you find this surprising, consider that pylint, as a static analysis
tool, does not know if guarded()
is deterministic or talks to
a database. For constants (e.g. guarded
versus guarded()
),
this is less of an issue, so in this case,
possibly-used-before-assignment
acts more like a future-proofing style
preference than an error, per se.
Created by the variables checker.