# Python Developer Tooling Handbook


<section class="pdt-handbook-hero" aria-labelledby="pdt-hero-title">
<div class="pdt-handbook-hero__copy">
<h1 id="pdt-hero-title" class="pdt-handbook-hero__title">What to use.<br>And&nbsp;why<span class="pdt-hero-period" aria-hidden="true">.</span></h1>
<p class="pdt-handbook-hero__lede">Python's tooling is a maze of overlapping tools, cautious official docs, and stale blog posts. This handbook tells you what to use today, and why.</p>
<p class="pdt-handbook-hero__byline">By <a class="pdt-handbook-hero__byline-link" href="https://tdhopper.com/">Tim Hopper</a> · Independent · Current</p>
<div class="pdt-handbook-hero__actions"><a class="pdt-handbook-hero__cta" href="/handbook/tutorial/create-your-first-python-project/"><span>Begin with the first tutorial</span><svg class="pdt-handbook-hero__cta-arrow" aria-hidden="true" width="16" height="16" viewBox="0 0 16 16"><path d="M3 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/></svg></a><a class="pdt-handbook-hero__secondary" href="#pdt-newsletter">Get the monthly tooling update</a></div>
</div>
<div class="pdt-handbook-hero__terminal" role="img" aria-label="Example uv session: uv init my-project, uv add requests, uv run hello.py, prints Hello, world!">
<div class="pdt-handbook-hero__terminal-chrome" aria-hidden="true"><span></span><span></span><span></span></div>
<pre class="pdt-handbook-hero__terminal-body" aria-hidden="true"><code><span class="pdt-t-line"><span class="pdt-t-prompt">$</span> <span class="pdt-t-cmd">uv</span> init my-project</span>
<span class="pdt-t-line"><span class="pdt-t-prompt">$</span> <span class="pdt-t-cmd">uv</span> add requests</span>
<span class="pdt-t-line"><span class="pdt-t-prompt">$</span> <span class="pdt-t-cmd">uv</span> run hello.py</span>
<span class="pdt-t-line pdt-t-out">Hello, world!</span></code></pre>
</div>
</section>

<script>
(function () {
  var hero = document.querySelector('.pdt-handbook-hero');
  if (!hero) return;

  /* ---- Easter egg 1: Terminal window dots ---- */
  var term = hero.querySelector('.pdt-handbook-hero__terminal');
  var dots = hero.querySelectorAll('.pdt-handbook-hero__terminal-chrome > span');

  if (term && dots.length === 3) {
    /* Pin the terminal visible so removing animation classes can't
       flicker back to the entrance animation's opacity:0 base state */
    function pinVisible() {
      term.style.opacity = '1';
      term.style.transform = 'none';
    }

    function exitFullscreen() {
      term.classList.remove('pdt-terminal--fullscreen');
      pinVisible();
    }

    /* Red dot: "close" the terminal (or exit fullscreen) */
    dots[0].addEventListener('click', function () {
      if (term.classList.contains('pdt-terminal--fullscreen')) { exitFullscreen(); return; }
      if (term.classList.contains('pdt-terminal--closing') ||
          term.classList.contains('pdt-terminal--minimizing')) return;
      term.classList.add('pdt-terminal--closing');
      setTimeout(function () { term.classList.remove('pdt-terminal--closing'); pinVisible(); }, 1600);
    });

    /* Yellow dot: "minimize" the terminal (or exit fullscreen) */
    dots[1].addEventListener('click', function () {
      if (term.classList.contains('pdt-terminal--fullscreen')) { exitFullscreen(); return; }
      if (term.classList.contains('pdt-terminal--closing') ||
          term.classList.contains('pdt-terminal--minimizing')) return;
      term.classList.add('pdt-terminal--minimizing');
      setTimeout(function () { term.classList.remove('pdt-terminal--minimizing'); pinVisible(); }, 1600);
    });

    /* Green dot: "fullscreen" the terminal */
    dots[2].addEventListener('click', function () {
      if (term.classList.contains('pdt-terminal--closing') ||
          term.classList.contains('pdt-terminal--minimizing')) return;
      term.classList.toggle('pdt-terminal--fullscreen');
    });
  }

  /* ---- Easter egg 2: Headline tagline cycling ---- */
  var title = document.getElementById('pdt-hero-title');
  var period = hero.querySelector('.pdt-hero-period');
  var taglines = [
    'What to use.<br>And\u00a0why',
    'What to drop.<br>And\u00a0when',
    'What changed.<br>Since\u00a0Tuesday'
  ];
  var idx = 0;

  if (title && period) {
    /* Delegate to the title so the listener survives innerHTML rebuilds */
    title.addEventListener('click', function (e) {
      if (!e.target.classList.contains('pdt-hero-period')) return;
      idx = (idx + 1) % taglines.length;
      title.innerHTML = taglines[idx] + '<span class="pdt-hero-period" aria-hidden="true">.</span>';
      title.classList.toggle('pdt-hero-title--swapped', idx !== 0);
    });
  }
})();
</script>

New to Python and just need it running? Start with [How to Install Python]({{< ref "handbook/How To/how-to-install-python.md" >}}). It tells you what to install on macOS, Windows, or Linux, and what to ignore.

The handbook covers [packaging]({{< ref "handbook/Reference/uv.md" >}}), [linting and formatting]({{< ref "handbook/Reference/ruff.md" >}}), [testing]({{< ref "handbook/Reference/pytest.md" >}}), [type checking]({{< ref "handbook/Reference/mypy.md" >}}), and [dependency management]({{< ref "handbook/Explanation/why-should-i-choose-pyproject-toml-over-requirements-txt-for-managing-dependencies.md" >}}) with opinionated recommendations and honest trade-offs. Each tool's [Reference]({{< ref "handbook/Reference/" >}}) page links to its official documentation; the handbook complements those docs, the [Python Packaging User Guide](https://packaging.python.org/), and the [Scientific Python Library Development Guide](https://learn.scientific-python.org/development/), not replaces them.

Starting or standardizing a project? The [Modern Python Tooling Checklist]({{< ref "tooling-checklist.md" >}}) puts these defaults on one page.

## Topic hubs {#topic-hubs}

Curated entry points for the tools and tasks at the heart of modern Python development.

{{< cards >}}
  {{< card link="/handbook/topics/uv/" title="uv" icon="cube" subtitle="Python's fastest package and project manager" >}}
  {{< card link="/handbook/topics/ruff/" title="Ruff" icon="sparkles" subtitle="Fast linting and formatting" >}}
  {{< card link="/handbook/topics/ty/" title="ty" icon="shield-check" subtitle="Fast type checker built by Astral, now at OpenAI" >}}
  {{< card link="/handbook/topics/testing/" title="Testing" icon="check-circle" subtitle="pytest, fixtures, parallel runs, and CI" >}}
  {{< card link="/handbook/topics/packaging/" title="Packaging" icon="cube" subtitle="Build wheels, lock dependencies, publish to PyPI" >}}
  {{< card link="/handbook/topics/security/" title="Security" icon="lock-closed" subtitle="Supply chain, attestations, vulnerability scans" >}}
  {{< card link="/handbook/topics/scientific-python/" title="Scientific Python" icon="beaker" subtitle="NumPy, CUDA, conda, pixi, ML stacks" >}}
  {{< card link="/handbook/topics/ai-assistants/" title="AI Assistants" icon="chat" subtitle="Claude Code, Cursor, Codex, GitHub Copilot" >}}
{{< /cards >}}

## Popular pages

{{< cards >}}
  {{< card link="/handbook/explanation/whats-the-difference-between-pip-and-uv" title="pip vs uv" icon="scale" subtitle="Compare Python package managers: features, speed, and workflows" >}}
  {{< card link="/handbook/tutorial/create-your-first-python-project" title="First Python project" icon="play" subtitle="Structure and initialize a new Python project with uv" >}}
  {{< card link="/handbook/how-to/migrate-requirements.txt/" title="Migrate from requirements.txt" icon="arrow-up" subtitle="Move a legacy project to pyproject.toml using uv" >}}
  {{< card link="/handbook/how-to/how-to-migrate-from-poetry-to-uv" title="Poetry to uv" icon="clock" subtitle="Switch from Poetry to uv for faster dependency management" >}}
  {{< card link="/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code" title="Set up Ruff" icon="sparkles" subtitle="Automate code formatting and linting with Ruff" >}}
  {{< card link="/handbook/tutorial/setting-up-testing-with-pytest-and-uv" title="Testing with pytest" icon="check-circle" subtitle="Configure and run tests with pytest and uv" >}}
  {{< card link="/handbook/how-to/how-to-change-the-python-version-of-a-uv-project" title="Change Python versions" icon="refresh" subtitle="Switch Python versions in a uv-managed project" >}}
  {{< card link="/handbook/explanation/pyproject-vs-requirements" title="pyproject.toml vs requirements.txt" icon="document" subtitle="Why pyproject.toml is the modern standard for dependencies" >}}
{{< /cards >}}

## Browse by section

- [Tutorial]({{< ref "handbook/Tutorial/" >}}) Step-by-step guides for setting up tools and workflows.
- [How To]({{< ref "handbook/How To/" >}}) Practical solutions to specific problems.
- [Explanation]({{< ref "handbook/Explanation/" >}}) Context and background for understanding the ecosystem.
- [Reference]({{< ref "handbook/Reference/" >}}) Tool-by-tool technical descriptions.

Feedback on any page is welcome via the form at the bottom.

<div id="pdt-newsletter"></div>

{{< newsletter >}}

## Recent Blog Posts

- [Python Development Tooling Tutorials](https://pydevtools.com/handbook/tutorial/index.md)
- [Python Development Tooling How-To Guides](https://pydevtools.com/handbook/how-to/index.md)
- [Python Tooling Explained](https://pydevtools.com/handbook/explanation/index.md)
- [Python Developer Tools Reference](https://pydevtools.com/handbook/reference/index.md)
