<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python Developer Tooling Handbook – Python Development Tooling How-To Guides</title>
    <link>https://pydevtools.com/handbook/how-to/</link>
    <description>Practical guides for accomplishing specific tasks with Python development tools like uv, ruff, and pytest.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Mon, 27 Apr 2026 11:32:36 -0400</lastBuildDate>
    
	  <atom:link href="https://pydevtools.com/handbook/how-to/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>How to add dynamic versioning to uv projects</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-add-dynamic-versioning-to-uv-projects/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-add-dynamic-versioning-to-uv-projects/</guid>
      <description>&lt;p&gt;Dynamic versioning generates version numbers from Git tags instead of requiring manual updates to a static version string in &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt;. The release workflow becomes a single &lt;code&gt;git tag&lt;/code&gt; command: the build backend reads the tag, and the wheel and source distribution filenames pick up the matching version automatically.&lt;/p&gt;
&lt;p&gt;This guide uses &lt;a href=&#34;https://github.com/ninoseki/uv-dynamic-versioning/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv-dynamic-versioning&lt;/a&gt;, a &lt;a href=&#34;https://pydevtools.com/handbook/reference/hatch/&#34;&gt;hatchling&lt;/a&gt; plugin that ships a sensible default configuration for &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; projects.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Git repository for your Python project with at least one commit&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; installed on your system&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;src/your_package/&lt;/code&gt; layout (the default for &lt;code&gt;uv init --package&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Configure the build system&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;configure-the-build-system&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#configure-the-build-system&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Update &lt;code&gt;pyproject.toml&lt;/code&gt; to use uv-dynamic-versioning as a &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-build-backend/&#34;&gt;build backend&lt;/a&gt; dependency:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to add Python to your system path with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-add-python-to-your-system-path-with-uv/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-add-python-to-your-system-path-with-uv/</guid>
      <description>&lt;p&gt;Since uv 0.8, Python versions installed by &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; are automatically added to your PATH. When you run &lt;code&gt;uv python install&lt;/code&gt;, uv places versioned Python executables (like &lt;code&gt;python3.12&lt;/code&gt;) in a directory on your PATH (typically &lt;code&gt;~/.local/bin&lt;/code&gt;).&lt;/p&gt;
&lt;h2&gt;Installing a Python version&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;installing-a-python-version&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#installing-a-python-version&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv python install 3.12&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After running the command, the versioned executable is available:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to add type annotations to a Python project with pyrefly infer</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-add-type-annotations-with-pyrefly-infer/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-add-type-annotations-with-pyrefly-infer/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/pyrefly/&#34;&gt;Pyrefly&lt;/a&gt; can turn &lt;code&gt;def total(numbers):&lt;/code&gt; into &lt;code&gt;def total(numbers: list[int]) -&amp;gt; int:&lt;/code&gt; without running your code. The command is &lt;code&gt;pyrefly infer&lt;/code&gt;, previously called &lt;code&gt;autotype&lt;/code&gt;, and it writes draft annotations by reading call sites with static analysis.&lt;/p&gt;
&lt;p&gt;For a legacy codebase with thousands of unannotated functions, this turns weeks of manual annotation into a reviewable diff. The output needs a human review pass before merging.&lt;/p&gt;
&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200&#34;&gt;
  &lt;p class=&#34;hx:flex hx:items-center hx:font-medium&#34;&gt;&lt;svg height=16px class=&#34;hx:inline-block hx:align-middle hx:mr-2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z&#34;/&gt;&lt;/svg&gt;Note&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Build Multi-Platform Wheels with cibuildwheel</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-build-multi-platform-wheels-with-cibuildwheel/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-build-multi-platform-wheels-with-cibuildwheel/</guid>
      <description>&lt;p&gt;Python packages with compiled extensions (C, C++, Rust, Cython) need platform-specific &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt; so users can install them without a compiler. &lt;a href=&#34;https://pydevtools.com/handbook/reference/cibuildwheel/&#34;&gt;cibuildwheel&lt;/a&gt; automates building these wheels across operating systems, architectures, and Python versions in CI.&lt;/p&gt;
&lt;p&gt;This guide sets up a GitHub Actions workflow that builds wheels for Linux, macOS, and Windows, then publishes them to &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pypi/&#34;&gt;PyPI&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Python project with a compiled extension and a &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pep-517/&#34;&gt;PEP 517&lt;/a&gt;-compliant &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-build-backend/&#34;&gt;build backend&lt;/a&gt; (setuptools, scikit-build-core, maturin, etc.)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;[build-system]&lt;/code&gt; table in &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A GitHub repository&lt;/li&gt;
&lt;li&gt;A PyPI account with &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-publish-to-pypi-with-trusted-publishing/&#34;&gt;trusted publishing&lt;/a&gt; configured for the repository&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Configure cibuildwheel&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;configure-cibuildwheel&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#configure-cibuildwheel&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add a &lt;code&gt;[tool.cibuildwheel]&lt;/code&gt; section to &lt;code&gt;pyproject.toml&lt;/code&gt;. This example targets CPython 3.11 through 3.13, skips 32-bit builds, and runs pytest after each wheel build:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Build Read the Docs with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-build-read-the-docs-with-uv/</link>
      <pubDate>Fri, 01 May 2026 06:58:04 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-build-read-the-docs-with-uv/</guid>
      <description>&lt;p&gt;If your docs already build on Read the Docs, you can now switch &lt;code&gt;.readthedocs.yaml&lt;/code&gt; to native &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; support instead of maintaining a hand-rolled &lt;code&gt;build.jobs&lt;/code&gt; override. Read the Docs added this support on April 21, 2026. The two supported paths are &lt;code&gt;uv sync&lt;/code&gt; with a &lt;code&gt;docs&lt;/code&gt; dependency group, and &lt;code&gt;uv pip install&lt;/code&gt; with a requirements file.&lt;/p&gt;
&lt;h2&gt;Define a docs dependency group&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;define-a-docs-dependency-group&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#define-a-docs-dependency-group&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your project already has a &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/a&gt;, declare a dependency group for the documentation toolchain. Groups are the &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pep-735/&#34;&gt;PEP 735&lt;/a&gt; standard place to keep development-only dependencies out of what your users install:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to change the Python version of a uv project</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-change-the-python-version-of-a-uv-project/</link>
      <pubDate>Tue, 14 Apr 2026 13:37:50 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-change-the-python-version-of-a-uv-project/</guid>
      <description>&lt;p&gt;To change the Python version of a &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; project, run &lt;code&gt;uv python pin 3.12&lt;/code&gt; to update &lt;code&gt;.python-version&lt;/code&gt;, then &lt;code&gt;uv sync&lt;/code&gt; to rebuild the virtual environment against the new interpreter. If you also want to change which versions the project &lt;em&gt;supports&lt;/em&gt;, edit &lt;code&gt;requires-python&lt;/code&gt; in &lt;code&gt;pyproject.toml&lt;/code&gt; and run &lt;code&gt;uv lock &amp;amp;&amp;amp; uv sync&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A uv project tracks Python versions in two places: the &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-python-version-file/&#34;&gt;.python-version file&lt;/a&gt; pins the development interpreter (e.g., &lt;code&gt;3.12&lt;/code&gt;), and &lt;code&gt;requires-python&lt;/code&gt; in &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt; declares which versions the project supports (e.g., &lt;code&gt;&amp;gt;=3.11&lt;/code&gt;). The pinned version must satisfy the &lt;code&gt;requires-python&lt;/code&gt; constraint, or uv will report an &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv/&#34;&gt;incompatibility error&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Claude Code to use uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-uv/</link>
      <pubDate>Wed, 06 May 2026 06:23:27 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-uv/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://claude.com/product/claude-code&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Claude Code&lt;/a&gt; defaults to &lt;a href=&#34;https://pydevtools.com/handbook/reference/pip/&#34;&gt;pip&lt;/a&gt; when it needs to install packages or run scripts. A &lt;a href=&#34;https://code.claude.com/docs/en/memory#set-up-a-project-claude-md&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CLAUDE.md&lt;/a&gt; file in your project root overrides that default so every session uses &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; instead.&lt;/p&gt;
