<?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 – Ruff</title>
    <link>https://pydevtools.com/handbook/topics/ruff/</link>
    <description>Fast linting and formatting for Python. Configure, integrate, and learn Ruff.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 08 Apr 2026 09:50:55 -0400</lastBuildDate>
    
	  <atom:link href="https://pydevtools.com/handbook/topics/ruff/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Ruff: A Complete Guide to Python&#39;s Fastest Linter and Formatter</title>
      <link>https://pydevtools.com/handbook/explanation/ruff-complete-guide/</link>
      <pubDate>Wed, 06 May 2026 06:22:32 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/explanation/ruff-complete-guide/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt; replaces flake8, &lt;a href=&#34;https://pydevtools.com/handbook/reference/black/&#34;&gt;Black&lt;/a&gt;, isort, pyupgrade, pydocstyle, and dozens of other Python code quality tools with a single binary. It re-implements over 1,000 lint rules from dozens of existing tools and runs 10-100x faster than the tools it replaces.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://astral.sh&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Astral&lt;/a&gt; (the team behind &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; and &lt;a href=&#34;https://pydevtools.com/handbook/reference/ty/&#34;&gt;ty&lt;/a&gt;) builds and maintains Ruff.&lt;/p&gt;
&lt;h2&gt;Why Ruff exists&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;why-ruff-exists&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#why-ruff-exists&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ruff gives Python developers a single tool for linting, formatting, import sorting, and code modernization. One dev dependency, one configuration section in &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyproject.toml/&#34;&gt;pyproject.toml&lt;/a&gt;, one CI step. It ships as a standalone binary with no runtime dependencies, so installation is fast and there are no version conflicts to manage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How do Ruff and Pylint compare?</title>
      <link>https://pydevtools.com/handbook/explanation/how-do-ruff-and-pylint-compare/</link>
      <pubDate>Fri, 01 May 2026 06:58:47 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/explanation/how-do-ruff-and-pylint-compare/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt; and &lt;a href=&#34;https://pydevtools.com/handbook/reference/pylint/&#34;&gt;Pylint&lt;/a&gt; are Python code analysis tools with overlapping but distinct capabilities.&lt;/p&gt;
&lt;h2&gt;Core Differences&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;core-differences&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#core-differences&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;Speed and Architecture&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;speed-and-architecture&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#speed-and-architecture&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ruff&amp;rsquo;s Rust implementation delivers dramatically faster performance than Pylint&amp;rsquo;s Python codebase. This speed advantage becomes particularly noticeable in large codebases where Ruff can analyze files orders of magnitude faster.&lt;/p&gt;
&lt;h3&gt;Rule Coverage&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;rule-coverage&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#rule-coverage&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While Pylint implements approximately 409 rules, Ruff now exceeds 1,000 total rules, with around 209 overlapping with Pylint&amp;rsquo;s ruleset. However, these numbers continue to change, especially as Ruff undergoes rapid development.&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>Wed, 13 May 2026 06:43:22 -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, 13 May 2026 06:43:22 -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, 13 May 2026 06:43:22 -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 Enable Ruff Security Rules</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-enable-ruff-security-rules/</link>
      <pubDate>Wed, 13 May 2026 06:43:22 -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 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>Sat, 16 May 2026 07:30:29 -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 migrate from Black to Ruff formatter</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-migrate-from-black-to-ruff-formatter/</link>
      <pubDate>Wed, 13 May 2026 06:43:22 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-migrate-from-black-to-ruff-formatter/</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;ruff format&lt;/code&gt; command is a drop-in replacement for &lt;a href=&#34;https://pydevtools.com/handbook/reference/black/&#34;&gt;Black&lt;/a&gt;. It follows the same formatting style, reads the same defaults (88-character lines, double quotes, space indentation), and formats 10-100x faster. Ruff also handles linting and import sorting, so the migration is often a chance to consolidate three tools (Black, &lt;a href=&#34;https://pydevtools.com/handbook/reference/flake8/&#34;&gt;flake8&lt;/a&gt;, isort) into one.&lt;/p&gt;
