Build Tools

Task runners and software build tools. If you're looking for Python packaging/build tools, see Package Management.

Tasks like running your tests go in pyproject.toml for Poe the Poet to run. C and C++ projects that replace Make with a Python build tool pick SCons.

How to choose:

  • Project tasks in pyproject.toml, run in your uv or Poetry environment: Poe the Poet
  • Compiling C or C++ in place of Make: SCons
  • Tasks written as Python functions that run shell commands: Invoke
  • Steps that skip when their input files haven't changed: doit

Listed in editorial order. Click a column header to re-sort the whole list.

Press / to search. Tags open their category. Click a row for details.

Search and filter

Results

Row number Tags
A tool for managing shell-oriented subprocesses and organizing executable Python code into CLI-invokable tasks.
pyinvoke/github.com/pyinvoke/invoke /4,781 stars /
A task runner that defines tasks in pyproject.toml and works with poetry or uv.
nat-n/github.com/nat-n/poethepoet /2,093 stars /
A software construction tool.
SCons/github.com/SCons/scons /2,437 stars /
A task runner and build tool.
pydoit/github.com/pydoit/doit /2,095 stars /

Build Tools guide

Poe the Poet reads tasks from a [tool.poe.tasks] table in pyproject.toml. A string like test = "pytest" is a whole task, run as a command without a shell. In a uv or Poetry project, poe runs tasks in the project's virtualenv, so you don't type uv run or poetry run in front.

Invoke tasks are Python functions in a tasks.py file, decorated with @task and taking a context as their first argument. Inside, c.run() runs a shell command. A function's arguments become CLI flags, and a task can name pre-tasks to always run before it.

doit reads tasks from a dodo.py file, where each task_ function returns a dict of actions, file dependencies, and targets instead of running anything. It saves a signature of each file_dep and skips a task whose inputs haven't changed. A task that declares no input never counts as up to date, so list the files each task reads in file_dep.

SCons reads your build from an SConstruct file, which is a Python script: Program('hello.c') there is enough for scons to compile a program. Calling a builder like Program() declares what you want built instead of building it on that line, and SCons works out when to run each step.

Know a project that belongs here?

Tell us what it does and why it stands out.