Python foundations

Build a dependable Python foundation with tests

Learn a repeatable Python project loop built around isolated environments, explicit data contracts, failure cases, and standard-library tests.

Outcome

Set up a small Python project, run the published agent-loop tests, and use the same arrange-act-assert pattern for your next function.

Prerequisites
  • Python 3.12 or newer
  • A terminal and a text editor

Start with an isolated project

Create an environment before installing anything. Even a standard-library-only project benefits from a recorded Python version and a repeatable activation step.

mkdir dependable-python
cd dependable-python
python3 -m venv .venv
source .venv/bin/activate
python --version

On Windows PowerShell, activate with .venv\Scripts\Activate.ps1. Keep .venv out of version control. Record the supported version in the README and continuous-integration configuration.

Make the contract visible

A dependable function has a narrow input, a named output, and an explicit failure policy. Type hints communicate the intended contract; they do not replace runtime checks for untrusted input.

The published agent loop source uses a dataclass for each planned action and a small tool registry. Read those boundaries before reading the control loop itself:

  1. Action defines the planner-to-runtime message.
  2. TOOLS is the complete execution allowlist.
  3. Tool validation happens before execution.
  4. The trace records what actually ran.

Download the example and its tests, then run:

python3 -m unittest -v

Test behavior, including failure behavior

Use the same shape for a new function:

  • Arrange: construct a realistic input and any bounded dependency.
  • Act: call one public behavior.
  • Assert: check the returned value or the specific error.

One successful example is insufficient. Add a malformed input, an empty boundary, and a dependency failure when each is relevant. A test should explain the contract, not mirror every implementation line.

Keep failures actionable

Raise an error at the boundary that can explain it. Avoid catching Exception only to return an empty value; that turns a useful failure into misleading success.

For command-line programs, separate domain logic from printing and process exit codes. Domain functions should be directly testable. The thin command-line layer can translate a known exception into a concise message and a non-zero exit status.

Completion checklist

  • The project declares its supported Python version.
  • A clean environment can run the documented command.
  • Public inputs and outputs are named and typed.
  • Invalid inputs fail before side effects.
  • Tests cover one success path and the important failure paths.
  • The verification command is suitable for CI.

Sources

This guide follows the Python documentation for virtual environments, unittest, and dataclasses.

Next, turn the same tested core into a network boundary with Design a small Python web API with explicit boundaries.

Verification record

Code verification

Python 3.14.7 runtime on macOS; Python 3.12 syntax compatibility checked. Verified 2026-08-31. Command: python3 -m unittest discover -s public/examples/agent-loop -p 'test_*.py' -v.

About the author

Practical Python guides researched, tested, and maintained by the FlyPython editorial team. Editorial standards and contact details →