Well, actually — an opinionated Python linter and formatter: bans else and elif, allows only flat ternaries, and enforces blank lines around return
Project description
actually
Well, actually, your code should read like this.
actually is a highly opinionated Python linter and formatter built on
ast-grep. It enforces a guard-clause style:
elseis banned — onif, and as the completion clause onfor,while, andtryalikeelifis banned- ternaries are allowed only flat — nested conditional expressions are banned
returnneeds a blank line above it when it follows other statements in its blockreturnneeds a blank line below it when more code follows
Usage
uvx well-actually@latest check .
uvx well-actually@latest format .
The @latest matters: a bare uvx well-actually reuses a cached tool environment and can
silently run an outdated version; @latest re-resolves against the index every time.
Installed (uv tool install well-actually), the short command is available too:
actually check .
actually format .
check reports violations and exits non-zero when it finds any. Both commands lint .py
files only; directory scans skip environment, cache, and VCS directories (.venv, venv,
.git, __pycache__, node_modules, and friends) and respect .gitignore files — nested
ones and negations included, matched via pathspec
(black's approach), so no git installation is required. When a .git directory is found
above the scanned path, .gitignore files up to that repo root apply as well. Global
excludes (core.excludesFile, .git/info/exclude) are not consulted. A .py file passed
explicitly is always linted.
format rewrites files in place, then reports what it could not fix:
- inserts the missing blank lines around
return - dedents a
try/except/elsecompletion clause into straight-line code when everyexceptbody already exits (return,raise,continue,break) — when one falls through, the rewrite would change behaviour, so it is reported for human refactoring instead
Example
def describe_config(path):
try:
config = parse_json_file(path)
except ParseError:
return "invalid config"
else:
return describe(config)
actually format rewrites this to:
def describe_config(path):
try:
config = parse_json_file(path)
except ParseError:
return "invalid config"
return describe(config)
Development
uv sync
uv run pytest
uv run actually check src/ tests/
Project details
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 well_actually-0.2.3.tar.gz.
File metadata
- Download URL: well_actually-0.2.3.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ab2a2c5f85ef0dee74a80b0258d2561db0f70c2549456c6136c49fddb724642
|
|
| MD5 |
7f4594e5ba754cc35f6cae8076653263
|
|
| BLAKE2b-256 |
57b8d029bdb24d4735c713fa95d97b4868c48f3faed165483996e16999da57da
|
File details
Details for the file well_actually-0.2.3-py3-none-any.whl.
File metadata
- Download URL: well_actually-0.2.3-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
511f65852d74ff5d592227ef08dcc8501a85de030dcdec70956ebece3f3e67a5
|
|
| MD5 |
8d578a711faf8faeac2dcb679b285368
|
|
| BLAKE2b-256 |
eccb921311086871754002292beb3b3287c97ba506ecaa27ccb8cf4e38dd8e63
|