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)
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.
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.6
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.6.tar.gz | 120.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyreorder-2026.9.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 166.3 kB
Release files / pyreorder-2026.9.6.tar.gz
| Download URL | pyreorder-2026.9.6.tar.gz |
|---|---|
| Size | 120.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f56ea760c97f03d5b7d7fbee5f9f1e4d574256556d931aec02c0b39bb02ddd90
|
|
BLAKE2b-256 checksum How to use checksums |
311b10a07156fc208150bcbd72cc2a3c30f57b8ab7c7d0813b2dd1ebcc4e339a
|
| 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.6-py3-none-any.whl
| Download URL | pyreorder-2026.9.6-py3-none-any.whl |
|---|---|
| Size | 45.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de173b412b029978e6ed525984b1fec7e0179001ebb2acba4867fc12e2a8f46b
|
|
BLAKE2b-256 checksum How to use checksums |
d7b2659da4337050766437380e5549de63f555c31ac819d3824ec923176ee2ba
|
| 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