Configure linter¶
This tutorial walks you through the steps to configure your linter. We will start from the code in the previous tutorial.
Warning
Gather code from the first Basic linter tutorial to follow along.
Update rule to use config¶
One of the rules in previous tutorial has a magic number which you might want to have customizable (e.g. by providing linter configuration via pyproject.toml
like ruff
⧉).
Let's do this by adjusting NameIsShort
rule first (leave rest of the file as is):
... # rest of the file
# Let's add one simple rule for fun
class NameIsShort(PyProjectNameLoader, code=4):
"""Checks if `name` is below `N` characters."""
def __init__(self):
# Always call base constructor
super().__init__()
self.max_name_length = 10
def check(self, value: lintkit.Value[str | None]) -> bool:
# Change 10 to attribute
return isinstance(value, str) and len(value) < self.max_name_length
def message(self, v: lintkit.Value | None) -> str:
return (
f"Field 'project.name' is too long ({len(v)} > {name_length} chars)"
)
Read on to see how to inject max_name_length
attribute without passing values to __init__
Tip
lintkit.rule.Rule
is instantiated by lintkit.run
call and no arguments are passed.
Update config¶
You will continue with previously define pyproject.toml
, add the following section to our linter:
Load and inject config¶
To load config of linter from pyproject.toml
one can use loadfig
⧉ project which is no dependency library loading tool section from pyproject.toml
.
You can install it with pip (or use your package manager like uv
⧉):
Tip
You can use any other config loading tool or write one yourself.
Now edit run.py
:
import sys
import loadfig
import lintkit
import rules
def main() -> None:
# Simply specify name of the tool
config: dict = loadfig.config("mylinter")
# Add `max_name_length` attribute to all rules
# Has to be run after `rules` are imported!
lintkit.registry.inject(
"max_name_length",
# None if the value was not defined
config.get("max_name_length", None),
)
# Run the linter with code inclusions and exclusions
exit_code = lintkit.run(
"pyproject.toml",
include_rules=config.get("include_rules", None),
exclude_rules=config.get("exclude_rules", None),
)
sys.exit(exit_code)
if __name__ == "__main__":
main()
Things you should note:
lintkit.registry.inject
allows you to register variables (or whole configs) so they are available to all ruleslintkit.run
gives you more flexibility (e.g. including or excluding code parts).
Note
Exclusions take precedence over inclusions. In our case, the only included rule will be effectively 4
.
Tip
You can use any other config loading tool or load the config directly using standard tomllib
library ⧉
Run¶
You can run the run.py
file once again, this time the output should be as follows:
Next steps¶
Check one of the following tutorials to learn more about what you can do with lintkit
:
- Previous basic tutorial showcasing
lintkit
capabilities - Advanced linter for Python code
- File linters