pyreorder¶
AST-based Python module reorganizer.
pyreorder reorders the top-level statements of a Python module into a canonical
section layout (imports → globals → constants → classes → functions → main)
and reorders the methods inside each class by visibility and type. It is built
on libcst, so comments and formatting
are preserved.
It is a module reorganizer: it focuses on grouping and ordering imports/globals/constants/classes/methods/etc. It does not integrate with other sorting tools (isort, undersort, etc.) or provide ruff subcommands.
Install¶
Requires Python 3.11+; Linux, macOS, and Windows are all supported.
uv tool install pyreorder
pyreorder --version # `rord` is installed as a short alias
Or with pip:
pip install pyreorder
Quick start¶
pyreorder run src/ # sort files in place
pyreorder check src/ # exit 1 if anything would change (CI / pre-commit)
pyreorder diff src/ # preview changes
pyreorder config generate # write/print a pyreorder.toml template (--with-comments, --with-config)
A short alias rord is installed alongside pyreorder, so every command also
works as rord run src/, rord check src/, rord diff src/, and so on.
Before → after¶
Given this module:
import sys
def main():
greet()
def greet():
print("hi")
class Service:
def _close(self):
...
def start(self):
...
MAX_CONN = 10
if __name__ == "__main__":
main()
pyreorder run (with functions = "stepdown") produces:
import sys
MAX_CONN = 10
class Service:
def start(self):
...
def _close(self): # public methods first, then protected
def main(): # caller before callee (step-down rule)
greet()
def greet():
print("hi")
if __name__ == "__main__":
main()
Configuration¶
Discovered from (first wins, walking up from the target file): --config,
pyreorder.toml, .config/pyreorder.toml, [tool.pyreorder] in pyproject.toml.
[tool.pyreorder.module]
sections = [
"imports", "typing_imports", "module_constants", "enums",
"dataclasses", "classes", "functions", "dunder_exports", "main_block",
]
[tool.pyreorder.strategy] # per-section; omit => "keep"
enums = "alpha"
functions = "stepdown" # "alpha" | "stepdown" | "abstraction" | "keep"
[tool.pyreorder.class_methods] # undersort-style ordering within each class
enabled = true
order = ["public", "protected", "private"]
method_type_order = ["instance", "class", "static"]
Strategies¶
| value | meaning | applies to |
|---|---|---|
keep |
preserve original order (default) | any section |
alpha |
alphabetical by primary name | imports, enums |
stepdown |
caller before callee (top-down narrative) | functions, classes |
abstraction |
callee before caller (low-level utilities first) | functions, classes |
Caution:
alphaonmodule_constants/classes/dataclassescan break runtime order (interdependent constants, inheritance). Always preview withpyreorder difffirst.
Safety model¶
pyreorder is conservative by design:
- Barriers — statements that don't map to a configured section (runtime
setup like
app = typer.Typer()) are never moved. Recognised statements only reorder within their contiguous barrier-free run, so pyreorder never moves code across a statement it might depend on. - Pinned — the module docstring and
from __future__ import ...always stay first. - Opt-out — a
# pyreorder: off(or# nosort) comment in a file's header skips the file;class C: # pyreorder: offskips that class. - Idempotent — running
pyreordertwice never changes a file a second time.
Programmatic API¶
from pyreorder import sort_source, Config
cfg = Config(strategies={"functions": "stepdown"})
sorted_text = sort_source(source_text, cfg)
Agent skill¶
An installable agent skill lives in skills/pyreorder.
Install it for your AI assistant:
bun x skills add https://github.com/jr2804/pyreorder.git -s pyreorder -a universal -y
Documentation¶
Full documentation: https://jr2804.github.io/pyreorder/ — architecture, configuration reference, section layout, sorting modes, comparison with other tools, ADRs, and the API reference.
Contributor setup, the check/test tasks, the docs build, pre-commit hooks, and the release process are on the Development page.
Contributing¶
Contributions are welcome. Development setup, the check and test tasks, pre-commit hooks, and the release process are on the Development page; CONTRIBUTING.md has the short version.
Support¶
Bug reports and feature requests go to the issue tracker.
Acknowledgements¶
The in-class method sorter is an adapted reimplementation of undersort (MIT). Dependency-aware function ordering was inspired by ssort, sdsort and ABSort. See Credits.
License¶
MIT — see LICENSE.