Skip to content

PY-DEAD0001 · unreferenced_private_function

Detect an undecorated private module function without project reference evidence.

This is a deterministic rule for python. Read its implementation.

Inspect module functions with one leading underscore and no decorator. Retain a function when another source location loads its name, accesses an attribute with the same name, or contains that name as a string for dynamic lookup. A recursive reference inside the candidate does not make an otherwise unreachable function live. Dunder hooks, methods, classes, public API, and decorated registrations are outside the rule. Ruff continues to own unused imports and local variables.

Each finding points to the definition and records the high-confidence private-function scope. The rule reuses the project AST prepared by the collector and performs no file read or second parse.

Dynamic lookup assembled from multiple strings and external consumers outside the scanned project cannot be proved. The rule prefers a false negative when any plausible project reference exists. Public library functions are deliberately excluded because repository-only analysis cannot know their consumers.

Bad

`def _obsolete(): ...` with no project reference produces one finding.
Good

_parse passed as a callback, module._parse(), and getattr(module, "_parse") retain the function. @router.register and public functions are outside the candidate set.

  • Generalizes Pylint W0238 unused-private-member
  • Cites “Vulture documentation”, unused function detection and confidence. Open reference
  • Cites “PEP 8, Style Guide for Python Code”, Public and Internal Interfaces. Open reference