Rewrap Python # comments to a specified line length
Project description
octowrap
A CLI tool that rewraps octothorpe (#) Python comments to a specified line length while preserving commented-out code, section dividers, list items, special markers, and tool directives.
Features
- Rewraps comment blocks to a configurable line length (default 88)
- Preserves commented-out Python code (detected via 21 heuristic patterns)
- Preserves section dividers (
# --------,# ========, etc.) - Preserves list items (bullets, numbered items)
- Preserves special markers (
TODO,FIXME,NOTE,XXX,HACK) - Preserves tool directives (
type: ignore,noqa,fmt: off,pragma: no cover,pylint: disable, etc.) - Supports
# octowrap: off/# octowrap: onpragma comments to disable rewrapping for regions of a file - Applies changes automatically by default, or use
-ifor interactive per-block approval with colorized diffs (aaccept,Aaccept all,sskip,qquit) - Reads from stdin when
-is passed as the path (like black/ruff/isort) - Auto-detects color support; respects
--no-color,--color, and theNO_COLORenv var - Project-level configuration via
[tool.octowrap]inpyproject.toml
Development Setup
git clone https://github.com/camUrban/octowrap.git
cd octowrap
uv pip install -e ".[dev]"
Usage
octowrap <files_or_dirs> [--line-length 88] [--config PATH] [--dry-run] [--diff] [--check] [--no-recursive] [-i] [--color | --no-color]
Stdin/stdout
Pass - as the path to read from stdin and write to stdout:
echo "# A very long comment that needs rewrapping to a shorter width." | octowrap -
cat file.py | octowrap - --diff # show diff
cat file.py | octowrap - --check # exit 1 if changes needed
cat file.py | octowrap - -l 79 # custom line length
Note: - cannot be mixed with other paths and is incompatible with -i (interactive mode).
Example
Before:
# This is a long comment that has been written without much regard for line length and really should be wrapped to fit within a reasonable number of columns.
After (--line-length 88):
# This is a long comment that has been written without much regard for line
# length and really should be wrapped to fit within a reasonable number of
# columns.
Disabling Rewrapping
Use pragma comments to protect regions of a file from rewrapping, similar to # fmt: off/on in black/ruff:
# octowrap: off
# This comment will not be rewrapped,
# no matter how long or short
# the lines are.
# octowrap: on
# This comment will be rewrapped normally.
- Directives are case-insensitive (
# OCTOWRAP: OFFworks) - Must be a standalone comment line (inline
x = 1 # octowrap: offis ignored) # octowrap: offwithout a matchingondisables rewrapping through end of file- Pragma lines themselves are always preserved as-is
Pre-commit Hook
Add octowrap to your .pre-commit-config.yaml:
- repo: https://github.com/camUrban/octowrap
rev: v0.1.0
hooks:
- id: octowrap
# args: [-l, "79"] # custom line length
# args: [--check] # fail without modifying (useful for CI)
Configuration
Add a [tool.octowrap] section to your pyproject.toml to set project-level defaults:
[tool.octowrap]
line-length = 120
recursive = false
exclude = ["migrations", "generated"]
extend-exclude = ["vendor"]
| Key | Type | Default | CLI equivalent |
|---|---|---|---|
line-length |
int | 88 | --line-length |
recursive |
bool | true | --no-recursive |
exclude |
list[str] | — | — |
extend-exclude |
list[str] | — | — |
CLI flags always take precedence over config values. Use --config PATH to point to a specific pyproject.toml instead of relying on auto-discovery.
exclude replaces the built-in default exclude list entirely. extend-exclude adds patterns to the defaults (or to exclude if set). Default excludes: .git, .hg, .svn, .bzr, .venv, venv, .tox, .nox, .mypy_cache, .ruff_cache, .pytest_cache, __pycache__, __pypackages__, _build, build, dist, node_modules, .eggs. Patterns are matched against individual path components using fnmatch.
License
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 octowrap-0.1.0.tar.gz.
File metadata
- Download URL: octowrap-0.1.0.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
43e7a4df6ed06cec7ffb72716682ae2f211de92a6ff56b2dd07852a2870da21b
|
|
| MD5 |
ba6c6535fc9e1c6de287313b1a7a33ce
|
|
| BLAKE2b-256 |
b8f256ae8e32cd1368d4b00ab467cbe745c9cc2ffe196f5d9ae2cff15c820939
|
Provenance
The following attestation bundles were made for octowrap-0.1.0.tar.gz:
Publisher:
publish.yml on camUrban/octowrap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
octowrap-0.1.0.tar.gz -
Subject digest:
43e7a4df6ed06cec7ffb72716682ae2f211de92a6ff56b2dd07852a2870da21b - Sigstore transparency entry: 923296470
- Sigstore integration time:
-
Permalink:
camUrban/octowrap@8eba90bf09ad2ab599b7cc0dc7570f863cdc3ec5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/camUrban
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8eba90bf09ad2ab599b7cc0dc7570f863cdc3ec5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file octowrap-0.1.0-py3-none-any.whl.
File metadata
- Download URL: octowrap-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49d5d583a2141968b49ca106f2feec5de8e6e4e869015fb19a62ea19dd802705
|
|
| MD5 |
4dfe5300b730b7955804089aa088e98c
|
|
| BLAKE2b-256 |
ce1883e59b22a510f355af5f3b431ee2f4fcfa7da386776c259c743dc740518e
|
Provenance
The following attestation bundles were made for octowrap-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on camUrban/octowrap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
octowrap-0.1.0-py3-none-any.whl -
Subject digest:
49d5d583a2141968b49ca106f2feec5de8e6e4e869015fb19a62ea19dd802705 - Sigstore transparency entry: 923296511
- Sigstore integration time:
-
Permalink:
camUrban/octowrap@8eba90bf09ad2ab599b7cc0dc7570f863cdc3ec5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/camUrban
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8eba90bf09ad2ab599b7cc0dc7570f863cdc3ec5 -
Trigger Event:
release
-
Statement type: