Skip to main content

Enforce stepdown rule in Python files

Project description

pystepdowner

A tool to enforce the Stepdown Rule (from Uncle Bob's Clean Code) in your Python files.

The Stepdown Rule states that code should be readable from top to bottom. Every function should be followed by those at the next level of abstraction so that we can read the program, descending one level of abstraction at a time as we read down the list of functions.

pystepdowner analyzes your Python files and rearranges functions and methods to adhere to this rule, prioritizing source-code call order and correctly handling complex dependency graphs.

Installation

You can install pystepdowner as a global CLI tool using uv (recommended):

# Install from PyPI
uv tool install pystepdowner

# Or install from source locally
uv tool install .

Alternatively, you can install it into any Python environment using standard pip:

pip install pystepdowner

Usage

The CLI provides two main commands: fmt and rw.

1. fmt: Format and Print to Output

Use the fmt command to format a single file and output the result to your terminal. This is useful for previewing changes without modifying the actual file.

pystepdowner fmt -i my_script.py

2. rw: Rewrite Files

Use the rw command to format and rewrite files. You can rewrite a single file or an entire directory recursively.

Rewrite a Single File In-Place

pystepdowner rw -i my_script.py

Rewrite a Single File and Save to a New Location

pystepdowner rw -i my_script.py -o formatted_script.py

Rewrite an Entire Directory In-Place

This will recursively find and format all .py files inside the target directory.

pystepdowner rw -i src/

Example

pystepdowner transforms bottom-up code into top-down code, putting high-level logic before the helpers it calls.

Before:

def load_user(user_id: int) -> dict:
    return {"id": user_id, "name": "Alice"}


def format_user(user: dict) -> str:
    return f"{user['id']}: {user['name']}"


def user_controller(user_id: int) -> dict:
    user = load_user(user_id)
    return {"body": format_user(user)}

After running pystepdowner rw -i my_script.py:

def user_controller(user_id: int) -> dict:
    user = load_user(user_id)
    return {"body": format_user(user)}


def load_user(user_id: int) -> dict:
    return {"id": user_id, "name": "Alice"}


def format_user(user: dict) -> str:
    return f"{user['id']}: {user['name']}"

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

pystepdowner-1.0.0.tar.gz (56.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pystepdowner-1.0.0-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file pystepdowner-1.0.0.tar.gz.

File metadata

  • Download URL: pystepdowner-1.0.0.tar.gz
  • Upload date:
  • Size: 56.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pystepdowner-1.0.0.tar.gz
Algorithm Hash digest
SHA256 63ec1839f53c21b2663edf7fcb8e4d43f5b4fb808f195b8bf83b8c951975f356
MD5 09d3ebe11b6d51c73977f4a2127daeeb
BLAKE2b-256 8fc7ec0146bd079a5e8eae36edbee173631271dc03377bacd8c2ce8ac7f5b2ce

See more details on using hashes here.

File details

Details for the file pystepdowner-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pystepdowner-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pystepdowner-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5dc33f1343815f1655bb0f8f03992839ab82863f313b229cda1fb6e908aba2e1
MD5 a31a0d2cbf7b63fcdcf226b0f74af1bd
BLAKE2b-256 2f6aa8acc51a33c62bbac18c8460d7ba2b47a3a624ead597323c160ff2a37bc4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page