&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200&#34;&gt;
  &lt;p class=&#34;hx:flex hx:items-center hx:font-medium&#34;&gt;&lt;svg height=16px class=&#34;hx:inline-block hx:align-middle hx:mr-2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z&#34;/&gt;&lt;/svg&gt;Tip&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Claude Code to use virtual environments</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-virtual-environments/</link>
      <pubDate>Wed, 06 May 2026 06:23:27 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-claude-code-to-use-virtual-environments/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://code.claude.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Claude Code&lt;/a&gt; starts a fresh shell for every Bash tool call, so &lt;code&gt;source .venv/bin/activate&lt;/code&gt; in one command has no effect on the next. Without configuration, Claude reaches for system Python and installs packages outside the project&amp;rsquo;s &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;virtual environment&lt;/a&gt;. Four configuration patterns work around the stateless-shell limitation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;uv run&lt;/code&gt; for projects on &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt;, which sidesteps activation entirely&lt;/li&gt;
&lt;li&gt;A CLAUDE.md instruction that tells Claude to call the venv&amp;rsquo;s interpreter directly&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;.claude/settings.json&lt;/code&gt; &lt;code&gt;env&lt;/code&gt; block that pre-sets &lt;code&gt;VIRTUAL_ENV&lt;/code&gt; and &lt;code&gt;PATH&lt;/code&gt; for every session&lt;/li&gt;
&lt;li&gt;A PreToolUse hook that blocks bare &lt;code&gt;python&lt;/code&gt; and &lt;code&gt;pip&lt;/code&gt; so the rules are enforced, not just suggested&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Trace why &lt;code&gt;source activate&lt;/code&gt; doesn&amp;rsquo;t persist&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;trace-why-source-activate-doesnt-persist&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#trace-why-source-activate-doesnt-persist&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each Bash tool call Claude Code runs spawns a separate shell process. Environment changes made by &lt;code&gt;source .venv/bin/activate&lt;/code&gt; (it sets &lt;code&gt;VIRTUAL_ENV&lt;/code&gt; and prepends &lt;code&gt;.venv/bin&lt;/code&gt; to &lt;code&gt;PATH&lt;/code&gt;) live only inside that shell. When the next tool call starts a new shell, those variables are gone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Cursor for a uv project</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-cursor-for-a-uv-project/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-cursor-for-a-uv-project/</guid>
      <description>&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes you have a Python project managed with &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv&lt;/a&gt;. If you haven&amp;rsquo;t created a project yet, see the &lt;a href=&#34;https://pydevtools.com/handbook/tutorial/create-your-first-python-project/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;project creation tutorial&lt;/a&gt;.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Cursor is a fork of VS Code, so most Python tooling configuration works the same way. The key difference is Cursor&amp;rsquo;s AI agent, which needs explicit rules to use uv instead of pip. This guide covers both the editor setup and the agent configuration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Cursor rules to use uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-cursor-rules-to-use-uv/</link>
      <pubDate>Wed, 22 Apr 2026 11:52:08 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-cursor-rules-to-use-uv/</guid>
      <description>&lt;p&gt;This guide shows you how to configure &lt;a href=&#34;https://cursor.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cursor&lt;/a&gt; &lt;a href=&#34;https://docs.cursor.com/context/rules&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;editor rules&lt;/a&gt; to automatically use &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; for Python package management instead of &lt;a href=&#34;https://pydevtools.com/handbook/reference/pip/&#34;&gt;pip&lt;/a&gt;. Cursor rules help ensure consistent tooling across your development workflow by providing context to the AI about your project preferences.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://cursor.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cursor editor&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.astral.sh/uv/getting-started/installation/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv installed&lt;/a&gt; on your system&lt;/li&gt;
