Verified against Claude Code · 2026-08-01
Package a Python project for real distribution with pyproject.toml
A prompt for producing a complete, modern src-layout package with a real pyproject.toml, dev/test dependency groups, and a verified build step, instead of a bare setup.py or an incomplete pyproject stub.
The prompt
Ready to copy — highlighted parts are example details you can swap.
Package the project below for real distribution — not a script that only runs from inside its own folder. PROJECT A small library called "orderkit" for parsing and validating e-commerce order exports. RUNTIME DEPENDENCIES pydantic>=2.9, pandas>=2.2 DISTRIBUTION TARGET internal use via a private index, not public PyPI REQUIREMENTS 1. Use a src/ layout (src/<package_name>/..., inferring the actual package name from the project description) so the package can't accidentally be imported from the repo root during development, hiding a packaging bug that only shows up after a real install. 2. A complete pyproject.toml: [build-system] naming a specific backend (hatchling or setuptools>=68 — say which and why), [project] with name, version, requires-python, dependencies pinned with sensible lower bounds, and [project.optional-dependencies] for dev/test tooling (pytest, ruff, mypy) kept separate from runtime deps. 3. If this needs a CLI entry point, define it under [project.scripts]. 4. A .gitignore covering build artifacts (dist/, *.egg-info, __pycache__/) and a minimal README.md with install and usage instructions matching internal use via a private index, not public PyPI. 5. If internal use via a private index, not public PyPI is public PyPI, flag what else is needed before publishing — a unique name check, a license file, a long_description sourced from the README — rather than assuming it's ready. 6. State the exact commands to build and locally verify the package installs cleanly: build it, install the built wheel into a fresh throwaway virtual environment, and import it, before it's ever pushed anywhere. OUTPUT FORMAT 1. The file tree. 2. The full pyproject.toml. 3. The build-and-verify commands, in order.
Customize the highlighted detailsoptional — the prompt above already works
Why this works
Requiring the src/ layout by name matters because it prevents the single most common packaging bug: a package that imports fine during development purely because the current working directory happens to be on sys.path, then fails on a genuinely clean install because a missing __init__.py or a broken relative import was never actually exercised until now. Requiring the build backend to be named and justified, rather than left to the model's default, matters because pyproject.toml's [build-system] table is exactly the part that varies most across tutorials of different vintages — an unconstrained prompt is as likely to produce a stale setup.py-based flow as a modern one. Requiring the fresh-venv install-and-import step as an explicit output, not just the config file, is what catches "works on my machine" packaging bugs — a dependency that was actually already installed globally, or a file that exists locally but was never added to the package manifest — before they reach a real install anywhere else.
Verified against
Claude Code Sonnet 4.6 · 2026-08-01
ChatGPT GPT-5.1 · 2026-08-02
Changelog
- 2026-08-02 — Initial publish, verified against Claude Code (Sonnet 4.6) and ChatGPT (GPT-5.1) using uv 0.5 for the build/verify step.
Need this built into your business?
If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.
EXPLORE CUSTOM SOFTWARE

