Enforce top-down / newspaper-style function ordering in Python
Project description
flake8-stepdown
A flake8 plugin that enforces top-down (newspaper-style) function ordering in Python modules.
This is inspired by Robert C. Martin's "Clean Code" stepdown rule: High-level logic first, details later. When reading a module, callers should appear before callees, so you can read the code from top to bottom like a newspaper article.
Violation codes
| Code | Meaning |
|---|---|
| TDP001 | Function is defined in the wrong order (should appear after another function) |
Installation
pip install flake8-stepdown
The plugin registers itself with flake8 automatically. Verify it's installed:
flake8 --version
You should see flake8-stepdown in the list of installed plugins.
Usage
As a flake8 plugin
Just run flake8 as usual, the plugin will report TDP001 violations:
flake8 your_module.py
Standalone CLI
The package also provides a stepdown command with three subcommands:
# Report violations
stepdown check your_module.py
# Show a unified diff of the proposed reordering
stepdown diff your_module.py
# Rewrite files in place
stepdown fix your_module.py
Use -v / --verbose to show mutual recursion info on stderr.
Development
Prerequisites
- UV (Python package manager)
Setup
uv sync
Linting
./lint.sh
Testing
uv run pytest
Tests are organized by pipeline stage (test_parser.py, test_graph.py, test_rewriter.py, etc.). The rewriter uses snapshot testing: tests/fixtures/ contains input Python files exercising various scenarios (bottom-up ordering, mutual recursion, decorators, etc.), and tests/snapshots/ contains the expected output after rewriting. The test suite asserts correctness against snapshots, idempotency, and syntax validity.
Pre-commit hooks
Pre-commit hooks are installed automatically. To run manually:
uv run pre-commit run --all-files
CI
GitHub Actions runs linting, type checking, and tests on every push to main and on pull requests.
Publishing to PyPI
This project uses trusted publishing via GitHub Actions.
To publish a new version:
- Bump the version with
uv version --bump patch(orminor/major) - Create a GitHub release with a tag matching the version (e.g.,
v0.1.0) - The publish workflow will automatically build and upload to PyPI
First-time setup: Configure a trusted publisher on PyPI under your project's settings (Publishing tab). Use
publish.ymlas the workflow name andpublishas the environment name.
Contributing
See CONTRIBUTING.md for code style, conventions, and development workflow.
Project details
Release history Release notifications | RSS feed
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 flake8_stepdown-0.1.0.tar.gz.
File metadata
- Download URL: flake8_stepdown-0.1.0.tar.gz
- Upload date:
- Size: 55.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2ada0862a00c1649fe6da2a7fa7f747fa53fb8c4ed797d517c68dd8e8812c34
|
|
| MD5 |
b03ab0f5685174209d102e094e16a9dd
|
|
| BLAKE2b-256 |
6ab66eb83487408d3b330e092975682a76d7a0bcc9cb34c13a3c34c864e2f719
|
Provenance
The following attestation bundles were made for flake8_stepdown-0.1.0.tar.gz:
Publisher:
publish.yml on didmar/flake8-stepdown
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flake8_stepdown-0.1.0.tar.gz -
Subject digest:
e2ada0862a00c1649fe6da2a7fa7f747fa53fb8c4ed797d517c68dd8e8812c34 - Sigstore transparency entry: 1124363418
- Sigstore integration time:
-
Permalink:
didmar/flake8-stepdown@20f69807d6c55e53f661e362157a591e5fbd0c3b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/didmar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@20f69807d6c55e53f661e362157a591e5fbd0c3b -
Trigger Event:
release
-
Statement type:
File details
Details for the file flake8_stepdown-0.1.0-py3-none-any.whl.
File metadata
- Download URL: flake8_stepdown-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.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 |
6daa62ac1975f939b6b2f9b3eeda6cc335cfa7004ff7f1057fdff190380216f3
|
|
| MD5 |
6b8333dd8814a6f2c34aff04b3477f07
|
|
| BLAKE2b-256 |
e400a3f49f6e2b355330f4ca6afde0c100b8e3e14064e78382341a0c7e670e50
|
Provenance
The following attestation bundles were made for flake8_stepdown-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on didmar/flake8-stepdown
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flake8_stepdown-0.1.0-py3-none-any.whl -
Subject digest:
6daa62ac1975f939b6b2f9b3eeda6cc335cfa7004ff7f1057fdff190380216f3 - Sigstore transparency entry: 1124363484
- Sigstore integration time:
-
Permalink:
didmar/flake8-stepdown@20f69807d6c55e53f661e362157a591e5fbd0c3b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/didmar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@20f69807d6c55e53f661e362157a591e5fbd0c3b -
Trigger Event:
release
-
Statement type: