Extensible and customizable file formatter with reading (me) friendly defaults.
Project description
cleer
cleer is a file formatter that is customizable and easy to extend.
It was primarily made for python (in python), but can work with any language.
It has a set of defaults that I have chosen for a specific and readable style. It does not try to make the smallest git diffs, but he most readable code in general. Objectively speaking of course (I like the formatting).
Installation
pip install cleer
Tutorial
Quickstart
Out of the box it comes with a CLI.
Use --helpon the base or any commands for all options.
cleer --help
It has 2 main commands:
- inspect - JSON output of the formatting violations
- format - format files in place
You can use them both on a single file or a all files/dirs in a directory.
cleer inspect path/to/file.py
cleer inspect path/to/dir/
Output example for inspect:
[
{
"path": "/full/path/to/file.py",
"violations": [
{
"start_index": 49,
"length": 22,
"message": "Lines should not have any trailing whitespace."
}
]
}
]
Format files in place:
cleer format path/to/file.py
Inspect or format with specific config and log level
cleer format --log-level DEBUG --cleer python_path.to.my_file:my_cleer_instance path/to/file.py
Formatters for python packages are recommended to create a clr.py file in the root of the project.
If the package can by imported as "my_package", and you just want the default formatting:
"""clr.py"""
from cleer import cleer_default
clr = cleer_default(current_packages=["my_package"])
This will ensure that imports are properly grouped and sorted.
Configuration
The chain of configuration is as follows:
- If a custom cleer instance is given with the
--cleerargument. - The default python path of
clr:clr. - A default configuration is generated.
Example of custom Cleer instance/config:
from cleer import *
# use the defaults with minimal input
clr = cleer_default(current_packages=["my_package"], internal_packages=["my_other_private_package"])
# create your own config from scratch
clr = Cleer(
config={
"groups": [ # Groups are collections of formatting stages
{
"includes": ["**/*.py"], # A group uses glob style include and exclude patterns to determine which files be collected
"excludes": [
"**/.venv*/**",
"**/venv*/**"
],
"stages": [ # stages are run in serial to format or inspect documents
{
"tokenizer": LineTokenizer(), # each stage has a tokenizer, that will tokenize and iterate through the tokens
"formatters": [ # formatters are all run in order on each token.
TrailingWhitespaceFormatter(),
]
}
]
}
]
}
)
Logging
cleer uses standard python logging levels. By default it is set to CRITICAL. You can change this with the --log-level argument.
DEBUGINFOWARNINGERRORCRITICAL
Run with VSCode
You can automatically format on save in vscode by installing the (Run On Save)[https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave] extension and adding a config like this under .vscode/settings.json:
{
"emeraldwalk.runonsave": {
"commands": [
{
"cmd": "./venv/bin/cleer format --log-level DEBUG ${file}"
}
]
}
}
Update the path to cleer to where ever you installed cleer at.
Programmatic API
The cleer CLI is a thin wrapper around the Cleer class.
You can directly call different inspect and format options on the Cleer class instance.
import pathlib
from cleer import *
# get a default instance, set some configs
clr = cleer_default(current_packages=["my_package"], internal_packages=["my_internal_pkg"])
# Or create your own instance from scratch
clr = Cleer(
config={
"groups": [
{
"includes": ["**/*.py"],
"excludes": [
"**/.venv*/**",
"**/venv*/**"
],
"stages": [
{
"tokenizer": LineTokenizer(),
"formatters": [
TrailingWhitespaceFormatter(),
]
}
]
}
]
}
)
# inspect a document string for violations
violations = clr.inspect_str("x = 1 \n", "my_pkg/thing.py")
# note that even for strings you have to pass a "file name"
# this is so that the "file" can be picked up by the matching config groups.
# [
# {
# "start_index": 29,
# "length": 20,
# "message": "Lines should not have any trailing whitespace."
# }
# ]
# inspect a file pointer
with open("thing.py", "r") as fp:
violations = clr.inspect_fp(fp, "my_pkg/thing.py")
# note that even for strings you have to pass a "file name"
# this is so that the "file" can be picked up by the matching config groups.
# [
# {
# "start_index": 29,
# "length": 20,
# "message": "Lines should not have any trailing whitespace."
# }
# ]
# inspect a file by path
violations = clr.inspect_file("my_pkg/thing.py")
# [
# {
# "start_index": 29,
# "length": 20,
# "message": "Lines should not have any trailing whitespace."
# }
# ]
# inspect all matching files in a directory
results = clr.inspect_dir(pathlib.Path("./"))
# [
# {
# "path": "my_pkg/thing.py",
# "violations": [
# {
# "start_index": 29,
# "length": 20,
# "message": "Lines should not have any trailing whitespace."
# }
# ]
# }
# ]
# inspect a path (file or directory, auto-detected)
# this is what is used by the CLI to take either
results = clr.inspect_path("my_pkg/")
# for files, one entry at most will be returned.
# [
# {
# "path": "my_pkg/thing.py",
# "violations": [
# {
# "start_index": 29,
# "length": 20,
# "message": "Lines should not have any trailing whitespace."
# }
# ]
# }
# ]
# format a document string (returns the formatted string)
formatted = clr.format_str("x = 1 \n", "my_pkg/thing.py")
# format a file pointer in place
with open("thing.py", "r+") as fp:
clr.format_fp(fp, "my_pkg/thing.py")
# format a file in place by path
clr.format_file("my_pkg/thing.py")
# format all matching files in a directory in place
clr.format_dir(pathlib.Path("./"))
# format a path (file or directory, auto-detected)
# this is what is used by the CLI to take either
clr.format_path("my_pkg/")
Changelog
Changelog for cleer.
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.1.0a2] - 2026-07-20
Initial Release
[0.1.0a1] - 2024-02-18
Initial stub
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cleer-0.1.0a2.tar.gz.
File metadata
- Download URL: cleer-0.1.0a2.tar.gz
- Upload date:
- Size: 63.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97771184b4456b2d70121d8d02ff788f1e9b22a88196571f906d61cf563778ee
|
|
| MD5 |
b2398a58cbc3750c5727e04593c81454
|
|
| BLAKE2b-256 |
713e1a92d8e90db962808c9e66c989734a9f5455bfb524516bcb96ba524fc4b3
|
File details
Details for the file cleer-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: cleer-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 108.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c417a3cda82595ce3b18a716a90490245e05f01a79b9164847b14e542ab7928
|
|
| MD5 |
94c8b028a9f6f2c1ebb0c56a3e6b3e3d
|
|
| BLAKE2b-256 |
1491fed30b18e294455530050c2cfd2295af306b567b17babc529412eb567073
|