&lt;li&gt;A uv-based Python project (e.g. created with &lt;code&gt;uv init&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Create Cursor rules to use uv&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;create-cursor-rules-to-use-uv&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#create-cursor-rules-to-use-uv&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;hextra-steps hx:ml-4 hx:mb-12 hx:ltr:border-l hx:rtl:border-r hx:border-gray-200 hx:ltr:pl-6 hx:rtl:pr-6 hx:dark:border-neutral-800 [counter-reset:step]&#34;&gt;
&lt;h3&gt;1. Create a global Cursor rules file&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;1-create-a-global-cursor-rules-file&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#1-create-a-global-cursor-rules-file&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To apply uv rules across all your Python projects, create a global Cursor rules file by opening the Cursor Command Palette (View Menu → Command Palette), search for &amp;ldquo;New Cursor Rule&amp;rdquo;, and create a new rule named &amp;ldquo;uv&amp;rdquo;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure mypy and django-stubs in a uv project</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-mypy-and-django-stubs-in-a-uv-project/</link>
      <pubDate>Tue, 05 May 2026 06:56:59 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-mypy-and-django-stubs-in-a-uv-project/</guid>
      <description>&lt;p&gt;Run &lt;a href=&#34;https://pydevtools.com/handbook/reference/mypy/&#34;&gt;mypy&lt;/a&gt; on a Django project without &lt;code&gt;django-stubs&lt;/code&gt; and the first error is &lt;code&gt;Need type annotation for &amp;quot;name&amp;quot;&lt;/code&gt; on every model field. mypy cannot infer that &lt;code&gt;models.CharField(max_length=200)&lt;/code&gt; resolves to &lt;code&gt;str&lt;/code&gt; or that &lt;code&gt;Question.objects.filter()&lt;/code&gt; returns a &lt;code&gt;QuerySet[Question]&lt;/code&gt;. The &lt;code&gt;django-stubs&lt;/code&gt; package and its bundled mypy plugin fill those gaps.&lt;/p&gt;
&lt;p&gt;This guide installs both with &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; and configures everything from a single &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/a&gt;, with an override pattern for adopting type checking gradually on a legacy Django codebase.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure mypy strict mode</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-mypy-strict-mode/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-mypy-strict-mode/</guid>
      <description>&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes you have a Python project set up with &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv&lt;/a&gt; and &lt;a href=&#34;https://pydevtools.com/handbook/reference/mypy/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;mypy&lt;/a&gt; installed as a dev dependency.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Running &lt;code&gt;mypy&lt;/code&gt; with default settings is lenient. It skips function bodies that lack type annotations and ignores several categories of type errors. Strict mode closes these gaps by requiring annotations on all functions and enabling a curated set of optional checks. The exact flags included in &lt;code&gt;--strict&lt;/code&gt; may change between mypy releases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure recommended Ruff defaults</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-recommended-ruff-defaults/</link>
      <pubDate>Tue, 05 May 2026 16:21:56 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-recommended-ruff-defaults/</guid>
      <description>&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes you have a Python project set up. If you haven&amp;rsquo;t created a project yet, see the &lt;a href=&#34;https://pydevtools.com/handbook/tutorial/create-your-first-python-project/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;project creation tutorial&lt;/a&gt; before proceeding.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This guide shows how to configure &lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt; with a curated set of linting rules that extend beyond the defaults. When starting a new project, it&amp;rsquo;s easier to enable a comprehensive set of rules from the beginning and selectively disable any that don&amp;rsquo;t fit the project&amp;rsquo;s needs, rather than gradually adding rules later when there&amp;rsquo;s already code to fix.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Ruff for Django</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-ruff-for-django/</link>
      <pubDate>Wed, 06 May 2026 06:22:32 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-ruff-for-django/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt;&amp;rsquo;s default rule set knows nothing about Django. It will not flag &lt;code&gt;CharField(null=True)&lt;/code&gt;, but it will flag every long line in an auto-generated migration. This guide fixes that: enable the &lt;code&gt;DJ&lt;/code&gt; rule set, give Ruff the per-file ignores Django&amp;rsquo;s generated code needs, and produce a configuration block that catches Django-specific bugs without burying them under noise.&lt;/p&gt;
&lt;p&gt;This guide assumes a working Django project. Follow &lt;a href=&#34;https://pydevtools.com/handbook/tutorial/set-up-a-django-project-with-uv/&#34;&gt;Set up a Django project with uv&lt;/a&gt; first if there isn&amp;rsquo;t one yet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure Ruff with Claude Code</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-ruff-with-claude-code/</link>
      <pubDate>Wed, 06 May 2026 06:23:27 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-ruff-with-claude-code/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://code.claude.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Claude Code&lt;/a&gt; does not run &lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt; by default, so Python edits land unformatted and lint errors slip through unless you wire Ruff in yourself. Out of the box, Claude often calls bare &lt;code&gt;ruff&lt;/code&gt; (which may resolve outside the project&amp;rsquo;s virtual environment) and skips formatting after edits. Wiring Ruff in correctly takes four layers, each with a different job.&lt;/p&gt;
&lt;p&gt;This guide covers all four and how they stack together:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A CLAUDE.md instruction that points Claude at Ruff&lt;/li&gt;
&lt;li&gt;The Astral plugin&amp;rsquo;s &lt;code&gt;/astral:ruff&lt;/code&gt; skill for on-demand Ruff guidance&lt;/li&gt;
&lt;li&gt;A PostToolUse hook that auto-formats every Python edit&lt;/li&gt;
&lt;li&gt;A &lt;a href=&#34;https://pre-commit.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pre-commit&lt;/a&gt; gate that catches anything Claude missed before commit time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://code.claude.com/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Claude Code&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;A Python project with Ruff added as a dev dependency (&lt;code&gt;uv add --dev ruff&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jq&lt;/code&gt; installed if you want to use the shell version of the auto-format hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Pick the right layer for your goal&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;pick-the-right-layer-for-your-goal&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#pick-the-right-layer-for-your-goal&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each layer answers a different question. Pick the ones that match what you actually need; nothing requires installing all four.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to configure VS Code for a uv project</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-configure-vs-code-for-a-uv-project/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-configure-vs-code-for-a-uv-project/</guid>
      <description>&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes you have a Python project managed with &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv&lt;/a&gt;. If you haven&amp;rsquo;t created a project yet, see the &lt;a href=&#34;https://pydevtools.com/handbook/tutorial/create-your-first-python-project/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;project creation tutorial&lt;/a&gt;.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;VS Code needs three things to work well with a &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; project: the right Python interpreter, a formatter and linter, and a test runner. This guide covers each.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to convert a script with requirements.txt to PEP 723 inline metadata</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-convert-a-script-with-requirements-txt-to-pep-723-inline-metadata/</link>
      <pubDate>Tue, 14 Apr 2026 23:55:39 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-convert-a-script-with-requirements-txt-to-pep-723-inline-metadata/</guid>
      <description>&lt;p&gt;A standalone Python script paired with a &lt;code&gt;requirements.txt&lt;/code&gt; is the old way of saying &amp;ldquo;this script needs these libraries.&amp;rdquo; &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pep-723/&#34;&gt;PEP 723&lt;/a&gt; replaces the sidecar file with a TOML block embedded in the script itself, and &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; reads that block to install dependencies into a temporary &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;virtual environment&lt;/a&gt; on every run.&lt;/p&gt;
&lt;h2&gt;Translate the requirements.txt into inline metadata&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;translate-the-requirementstxt-into-inline-metadata&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#translate-the-requirementstxt-into-inline-metadata&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Point &lt;code&gt;uv add --script&lt;/code&gt; at the existing requirements file. uv reads it and prepends a PEP 723 block to the script:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to create a new Python project with Codex</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-create-a-new-python-project-with-codex/</link>
      <pubDate>Sun, 19 Apr 2026 22:45:37 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-create-a-new-python-project-with-codex/</guid>
      <description>&lt;p&gt;Codex produces consistent project scaffolding when you explicitly point it at the &lt;a href=&#34;https://pydevtools.com/handbook/explanation/modern-python-project-setup-guide-for-ai-assistants/&#34;&gt;Modern Python Project Setup Guide for AI Assistants&lt;/a&gt;. Use the canonical Markdown URL (&lt;code&gt;https://pydevtools.com/handbook/explanation/modern-python-project-setup-guide-for-ai-assistants/index.md&lt;/code&gt;) inside your first prompt so Codex follows the uv-based workflow on macOS, Linux, and Windows.&lt;/p&gt;
&lt;h2&gt;Launch Codex with the guide loaded&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;launch-codex-with-the-guide-loaded&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#launch-codex-with-the-guide-loaded&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;hextra-steps hx:ml-4 hx:mb-12 hx:ltr:border-l hx:rtl:border-r hx:border-gray-200 hx:ltr:pl-6 hx:rtl:pr-6 hx:dark:border-neutral-800 [counter-reset:step]&#34;&gt;
&lt;h3&gt;1. Open a terminal in your repository root&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;1-open-a-terminal-in-your-repository-root&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#1-open-a-terminal-in-your-repository-root&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Codex works best when it starts in the directory that already contains your project files (or the Git repo where the project will live). On macOS/Linux you can &lt;code&gt;cd /path/to/repo&lt;/code&gt;; on Windows use PowerShell&amp;rsquo;s &lt;code&gt;Set-Location&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Create and Distribute a Python CLI Tool</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-create-and-distribute-a-python-cli-tool/</link>
      <pubDate>Mon, 20 Apr 2026 08:25:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-create-and-distribute-a-python-cli-tool/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt; lets you attach any Python function to an executable command name via &lt;code&gt;[project.scripts]&lt;/code&gt;. When someone installs the package, their package manager creates a wrapper script that calls that function. With &lt;a href=&#34;https://pydevtools.com/handbook/reference/uvx/&#34;&gt;uvx&lt;/a&gt;, users can run the tool without even installing it first.&lt;/p&gt;
&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-green-200 hx:bg-green-100 hx:text-green-900 hx:dark:border-green-200/30 hx:dark:bg-green-900/30 hx:dark:text-green-200&#34;&gt;
  &lt;p class=&#34;hx:flex hx:items-center hx:font-medium&#34;&gt;&lt;svg height=16px class=&#34;hx:inline-block hx:align-middle hx:mr-2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z&#34;/&gt;&lt;/svg&gt;Tip&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to create and use a Python virtual environment with venv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-create-and-use-a-python-virtual-environment-with-venv/</link>
      <pubDate>Tue, 21 Apr 2026 08:54:19 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-create-and-use-a-python-virtual-environment-with-venv/</guid>
      <description>&lt;p&gt;A README says &amp;ldquo;create a virtual environment&amp;rdquo; before it tells you what that means. Use Python&amp;rsquo;s built-in &lt;a href=&#34;https://pydevtools.com/handbook/reference/venv/&#34;&gt;&lt;code&gt;venv&lt;/code&gt;&lt;/a&gt; module to create one, activate it, and install packages into the right place. For the concepts, see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;What is a virtual environment?&lt;/a&gt;. For a new project from scratch, &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; handles all of this for you.&lt;/p&gt;
&lt;h2&gt;Create the environment&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;create-the-environment&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#create-the-environment&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run this from your project directory:&lt;/p&gt;






&lt;div class=&#34;hextra-scrollbar hx:overflow-x-auto hx:overflow-y-hidden hx:overscroll-x-contain&#34;&gt;
  &lt;div class=&#34;hx:mt-4 hx:flex hx:w-max hx:min-w-full hx:border-b hx:border-gray-200 hx:pb-px hx:dark:border-neutral-800&#34; role=&#34;tablist&#34;&gt;&lt;button class=&#34;hextra-tabs-toggle hx:cursor-pointer hx:data-[state=selected]:border-primary-500 hx:data-[state=selected]:text-primary-600 hx:data-[state=selected]:dark:border-primary-500 hx:data-[state=selected]:dark:text-primary-600 hx:mr-2 hx:rounded-t hx:p-2 hx:font-medium hx:leading-5 hx:transition-colors hx:-mb-0.5 hx:select-none hx:border-b-2 hx:border-transparent hx:text-gray-600 hx:hover:border-gray-200 hx:hover:text-black hx:dark:text-gray-200 hx:dark:hover:border-neutral-800 hx:dark:hover:text-white hx:hextra-focus-visible-inset&#34; id=&#34;tabs-tab-tabs-03-0&#34; role=&#34;tab&#34; type=&#34;button&#34; aria-controls=&#34;tabs-panel-tabs-03-0&#34; aria-selected=&#34;true&#34; tabindex=&#34;0&#34; data-state=&#34;selected&#34;&gt;&lt;span class=&#34;hx:inline-flex hx:items-center hx:gap-1.5&#34;&gt;&lt;span&gt;macOS/Linux&lt;/span&gt;&lt;/span&gt;&lt;/button&gt;&lt;button class=&#34;hextra-tabs-toggle hx:cursor-pointer hx:data-[state=selected]:border-primary-500 hx:data-[state=selected]:text-primary-600 hx:data-[state=selected]:dark:border-primary-500 hx:data-[state=selected]:dark:text-primary-600 hx:mr-2 hx:rounded-t hx:p-2 hx:font-medium hx:leading-5 hx:transition-colors hx:-mb-0.5 hx:select-none hx:border-b-2 hx:border-transparent hx:text-gray-600 hx:hover:border-gray-200 hx:hover:text-black hx:dark:text-gray-200 hx:dark:hover:border-neutral-800 hx:dark:hover:text-white hx:hextra-focus-visible-inset&#34; id=&#34;tabs-tab-tabs-03-1&#34; role=&#34;tab&#34; type=&#34;button&#34; aria-controls=&#34;tabs-panel-tabs-03-1&#34; aria-selected=&#34;false&#34; tabindex=&#34;-1&#34;&gt;&lt;span class=&#34;hx:inline-flex hx:items-center hx:gap-1.5&#34;&gt;&lt;span&gt;Windows&lt;/span&gt;&lt;/span&gt;&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;div class=&#34;hextra-tabs-panel hx:rounded-sm hx:pt-6 hx:hidden hx:data-[state=selected]:block&#34; id=&#34;tabs-panel-tabs-03-0&#34; role=&#34;tabpanel&#34; aria-labelledby=&#34;tabs-tab-tabs-03-0&#34; aria-hidden=&#34;false&#34; tabindex=&#34;0&#34; data-state=&#34;selected&#34;&gt;&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3 -m venv .venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;hextra-tabs-panel hx:rounded-sm hx:pt-6 hx:hidden hx:data-[state=selected]:block&#34; id=&#34;tabs-panel-tabs-03-1&#34; role=&#34;tabpanel&#34; aria-labelledby=&#34;tabs-tab-tabs-03-1&#34; aria-hidden=&#34;true&#34;&gt;&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;py&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-m&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;venv&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;venv&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If Windows does not recognize &lt;code&gt;py&lt;/code&gt;, use &lt;code&gt;python -m venv .venv&lt;/code&gt; instead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to customize uv&#39;s virtual environment location</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-customize-uvs-virtual-environment-location/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-customize-uvs-virtual-environment-location/</guid>
      <description>&lt;p&gt;When working with uv projects, the virtual environment is automatically created in a folder called &lt;code&gt;.venv&lt;/code&gt; in your project directory.&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;pre&gt;&lt;code&gt;your-project/
├── pyproject.toml
├── .venv/          # Virtual environment location
└── src/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can override this default with a flag or a environmental variable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to deploy a uv project to AWS Lambda</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-deploy-a-uv-project-to-aws-lambda/</link>
      <pubDate>Tue, 05 May 2026 06:55:50 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-deploy-a-uv-project-to-aws-lambda/</guid>
      <description>&lt;p&gt;AWS Lambda packages a Python function as either a zip archive (up to 250 MB unzipped) or a container image (up to 10 GB). Both formats need every dependency the function imports, compiled for Lambda&amp;rsquo;s Linux runtime, with no virtual environment and no &lt;code&gt;pip install&lt;/code&gt; step at runtime. &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; is fast at producing exactly that shape, and its &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-lock-file/&#34;&gt;lockfile&lt;/a&gt; makes the resulting deployment reproducible.&lt;/p&gt;
&lt;h2&gt;Pick a packaging format&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;pick-a-packaging-format&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#pick-a-packaging-format&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Format&lt;/th&gt;
          &lt;th&gt;Pick when&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Container image&lt;/td&gt;
          &lt;td&gt;Production services, dependencies near or above the 250 MB zip limit, native libraries that don&amp;rsquo;t ship manylinux wheels, image-based local testing.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Zip archive&lt;/td&gt;
          &lt;td&gt;Small functions, simple dependencies, fastest cold starts on Python managed runtimes.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Lambda layer + zip&lt;/td&gt;
          &lt;td&gt;Dependencies change rarely, function code changes often.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The zip and layer paths use the same &lt;code&gt;uv export&lt;/code&gt; + &lt;code&gt;uv pip install --target&lt;/code&gt; recipe; only the zip layout differs. The container path uses Lambda&amp;rsquo;s official Python base image and &lt;code&gt;uv pip install&lt;/code&gt; at build time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to distribute internal Python CLI tools with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-distribute-internal-python-cli-tools-with-uv/</link>
      <pubDate>Fri, 24 Apr 2026 16:44:14 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-distribute-internal-python-cli-tools-with-uv/</guid>
      <description>&lt;p&gt;Your team built a CLI. Now you need one install path for teammate laptops and fresh CI runners, plus a coordinated way to push updates. &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; installs the tool from a private index, a git tag, or a wheel, and &lt;code&gt;uv tool install pkg@latest&lt;/code&gt; rolls out upgrades on command.&lt;/p&gt;
&lt;p&gt;This guide picks up where &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-create-and-distribute-a-python-cli-tool/&#34;&gt;How to create and distribute a Python CLI tool&lt;/a&gt; leaves off. That page covers publishing the package; this one covers installing it, pinning it, and keeping it current across a team.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Enable Ruff Security Rules</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-enable-ruff-security-rules/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-enable-ruff-security-rules/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt;&amp;rsquo;s &lt;code&gt;S&lt;/code&gt; rule group implements &lt;a href=&#34;https://docs.astral.sh/ruff/rules/#flake8-bandit-s&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;flake8-bandit&lt;/a&gt; security checks, catching hardcoded passwords, injection vulnerabilities, insecure hashing, and unsafe deserialization before they reach production.&lt;/p&gt;
&lt;h2&gt;Enable the Full Set&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;enable-the-full-set&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#enable-the-full-set&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add the &lt;code&gt;S&lt;/code&gt; group to the project&amp;rsquo;s &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ruff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;extend-select&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;S&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;    &lt;span class=&#34;c&#34;&gt;# flake8-bandit security rules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This enables all flake8-bandit rules at once. Run the linter to see what it finds:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to fix &#34;No `project` Table Found&#34; error in uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-fix-no-project-table-found-error-in-uv/</link>
      <pubDate>Fri, 10 Apr 2026 07:07:14 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-fix-no-project-table-found-error-in-uv/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; project commands (&lt;code&gt;uv run&lt;/code&gt;, &lt;code&gt;uv sync&lt;/code&gt;, &lt;code&gt;uv add&lt;/code&gt;) expect a &lt;code&gt;[project]&lt;/code&gt; table in &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt;. Without one, uv reports:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;pre&gt;&lt;code&gt;error: No `project` table found in: `/path/to/pyproject.toml`&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This happens in two common situations: a repository uses &lt;code&gt;pyproject.toml&lt;/code&gt; only for tool configuration (&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt;, Black, &lt;a href=&#34;https://pydevtools.com/handbook/reference/mypy/&#34;&gt;mypy&lt;/a&gt;) without declaring a project, or a &lt;code&gt;pyproject.toml&lt;/code&gt; was created manually and the &lt;code&gt;[project]&lt;/code&gt; table was omitted.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Fix Common pytest Errors with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-fix-common-pytest-errors-with-uv/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-fix-common-pytest-errors-with-uv/</guid>
      <description>&lt;p&gt;pytest failures that have nothing to do with your actual tests are some of the most frustrating errors in Python development. This guide covers the problems people hit most often when running pytest in &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt;-managed projects and how to fix them.&lt;/p&gt;
&lt;h2&gt;ModuleNotFoundError&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;modulenotfounderror&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#modulenotfounderror&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common pytest error in uv projects. There are several causes.&lt;/p&gt;
&lt;h3&gt;Missing &lt;code&gt;uv sync&lt;/code&gt;&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;missing-uv-sync&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#missing-uv-sync&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you see &lt;code&gt;ModuleNotFoundError&lt;/code&gt; for your own package, the project likely has not been installed into the virtual environment:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Fix ModuleNotFoundError: No module named &#39;numpy&#39; During pip Install</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-fix-modulenotfounderror-no-module-named-numpy-during-pip-install/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-fix-modulenotfounderror-no-module-named-numpy-during-pip-install/</guid>
      <description>&lt;p&gt;This guide helps resolve an issue where a Python package fails to install because it cannot find &lt;code&gt;numpy&lt;/code&gt;, even though it is already installed in your &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;virtual environment&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Problem&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;problem&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#problem&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re trying to install a Python package using:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv pip install git+https://github.com/example/examplepkg.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Even though &lt;code&gt;numpy&lt;/code&gt; is installed in your &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;environment&lt;/a&gt;, the install fails with:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to fix Python version incompatibility errors in uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-fix-python-version-incompatibility-errors-in-uv/</guid>
      <description>&lt;h2&gt;Understanding the Error&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;understanding-the-error&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#understanding-the-error&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you see an error like this:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;pre&gt;&lt;code&gt;error: The Python request from `.python-version` resolved to Python 3.9.1, which is incompatible with the project&amp;#39;s Python requirement: `&amp;gt;=3.10`. Use `uv python pin` to update the `.python-version` file to a compatible version.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to fix the &#34;externally-managed-environment&#34; error</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-fix-the-externally-managed-environment-error/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-fix-the-externally-managed-environment-error/</guid>
      <description>&lt;p&gt;Running &lt;code&gt;pip install&lt;/code&gt; on a system Python protected by &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pep-668/&#34;&gt;PEP 668&lt;/a&gt; produces this error:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;pre&gt;&lt;code&gt;error: externally-managed-environment

× This environment is externally managed&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The fix depends on what was being installed.&lt;/p&gt;
&lt;h2&gt;Installing project dependencies&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;installing-project-dependencies&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#installing-project-dependencies&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; to create a project with its own &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;virtual environment&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to format pyproject.toml with taplo</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-format-pyproject-toml-with-taplo/</link>
      <pubDate>Mon, 20 Apr 2026 08:05:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-format-pyproject-toml-with-taplo/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; does not include a built-in formatter for &lt;code&gt;pyproject.toml&lt;/code&gt;. &lt;a href=&#34;https://taplo.tamasfe.dev/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Taplo&lt;/a&gt; is a TOML formatter and validator that keeps &lt;code&gt;pyproject.toml&lt;/code&gt; files consistently styled across a project.&lt;/p&gt;
&lt;h2&gt;Format with uvx&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;format-with-uvx&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#format-with-uvx&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run taplo as a one-off command without installing it:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uvx taplo fmt pyproject.toml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To check formatting without modifying files (useful in CI):&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to gradually adopt type checking in an existing Python project</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-gradually-adopt-type-checking-in-an-existing-python-project/</link>
      <pubDate>Sat, 25 Apr 2026 22:02:18 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-gradually-adopt-type-checking-in-an-existing-python-project/</guid>
      <description>&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes you have a Python project managed by &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv&lt;/a&gt;. If you haven&amp;rsquo;t created a project yet, see the &lt;a href=&#34;https://pydevtools.com/handbook/tutorial/create-your-first-python-project/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;project creation tutorial&lt;/a&gt; before proceeding.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Running a type checker on an established codebase for the first time produces hundreds or thousands of errors. That wall of red discourages adoption before it starts. The practical path is to check new code strictly while ignoring legacy issues, then shrink the ignore list over time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Host Your Own Python Package Index</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-host-your-own-python-package-index/</link>
      <pubDate>Wed, 29 Apr 2026 07:10:45 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-host-your-own-python-package-index/</guid>
      <description>&lt;p&gt;A self-hosted Python package index can save a team from PyPI outages, vendor lock-in, or restricted networks, but it also gives that team another service to run. Three tools cover almost every use case: &lt;a href=&#34;https://github.com/devpi/devpi&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;devpi&lt;/a&gt; for production multi-team setups, &lt;a href=&#34;https://github.com/pypiserver/pypiserver&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pypiserver&lt;/a&gt; for a small team that needs somewhere to put &lt;code&gt;internal-greeter-0.1.0.whl&lt;/code&gt;, and &lt;a href=&#34;https://github.com/pypa/bandersnatch&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;bandersnatch&lt;/a&gt; for full PyPI mirrors on networks that cannot reach &lt;code&gt;pypi.org&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Hosting an index is the server-side counterpart to &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-use-private-package-indexes-with-uv/&#34;&gt;How to use private package indexes with uv&lt;/a&gt;, which covers the client configuration for managed services like AWS CodeArtifact and JFrog Artifactory.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install bitsandbytes</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-bitsandbytes/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-bitsandbytes/</guid>
      <description>&lt;p&gt;bitsandbytes provides 4-bit and 8-bit quantization for large language models, cutting GPU memory usage enough to run models that would otherwise not fit. Unlike PyTorch (see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt;), bitsandbytes publishes platform-specific wheels to &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pypi/&#34;&gt;PyPI&lt;/a&gt; that bundle precompiled CUDA libraries for multiple toolkit versions. A plain &lt;code&gt;pip install&lt;/code&gt; works on Linux, Windows, and macOS without extra index URLs.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python &amp;gt;= 3.10&lt;/li&gt;
&lt;li&gt;PyTorch &amp;gt;= 2.3 (see &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-install-pytorch-with-uv/&#34;&gt;How to Install PyTorch with uv&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;NVIDIA GPU with compute capability 6.0+ for GPU quantization (Pascal or newer)&lt;/li&gt;
&lt;li&gt;NVIDIA driver that supports CUDA 11.8 or later&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;bitsandbytes also supports CPU-only, AMD ROCm (preview), Intel XPU, and Apple Silicon. GPU quantization requires an NVIDIA GPU.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install DeepSpeed</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-deepspeed/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-deepspeed/</guid>
      <description>&lt;p&gt;DeepSpeed publishes only a source distribution on &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pypi/&#34;&gt;PyPI&lt;/a&gt;, with no prebuilt &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt;. The &lt;code&gt;setup.py&lt;/code&gt; requires both PyTorch and a CUDA toolkit to generate metadata, so even a basic install needs &lt;code&gt;CUDA_HOME&lt;/code&gt; set and &lt;code&gt;nvcc&lt;/code&gt; on &lt;code&gt;PATH&lt;/code&gt;. Once installed, individual ops (fused Adam, CPU offloading, transformer kernels) are compiled on first use through PyTorch&amp;rsquo;s JIT C++ extension system. See &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt; for background.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Platform: Linux (x86_64). Windows has partial support through WSL2. No macOS GPU support.&lt;/li&gt;
&lt;li&gt;Software: PyTorch already installed, a C++ compiler (&lt;code&gt;gcc&lt;/code&gt; or &lt;code&gt;g++&lt;/code&gt;), the CUDA toolkit with &lt;code&gt;nvcc&lt;/code&gt; on &lt;code&gt;PATH&lt;/code&gt;, and &lt;code&gt;CUDA_HOME&lt;/code&gt; set to the toolkit root (e.g. &lt;code&gt;/usr/local/cuda&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;System libraries: &lt;code&gt;libaio-dev&lt;/code&gt; is required for the async I/O op used by ZeRO-Infinity and NVMe offloading. Install it with &lt;code&gt;apt install libaio-dev&lt;/code&gt; on Debian/Ubuntu.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install from PyPI&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;install-from-pypi&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#install-from-pypi&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;DeepSpeed&amp;rsquo;s &lt;code&gt;setup.py&lt;/code&gt; imports &lt;code&gt;torch&lt;/code&gt; at the top level, so PyTorch must be present before installation. The &lt;code&gt;--no-build-isolation&lt;/code&gt; flag tells the installer to use the current environment&amp;rsquo;s torch instead of creating a clean build environment:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install Flash-Attention</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-flash-attention/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-flash-attention/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pypi/&#34;&gt;PyPI&lt;/a&gt; has no &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt; for &lt;code&gt;flash-attn&lt;/code&gt;. Every &lt;code&gt;pip install flash-attn&lt;/code&gt; triggers a from-source CUDA compilation that can take over two hours (see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt; for background). Prebuilt wheels do exist on GitHub Releases, and the package&amp;rsquo;s &lt;code&gt;setup.py&lt;/code&gt; can fetch them automatically if your environment matches.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Platform: Linux on NVIDIA Ampere (A100, RTX 3090), Ada Lovelace (RTX 4090), or Hopper (H100). Windows has experimental support since v2.3.2. No macOS support.&lt;/li&gt;
&lt;li&gt;Software: CUDA toolkit &amp;gt;=12.0 with &lt;code&gt;nvcc&lt;/code&gt; on &lt;code&gt;PATH&lt;/code&gt;, PyTorch &amp;gt;=2.2 already installed in the target environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install with prebuilt wheels (recommended)&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;install-with-prebuilt-wheels-recommended&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#install-with-prebuilt-wheels-recommended&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;flash-attn&lt;/code&gt; package includes a &lt;code&gt;CachedWheelsCommand&lt;/code&gt; in its &lt;code&gt;setup.py&lt;/code&gt; that tries to download a matching prebuilt wheel from GitHub Releases before falling back to compilation. The &lt;code&gt;--no-build-isolation&lt;/code&gt; flag is required because &lt;code&gt;setup.py&lt;/code&gt; imports &lt;code&gt;torch&lt;/code&gt; and &lt;code&gt;packaging&lt;/code&gt; at the top level. Both must be installed in the environment before running the install:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install from a pylock.toml lockfile with pip</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-from-a-pylock-toml-lockfile-with-pip/</link>
      <pubDate>Tue, 28 Apr 2026 08:47:02 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-from-a-pylock-toml-lockfile-with-pip/</guid>
      <description>&lt;p&gt;A teammate hands you a &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pep-751/&#34;&gt;&lt;code&gt;pylock.toml&lt;/code&gt;&lt;/a&gt;. Or &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt;&amp;rsquo;s &lt;code&gt;uv export --format pylock.toml&lt;/code&gt; produces one. Now you need &lt;a href=&#34;https://pydevtools.com/handbook/reference/pip/&#34;&gt;pip&lt;/a&gt; to install from it. As of pip 26.1 (April 2026), &lt;code&gt;pip install -r pylock.toml&lt;/code&gt; works, with a few caveats worth knowing before you put it in CI.&lt;/p&gt;
&lt;h2&gt;Confirm pip 26.1 or newer&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;confirm-pip-261-or-newer&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#confirm-pip-261-or-newer&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-r pylock.toml&lt;/code&gt; form was added in pip 26.1. Older pips will treat the file as a regular requirements file and choke on the first TOML line.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install llama-cpp-python</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-llama-cpp-python/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-llama-cpp-python/</guid>
      <description>&lt;p&gt;PyPI has no prebuilt &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt; for &lt;code&gt;llama-cpp-python&lt;/code&gt;. A bare &lt;code&gt;pip install&lt;/code&gt; downloads a source distribution and compiles it without GPU support, which means inference runs entirely on CPU. To get CUDA or Metal acceleration, the build needs specific CMake flags passed through environment variables, or the install must pull from a separate wheel index that the maintainer publishes.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A C/C++ compiler and CMake are required for building from source. The project&amp;rsquo;s build system expects &lt;code&gt;clang&lt;/code&gt;; on systems where only &lt;code&gt;gcc&lt;/code&gt; is available, install &lt;code&gt;clang&lt;/code&gt; as well (e.g., &lt;code&gt;apt install clang&lt;/code&gt;). On macOS, Xcode command-line tools provide both. On Windows, Visual Studio Build Tools with the &amp;ldquo;Desktop development with C++&amp;rdquo; workload are needed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install Python CLI tools without Python</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-python-cli-tools-without-python/</link>
      <pubDate>Tue, 07 Apr 2026 14:40:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-python-cli-tools-without-python/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://uvx.sh&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uvx.sh&lt;/a&gt; provides installation scripts for any Python tool on PyPI. Use it to install tools like ruff, pre-commit, or pytest without having &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; or Python already installed.&lt;/p&gt;
&lt;h2&gt;Installing a Tool&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;installing-a-tool&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#installing-a-tool&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;






&lt;div class=&#34;hextra-scrollbar hx:overflow-x-auto hx:overflow-y-hidden hx:overscroll-x-contain&#34;&gt;
  &lt;div class=&#34;hx:mt-4 hx:flex hx:w-max hx:min-w-full hx:border-b hx:border-gray-200 hx:pb-px hx:dark:border-neutral-800&#34; role=&#34;tablist&#34;&gt;&lt;button class=&#34;hextra-tabs-toggle hx:cursor-pointer hx:data-[state=selected]:border-primary-500 hx:data-[state=selected]:text-primary-600 hx:data-[state=selected]:dark:border-primary-500 hx:data-[state=selected]:dark:text-primary-600 hx:mr-2 hx:rounded-t hx:p-2 hx:font-medium hx:leading-5 hx:transition-colors hx:-mb-0.5 hx:select-none hx:border-b-2 hx:border-transparent hx:text-gray-600 hx:hover:border-gray-200 hx:hover:text-black hx:dark:text-gray-200 hx:dark:hover:border-neutral-800 hx:dark:hover:text-white hx:hextra-focus-visible-inset&#34; id=&#34;tabs-tab-tabs-01-0&#34; role=&#34;tab&#34; type=&#34;button&#34; aria-controls=&#34;tabs-panel-tabs-01-0&#34; aria-selected=&#34;true&#34; tabindex=&#34;0&#34; data-state=&#34;selected&#34;&gt;&lt;span class=&#34;hx:inline-flex hx:items-center hx:gap-1.5&#34;&gt;&lt;span&gt;macOS/Linux&lt;/span&gt;&lt;/span&gt;&lt;/button&gt;&lt;button class=&#34;hextra-tabs-toggle hx:cursor-pointer hx:data-[state=selected]:border-primary-500 hx:data-[state=selected]:text-primary-600 hx:data-[state=selected]:dark:border-primary-500 hx:data-[state=selected]:dark:text-primary-600 hx:mr-2 hx:rounded-t hx:p-2 hx:font-medium hx:leading-5 hx:transition-colors hx:-mb-0.5 hx:select-none hx:border-b-2 hx:border-transparent hx:text-gray-600 hx:hover:border-gray-200 hx:hover:text-black hx:dark:text-gray-200 hx:dark:hover:border-neutral-800 hx:dark:hover:text-white hx:hextra-focus-visible-inset&#34; id=&#34;tabs-tab-tabs-01-1&#34; role=&#34;tab&#34; type=&#34;button&#34; aria-controls=&#34;tabs-panel-tabs-01-1&#34; aria-selected=&#34;false&#34; tabindex=&#34;-1&#34;&gt;&lt;span class=&#34;hx:inline-flex hx:items-center hx:gap-1.5&#34;&gt;&lt;span&gt;Windows&lt;/span&gt;&lt;/span&gt;&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;div class=&#34;hextra-tabs-panel hx:rounded-sm hx:pt-6 hx:hidden hx:data-[state=selected]:block&#34; id=&#34;tabs-panel-tabs-01-0&#34; role=&#34;tabpanel&#34; aria-labelledby=&#34;tabs-tab-tabs-01-0&#34; aria-hidden=&#34;false&#34; tabindex=&#34;0&#34; data-state=&#34;selected&#34;&gt;&lt;p&gt;Replace &lt;code&gt;{package}&lt;/code&gt; with any PyPI package name:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install Python with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv/</link>
      <pubDate>Mon, 04 May 2026 08:01:44 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; downloads and installs Python interpreters on demand, so you usually don&amp;rsquo;t need to install Python explicitly. Run &lt;code&gt;uv python install&lt;/code&gt; ahead of time to make a version available offline or to put it on your PATH. uv pulls prebuilt CPython binaries from &lt;a href=&#34;https://github.com/astral-sh/python-build-standalone&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;python-build-standalone&lt;/a&gt;, so installs don&amp;rsquo;t need admin privileges and don&amp;rsquo;t replace &lt;a href=&#34;https://pydevtools.com/handbook/explanation/why-should-i-avoid-system-python/&#34;&gt;system Python&lt;/a&gt; or interpreters managed by &lt;a href=&#34;https://pydevtools.com/handbook/reference/homebrew/&#34;&gt;Homebrew&lt;/a&gt; or &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyenv/&#34;&gt;pyenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The same commands work on macOS, Linux, and Windows. You only need &lt;a href=&#34;https://docs.astral.sh/uv/getting-started/installation/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv installed&lt;/a&gt; first.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install PyTorch with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-pytorch-with-uv/</link>
      <pubDate>Thu, 16 Apr 2026 07:09:14 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-pytorch-with-uv/</guid>
      <description>&lt;p&gt;PyTorch publishes different wheel builds for CPU, CUDA, ROCm, and XPU on separate package indexes (see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt; for background). Getting the right build requires telling &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; which index to use.&lt;/p&gt;
&lt;h2&gt;Default behavior without configuration&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;default-behavior-without-configuration&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#default-behavior-without-configuration&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running &lt;code&gt;uv add torch torchvision&lt;/code&gt; with no extra configuration installs from PyPI. PyPI carries CPU-only wheels for Windows and macOS, and CUDA 12.8 wheels for Linux (as of PyTorch 2.9.1). For projects that only need CPU support on Windows/macOS and GPU support on Linux, this default works without any additional setup.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install RAPIDS with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-rapids-with-uv/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-rapids-with-uv/</guid>
      <description>&lt;p&gt;RAPIDS packages live on NVIDIA&amp;rsquo;s own package index, not PyPI (see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt; for background). Getting &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; to find them requires registering that index.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RAPIDS requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux with glibc &amp;gt;= 2.28 (Ubuntu 20.04+, Debian 10+, Fedora 29+). On Windows, use WSL2 on Windows 11. macOS is not supported.&lt;/li&gt;
&lt;li&gt;NVIDIA GPU with compute capability 7.0+ (Volta architecture or newer).&lt;/li&gt;
&lt;li&gt;NVIDIA driver version 525.60.13+ for CUDA 12, or 580.65.06+ for CUDA 13.&lt;/li&gt;
&lt;li&gt;Python 3.10, 3.11, 3.12, or 3.13.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check the installed driver version with:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install the Astral plugins for Claude Code</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-astral-plugins-for-claude-code/</link>
      <pubDate>Fri, 08 May 2026 03:19:33 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-astral-plugins-for-claude-code/</guid>
      <description>&lt;p&gt;Astral publishes an &lt;a href=&#34;https://github.com/astral-sh/claude-code-plugins&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;official Claude Code plugin&lt;/a&gt; that bundles three skills (&lt;code&gt;/astral:uv&lt;/code&gt;, &lt;code&gt;/astral:ruff&lt;/code&gt;, &lt;code&gt;/astral:ty&lt;/code&gt;) and a &lt;a href=&#34;https://pydevtools.com/handbook/reference/ty/&#34;&gt;ty&lt;/a&gt; language server. The skills give Claude up-to-date usage guidance for each tool, and the language server feeds live type-checking diagnostics into the conversation.&lt;/p&gt;
&lt;h2&gt;Prerequisites&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;prerequisites&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#prerequisites&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://claude.com/product/claude-code&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Claude Code&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-install-uv/&#34;&gt;uv installed&lt;/a&gt; (required by the ty language server)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install the plugin for yourself&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;install-the-plugin-for-yourself&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#install-the-plugin-for-yourself&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;hextra-steps hx:ml-4 hx:mb-12 hx:ltr:border-l hx:rtl:border-r hx:border-gray-200 hx:ltr:pl-6 hx:rtl:pr-6 hx:dark:border-neutral-800 [counter-reset:step]&#34;&gt;
&lt;h3&gt;1. Add the Astral marketplace&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;1-add-the-astral-marketplace&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#1-add-the-astral-marketplace&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Run this slash command inside Claude Code:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install Triton</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-triton/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-triton/</guid>
      <description>&lt;p&gt;Triton is OpenAI&amp;rsquo;s open-source compiler for writing GPU kernels in Python. Most users encounter it as a transitive dependency of &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-install-pytorch-with-uv/&#34;&gt;PyTorch&lt;/a&gt;, but it can also be installed standalone for custom kernel development. Triton only ships &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt; for Linux (x86_64 and aarch64). There are no macOS or Windows builds.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux (x86_64 or aarch64). Triton has no wheels for macOS or Windows.&lt;/li&gt;
&lt;li&gt;Python 3.10 or later (up to 3.14).&lt;/li&gt;
&lt;li&gt;glibc 2.27 or later (Ubuntu 18.04+, Debian 10+, RHEL 8+).&lt;/li&gt;
&lt;li&gt;An NVIDIA or AMD GPU with appropriate drivers for running compiled kernels. Triton itself installs without a GPU, but kernels cannot execute without one.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install as a PyTorch dependency (automatic)&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;install-as-a-pytorch-dependency-automatic&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#install-as-a-pytorch-dependency-automatic&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;PyTorch declares Triton as a dependency on Linux x86_64. Installing PyTorch pulls in the matching Triton version automatically:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-uv/</link>
      <pubDate>Fri, 24 Apr 2026 10:27:15 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-uv/</guid>
      <description>&lt;p&gt;You can install &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt;, the fast Python package and project manager, with a standalone installer, with pip, or with package managers like Homebrew, WinGet, and Scoop. The recommended method on every platform is the official standalone installer, because it requires no existing Python interpreter, no package manager, and no other prerequisites.&lt;/p&gt;
&lt;p&gt;You do not need Python installed first. The standalone installer downloads a self-contained uv binary, and uv can then install and manage Python interpreters for you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install uv on Linux</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-linux/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-linux/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; is a fast Python package and project manager. This guide covers how to install it on Linux.&lt;/p&gt;
&lt;h2&gt;Standalone installer (recommended)&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;standalone-installer-recommended&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#standalone-installer-recommended&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The standalone installer is the recommended method because it requires no prerequisites: no Python, no package manager, nothing. It downloads a prebuilt binary and adds it to your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If your system doesn&amp;rsquo;t have &lt;code&gt;curl&lt;/code&gt;, use &lt;code&gt;wget&lt;/code&gt; instead:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install uv on macOS</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-macos/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-macos/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; is a fast Python package and project manager. This guide covers how to install it on macOS.&lt;/p&gt;
&lt;h2&gt;Standalone installer (recommended)&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;standalone-installer-recommended&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#standalone-installer-recommended&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The standalone installer is the recommended method because it requires no prerequisites: no Python, no package manager, nothing. It downloads a prebuilt binary and adds it to your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After running the installer, open a new terminal window so the updated &lt;code&gt;PATH&lt;/code&gt; takes effect.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install uv on Windows</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-windows/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-uv-on-windows/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; is a fast Python package and project manager. This guide covers how to install it on Windows.&lt;/p&gt;
&lt;h2&gt;Standalone installer (recommended)&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;standalone-installer-recommended&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#standalone-installer-recommended&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The standalone installer is the recommended method because it requires no prerequisites: no Python, no package manager, nothing. It downloads a prebuilt binary and adds it to your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Open PowerShell and run:&lt;/p&gt;
&lt;div class=&#34;hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code&#34;&gt;

&lt;div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ExecutionPolicy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ByPass&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;irm https://astral.sh/uv/install.ps1 | iex&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&#34;hextra-code-copy-btn-container  hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0&#34;&gt;
  &lt;button
    class=&#34;hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50&#34;
    title=&#34;Copy code&#34;
    aria-label=&#34;Copy code&#34;
    data-copied-label=&#34;Copied!&#34;
  &gt;
    &lt;div class=&#34;hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
&lt;div class=&#34;hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4&#34;&gt;&lt;/div&gt;
  &lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-ExecutionPolicy ByPass&lt;/code&gt; flag allows running the installation script from the internet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Install xformers</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-install-xformers/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-install-xformers/</guid>
      <description>&lt;p&gt;xformers ships prebuilt &lt;a href=&#34;https://pydevtools.com/handbook/reference/wheel/&#34;&gt;wheels&lt;/a&gt; through the PyTorch package index, not &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-pypi/&#34;&gt;PyPI&lt;/a&gt;. Like PyTorch itself, the correct binary depends on the CUDA version of the target machine (see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/installing-cuda-python-packages/&#34;&gt;Why Installing GPU Python Packages Is So Complicated&lt;/a&gt; for background). Each xformers release is pinned to a specific PyTorch version, so a version mismatch between the two is the most common source of installation failures.&lt;/p&gt;
&lt;h2&gt;Requirements&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;requirements&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#requirements&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux (manylinux_2_28, e.g. Ubuntu 20.04+) or Windows. macOS is not supported.&lt;/li&gt;
&lt;li&gt;NVIDIA GPU with compute capability 8.0+ (Ampere or newer). V100 support was dropped in xformers 0.0.30.&lt;/li&gt;
&lt;li&gt;NVIDIA driver compatible with the target CUDA version.&lt;/li&gt;
&lt;li&gt;Python 3.9 or later.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Version compatibility&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;version-compatibility&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#version-compatibility&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each xformers release requires a specific PyTorch version. Installing the wrong combination produces import errors or silent correctness bugs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to keep Python up to date with uv python upgrade</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-keep-python-up-to-date-with-uv-python-upgrade/</link>
      <pubDate>Sat, 25 Apr 2026 09:07:23 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-keep-python-up-to-date-with-uv-python-upgrade/</guid>
      <description>&lt;p&gt;Run &lt;code&gt;uv python upgrade&lt;/code&gt; to pull the latest patch release for every Python that &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; manages. Pass a minor version (&lt;code&gt;uv python upgrade 3.12&lt;/code&gt;) to scope the upgrade to one line. &lt;a href=&#34;https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment/&#34;&gt;Virtual environments&lt;/a&gt; created from a minor-version pin follow the new patch automatically.&lt;/p&gt;
&lt;p&gt;This keeps uv-managed CPython installs current with security and bug-fix releases. It does not touch &lt;a href=&#34;https://pydevtools.com/handbook/explanation/why-should-i-avoid-system-python/&#34;&gt;system Python&lt;/a&gt; or interpreters installed by &lt;a href=&#34;https://pydevtools.com/handbook/reference/homebrew/&#34;&gt;Homebrew&lt;/a&gt; or &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyenv/&#34;&gt;pyenv&lt;/a&gt;. For installing a new minor version or switching a project, see &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-install-python-with-uv/&#34;&gt;how to install Python with uv&lt;/a&gt; and &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-change-the-python-version-of-a-uv-project/&#34;&gt;how to change the Python version of a uv project&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to manage cross-repository Python dependencies with uv</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-manage-cross-repo-python-dependencies-with-uv/</link>
      <pubDate>Wed, 15 Apr 2026 21:34:41 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-manage-cross-repo-python-dependencies-with-uv/</guid>
      <description>&lt;p&gt;A &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; workspace keeps sibling packages in sync when they live in the same repository. When the packages live in &lt;em&gt;separate&lt;/em&gt; repositories, reach for &lt;code&gt;[tool.uv.sources]&lt;/code&gt; instead. A source override lets each consumer point a dependency at a local checkout, a git ref, or the published version on PyPI without changing the dependency spec itself.&lt;/p&gt;
&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200&#34;&gt;
  &lt;p class=&#34;hx:flex hx:items-center hx:font-medium&#34;&gt;&lt;svg height=16px class=&#34;hx:inline-block hx:align-middle hx:mr-2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z&#34;/&gt;&lt;/svg&gt;Note&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
