meaningless-name (SMP103)¶
Flags variables, parameters and attributes named with a placeholder word that says nothing about what they hold, such as
foo or baz. The words come from a list you can change.
Why is this bad?¶
A name is the only description a value carries at each place it is used. foo leaves the reader to find where it is
assigned, and then to learn what it is. A name for the contents, such as counts, answers that at once.
Example¶
1def load(payload: bytes) -> dict[str, int]:
2 foo = parse(payload)
3 return foo
1def load(payload: bytes) -> dict[str, int]:
2 counts = parse(payload)
3 return counts
Configuration¶
naming.meaningless-namesin[tool.simplint]: the words to report,foo,baz,quxandquuxby default. Words such asdata,result,valueortmpare left out: a parser’sfeed(data), afor key, value inloop or atmpdirectory reads well in context. A list replaces the default one, so a project that bans more words lists the defaults too.Example: configuration
pyproject.toml1[tool.simplint.naming] 2meaningless-names = ["foo", "baz", "tmp"]
1tmp = load()
What it does¶
Reported names are the ones the list holds, compared as whole names, so foo_count is not foo. A word matches in
lower case, or in upper case as a constant spells it, with or without leading or trailing underscores.
Active on¶
Variables: names bound by assignment,
forloops,with ... asand the walrus operator.Example: reported
1foo = 3Example: reported
1_FOO = 3Example: reported
1for foo in items: 2 print(foo)
Parameters of a function or a lambda.
Example: reported
1def scale(factor: float, foo: float) -> float: 2 return factor * foo
Exception and
matchnames: the nameexcept ... asand acasecapture binds.Example: reported
1try: 2 run() 3except OSError as foo: 4 print(foo)
Attributes a method declares:
self.name = ...in a method, orcls.name = ...in a classmethod.Example: reported
1class Cache: 2 def __init__(self) -> None: 3 self.foo = {}
Exceptions¶
Overrides: the parameters of a method decorated with
@overridekeep the names of the method they replace.Example: not reported
pyproject.toml1[project] 2requires-python = ">=3.12"
1from json import JSONEncoder 2from typing import override 3 4 5class Encoder(JSONEncoder): 6 @override 7 def default(self, foo: object) -> object: 8 return str(foo)
Dunder methods: the parameters of a method named with double underscores, such as
valuein__setitem__, keep the names of the protocol they implement.Example: not reported
pyproject.toml1[tool.simplint.naming] 2meaningless-names = ["value"]
1class Store: 2 def __setitem__(self, key: str, value: int) -> None: 3 self.items = {key: value}
Attributes written through other objects:
response.foo = ...names an attribute the code does not choose.Example: not reported
1def fill(response) -> None: 2 response.foo = b""
Names outside the list: a name that merely contains a listed word is a name with a meaning.
Example: not reported
1foo_count = load()Class names:
Foonames a class, which the rule does not check where it is defined, so aFoo = ...that rebinds one is not reported either.Example: not reported
1Foo = make_class()
Reporting¶
Each name is reported once per scope, at its first binding, as single-letter-name reports its names.
Ruff overlap¶
Ruff’s ambiguous-variable-name covers l, O and I
only. This rule covers a word list you choose, like pylint’s
disallowed-name.
Fix¶
No fix is offered, since a meaningful name cannot be derived from the code.
Other tools¶
flake8-variables-names reports placeholder names such as
dataas VNE002. Its strict option adds more words.wemake-python-styleguide reports a fixed list of blacklisted names as WPS110.
pylint reports the names in its disallowed-name list. That list defaults to placeholders such as
fooandbar, not words such asdata.