&lt;p&gt;This guide covers translating Black&amp;rsquo;s configuration, reformatting the codebase, updating &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-set-up-pre-commit-hooks-for-a-python-project/&#34;&gt;pre-commit hooks&lt;/a&gt;, and updating CI.&lt;/p&gt;
&lt;h2&gt;Check your starting point&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;check-your-starting-point&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#check-your-starting-point&#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;Commit any pending changes. The migration reformats files, so starting from a clean working tree makes the diff easy to review.&lt;/li&gt;
&lt;li&gt;Note your current Black version. Ruff&amp;rsquo;s formatter tracks Black&amp;rsquo;s stable style; the reformatting diff should be empty or nearly empty if your project already runs a recent Black release.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Add Ruff to the project&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;add-ruff-to-the-project&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#add-ruff-to-the-project&#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 Ruff as a development dependency:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to replace Black, isort, flake8, and pyupgrade with Ruff</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff/</link>
      <pubDate>Wed, 13 May 2026 06:43:22 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://pydevtools.com/handbook/reference/ruff/&#34;&gt;Ruff&lt;/a&gt; replaces &lt;a href=&#34;https://pydevtools.com/handbook/reference/black/&#34;&gt;Black&lt;/a&gt;, isort, &lt;a href=&#34;https://pydevtools.com/handbook/reference/flake8/&#34;&gt;flake8&lt;/a&gt; (with its plugins), and pyupgrade with one binary and one configuration table. This guide walks through the consolidation, including the awkward case of keeping flake8 around to run one in-house custom plugin.&lt;/p&gt;
&lt;p&gt;A typical 2010s Python project assembles its lint stack one tool at a time and ends up with config scattered across &lt;code&gt;pyproject.toml&lt;/code&gt;, &lt;code&gt;setup.cfg&lt;/code&gt;, &lt;code&gt;.flake8&lt;/code&gt;, and &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;. Ruff folds every rule set those tools provided into stable prefix codes inside a single binary. The formatter is Black-compatible and the import sorter matches isort; the &lt;code&gt;UP&lt;/code&gt; category covers what pyupgrade did.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to sort Python imports with Ruff</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-sort-python-imports-with-ruff/</link>
      <pubDate>Wed, 13 May 2026 06:43:22 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-sort-python-imports-with-ruff/</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 uv installed. If you haven&amp;rsquo;t installed uv yet, follow the &lt;a href=&#34;https://docs.astral.sh/uv/getting-started/installation/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;installation instructions&lt;/a&gt; before proceeding.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This guide shows how to automatically organize and sort Python imports using Ruff:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ruff: Python Linter and Formatter</title>
      <link>https://pydevtools.com/handbook/reference/ruff/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/reference/ruff/</guid>
      <description>&lt;p&gt;Ruff is a fast Python linter and code formatter from &lt;a href=&#34;https://astral.sh/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Astral&lt;/a&gt; (the makers of &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;&gt;uv&lt;/a&gt; and &lt;a href=&#34;https://pydevtools.com/handbook/reference/ty/&#34;&gt;ty&lt;/a&gt;). It replaces multiple Python code quality tools (like flake8, &lt;a href=&#34;https://pydevtools.com/handbook/reference/black/&#34;&gt;Black&lt;/a&gt;, isort, and pyupgrade) with a single binary.&lt;/p&gt;
&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-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;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;M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z&#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;Ruff includes over 1,000 built-in lint rules and can replace functionality from more than 20 different Python code quality tools.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;When to use Ruff&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;when-to-use-ruff&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#when-to-use-ruff&#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 Ruff when you want a single, fast tool for linting and formatting Python code instead of maintaining separate configurations for &lt;a href=&#34;https://pydevtools.com/handbook/reference/flake8/&#34;&gt;flake8&lt;/a&gt;, &lt;a href=&#34;https://pydevtools.com/handbook/reference/black/&#34;&gt;Black&lt;/a&gt;, isort, and other code quality tools. It is a strong default for any Python project, from small scripts to large monorepos, because it handles linting, formatting, and import sorting in one pass with minimal configuration. If you need deeper static analysis beyond what lint rules provide, pair Ruff with a type checker like &lt;a href=&#34;https://pydevtools.com/handbook/reference/mypy/&#34;&gt;mypy&lt;/a&gt; or &lt;a href=&#34;https://pydevtools.com/handbook/reference/pyright/&#34;&gt;pyright&lt;/a&gt;; for a comparison with traditional linting, see &lt;a href=&#34;https://pydevtools.com/handbook/explanation/how-do-ruff-and-pylint-compare/&#34;&gt;How do Ruff and Pylint compare?&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Set up Ruff for formatting and checking your code</title>
      <link>https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code/</link>
      <pubDate>Sat, 02 May 2026 08:50:33 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code/</guid>
      <description>&lt;p&gt;This tutorial helps you set up Ruff to automatically format your Python code and check it for common errors and style issues.&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;Before starting, make sure you have uv installed on your system. You can install it following the &lt;a href=&#34;https://docs.astral.sh/uv/getting-started/installation/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;installation guide&lt;/a&gt;.&lt;/p&gt;
&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-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;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;M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z&#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;You do not need Python installed - uv will handle installing it automatically.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Creating a sample project&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;creating-a-sample-project&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#creating-a-sample-project&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s create a new project to demonstrate Ruff:&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
