opennudge Python linter (naming conventions and other automated checks)
β¨ Features π Quick start π Documentation π€ Contribute π Adopters π Legal
pynudger is an opinionated linter for Python projects, focused on naming conventions and making your code "more Pythonic".
- Length rules: Too long class/function names are flagged.
- Setters/getters: Discourages usage of setters/getters, encourages properties instead.
- No helpers/utils/commons/shared names: Incentivizes more descriptive and semantically coherent names for functionalities.
> pip install pynudgerTo check against the rules run the following from the command line:
> pynudger checkYou can pass additional arguments to pynudger check, like files
to check (by default all Python files in the current directory):
> pynudger check path/to/file.py another_file.pyYou can configure pynudger in pyproject.toml (or .pynudger.toml
in the root of your project, just remove the [tool.pynudger] section),
for example:
[tool.pynudger]
# include rules by their code
include_codes = [1, 2, 5] # default: all rules included
# exclude rules by their code (takes precedence over include)
exclude_codes = [4, 5, 6] # default: no rules excluded
# whether to exit after first error or all errors
end_mode = "first" # default: "all"Tip
Rule-specific configuration can be found in the section below.
pynudger can be used as a pre-commit hook, to add as a plugin:
repos:
- repo: "https://github.com/open-nudge/pynudger"
rev: ... # select the tag or revision you want, or run `pre-commit autoupdate`
hooks:
- id: "pynudger"You can disable pynudger on a line-by-line basis
(you have to specify exact code), e.g.:
def set_my_too_long_function_name(): # noqa: PYNUDGER0, PYNUDGER19
passor a line span:
# noqa-start: PYNUDGER0, PYNUDGER19
def set_my_too_long_function_name():
pass
def set_another_long_function():
pass
# noqa-end: PYNUDGER0, PYNUDGER19
def set_will_error_out_this_time():
passIt is also possible to disable all checks in a file by placing the following somewhere in the file (preferably at the top):
# noqa-file: PYNUDGER0, PYNUDGER19Note
If you are running pynudger with
ruff you should add
lint.external = ["PYNUDGER"] to [tool.ruff] section in
pyproject.toml to avoid removing # noqa: PYNUDGER comments.
Tip
Run pynudger rules to see the list of available rules.
pynudger provides the following rules:
| Name | Description |
|---|---|
PYNUDGER0 |
Avoid using setters in class names. Use properties instead. |
PYNUDGER1 |
Avoid using setters in function names. Use properties instead. |
PYNUDGER2 |
Avoid using setters in file names. Define file name without it. |
PYNUDGER3 |
Avoid using getters in class names. Use properties instead. |
PYNUDGER4 |
Avoid using getters in function names. Use properties instead. |
PYNUDGER5 |
Avoid using getters in file names. Define file name without it. |
PYNUDGER6 |
Avoid using utils in class names. Name the class appropriately. |
PYNUDGER7 |
Avoid using utils in function names. Name the function appropriately. |
PYNUDGER8 |
Avoid defining utils modules. Move functionality to appropriate modules. |
PYNUDGER9 |
Avoid using helpers in class names. Name the class appropriately. |
PYNUDGER10 |
Avoid using helpers in function names. Name the function appropriately. |
PYNUDGER11 |
Avoid defining utils modules. Move functionality to appropriate modules. |
PYNUDGER12 |
Avoid using common in class names. Name the class appropriately. |
PYNUDGER13 |
Avoid using common in function names. Name the function appropriately. |
PYNUDGER14 |
Avoid defining common modules. Move functionality to appropriate modules. |
PYNUDGER15 |
Avoid using shared in class names. Name the class appropriately. |
PYNUDGER16 |
Avoid using shared in function names. Name the function appropriately. |
PYNUDGER17 |
Avoid defining shared modules. Move functionality to appropriate modules. |
PYNUDGER18 |
Avoid long class names. Specify intent by nesting modules/packages. |
PYNUDGER19 |
Avoid long function names. Specify intent by nesting modules/packages. |
PYNUDGER20 |
Avoid long path names. Specify intent by nesting modules/packages. |
PYNUDGER21 |
Avoid restricted state management keywords: del, global, nonlocal. |
PYNUDGER22 |
Avoid restricted iteration keywords: break, continue. |
PYNUDGER23 |
Avoid restricted compatibility functionality: object, basestring, unicode, long. |
PYNUDGER24 |
Avoid restricted utility/interactive functions: breakpoint, help, id. |
PYNUDGER25 |
Avoid restricted explicit casting functionality: typing.cast, cast, bool, float, int, str. |
PYNUDGER26 |
Avoid restricted insecure builtin functions: exec, eval, compile. |
PYNUDGER27 |
Avoid restricted explicit iteration: iter, aiter, anext, next. |
PYNUDGER28 |
Avoid restricted attribute manipulation: delattr, getattr, hasattr, setattr, globals, locals, vars, dir. |
PYNUDGER29 |
Avoid restricted explicit dunder access: attributes starting with __. |
PYNUDGER30 |
Avoid returning empty strings. Return None to indicate lack of value. |
PYNUDGER31 |
Avoid more than assert statements in pytest tests. Keep each test focused. |
PYNUDGER32 |
Avoid modules with more than total lines. Split code into focused modules. |
PYNUDGER33 |
Avoid modules with more than code lines. Split code into focused modules. |
PYNUDGER34 |
Avoid undocumented function parameters. Add an Args: docstring section. |
PYNUDGER35 |
Avoid undocumented generator yields. Add a Yields: docstring section. |
PYNUDGER36 |
Avoid undocumented return values. Add a Returns: docstring section. |
PYNUDGER37 |
Avoid small, rarely used internal functions. |
PYNUDGER38 |
Avoid small, rarely used internal classes. |
PYNUDGER39 |
Avoid small, rarely used internal methods. |
PYNUDGER40 |
Avoid repeating module names in variables. |
PYNUDGER41 |
Avoid repeating module names in classes. |
PYNUDGER42 |
Avoid repeating module names in functions. |
PYNUDGER43 |
Group globals with shared name words under modules. |
PYNUDGER44 |
Avoid pipe type unions with more than the configured number of members. |
PYNUDGER45 |
Avoid deeply nested types. |
PYNUDGER46 |
Avoid modules with fewer than objects. Move them into other modules. |
with the following configurable options (in pyproject.toml
or .pynudger.toml):
| Option | Description | Affected rules | Default |
|---|---|---|---|
pascal_length |
Maximum allowed length of PascalCase names | PYNUDGER18 | 3 |
snake_length |
Maximum allowed length of snake_case names | PYNUDGER19, PYNUDGER20 | 3 |
pascal_excludes |
List of words to exclude from PascalCase length check | PYNUDGER18 | [] |
snake_excludes |
List of words to exclude from snake_case length check | PYNUDGER19, PYNUDGER20 | [] |
maximum_test_asserts |
Maximum number of assert statements in pytest tests |
PYNUDGER31 | 1 |
max_module_lines |
Maximum number of any lines in a Python module | PYNUDGER32 | 600 |
max_module_code_lines |
Maximum number of code lines in a Python module | PYNUDGER33 | 200 |
minimum_module_objects |
Minimum assignment names, classes, and functions in a module | PYNUDGER46 | 3 |
minimum_internal_function_usages |
Minimum same-file usages for internal functions | PYNUDGER37 | 2 |
minimum_internal_function_lines |
Minimum code lines for internal functions | PYNUDGER37 | 5 |
minimum_internal_class_usages |
Minimum same-file usages for internal classes | PYNUDGER38 | 2 |
minimum_internal_class_lines |
Minimum code lines for internal classes | PYNUDGER38 | 5 |
minimum_internal_method_usages |
Minimum same-file usages for internal methods | PYNUDGER39 | 2 |
minimum_internal_method_lines |
Minimum code lines for internal methods | PYNUDGER39 | 5 |
minimum_same_name_occurrences |
Minimum declarations sharing a name word | PYNUDGER43 | 2 |
max_union_types |
Maximum members in a pipe type union | PYNUDGER44 | 3 |
max_type_depth |
Maximum nested type subscript depth | PYNUDGER45 | 1 |
dir_ignores |
List of (sub)directories to be excluded in case no files are provided | ALL | ["__pypackages__", ".venv", ".git", "__pycache__"] |
extend_dir_ignores |
Additional (sub)directories to ignore, extending the default ignores | ALL | [] |
PYNUDGER46 does not check package __init__.py files.
We welcome your contributions! Start here:
- This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
- This project is copyrighted by open-nudge - the appropriate copyright notice is included in each file.