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
uv tool install pyreorder
pyreorder --version # `rord` is installed as a short alias
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)
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)
Pre-commit
repos:
- repo: https://github.com/jr2804/pyreorder
rev: v0.1.0
hooks:
- id: pyreorder
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
Development
uv sync --dev # install dev dependencies
uv run pytest # tests
uvx ruff check . # lint
uvx ruff format . # format
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.
Metadata
Release files for pyreorder 2026.9.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyreorder-2026.9.4.tar.gz | 117.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyreorder-2026.9.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 163.5 kB
Release files / pyreorder-2026.9.4.tar.gz
| Download URL | pyreorder-2026.9.4.tar.gz |
|---|---|
| Size | 117.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9194717b2e69316111e779f9e76ebbbedeada08c2410c2a374fcf21853baf63
|
|
BLAKE2b-256 checksum How to use checksums |
3a25666cda00c92ae964cab4d25f705a7b3a1d556d8bc443191cd2f34981c6aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency logRelease files / pyreorder-2026.9.4-py3-none-any.whl
| Download URL | pyreorder-2026.9.4-py3-none-any.whl |
|---|---|
| Size | 45.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4cc105bb8b37925cebc162b7d9dbedfeb98f5143755f54e4a8759a5269e43856
|
|
BLAKE2b-256 checksum How to use checksums |
427f9fdbbd3ad0285310099a10a6d84a0d2460db0ae61be1ba0e3f38be4fb80c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.
Transparency log