{"slug": "ruff-v0-16-0", "title": "Ruff v0.16.0", "summary": "Ruff v0.16.0 now enables 413 rules by default, up from 59 in previous versions, according to an announcement from Brent Westbrook. The update, which expands the total rule count from 708 to 968, catches severe issues including syntax errors and immediate runtime errors without requiring configuration. Simon Willison reported that running the tool against his projects Datasette, sqlite-utils, and LLM found hundreds of minor issues, with sqlite-utils alone showing 1,618 errors (1,538 fixed, 80 remaining) after applying fixes.", "body_md": "`\"ruff\"`\n\ndev dependency.\nFrom Brent Westbrook's announcement post:\n\nRuff now enables 413 rules by default, up from 59 in previous versions.\n\nSince Ruff's default rule set was last modified in\n\n[v0.1.0], the number of rules in Ruff has grown from 708 to 968. Many of these rules catch severe issues, including[syntax errors]and[immediate runtime errors]but were not previously enabled by default. With the new rule set, Ruff will bring these issues and many others to your attention without any Ruff configuration.\n\nHere's a one-liner for trying it on any Python project:\n\n```\nuvx ruff@latest check .\n```\n\nI ran the latest Ruff against my three biggest projects - [Datasette](https://datasette.io/), [sqlite-utils](https://sqlite-utils.datasette.io/), and [LLM](https://llm.datasette.io/) - and it found *hundreds* of minor issues that breached the new default rules.\n\nAll three projects have very comprehensive test suites, executed in CI against Python 3.10 through Python 3.14, so upgrades like this are pretty safe. The following command did the bulk of the upgrades:\n\n```\nuvx ruff@latest check . --fix --unsafe-fixes\n```\n\nAgainst `sqlite-utils`\n\n, that command reported:\n\n```\nFound 1618 errors (1538 fixed, 80 remaining).\n```\n\nAs an illustrative example, here are three of the remaining issues. Ruff does a nice job of explaining each one:\n\n``` php\nDTZ005 `datetime.datetime.now()` called without a `tz` argument\n  --> tests/test_duplicate.py:17:10\n   |\n15 |     \"datetime_col\" TEXT)\"\"\")\n16 |     # Insert one row of mock data:\n17 |     dt = datetime.datetime.now()\n   |          ^^^^^^^^^^^^^^^^^^^^^^^\n18 |     data = {\n19 |         \"text_col\": \"Cleo\",\n   |\nhelp: Pass a `datetime.timezone` object to the `tz` parameter\n\nBLE001 Do not catch blind exception: `Exception`\n  --> tests/test_plugins.py:16:12\n   |\n14 |         db.execute(\"select * from pragma_function_list()\")\n15 |         return True\n16 |     except Exception:\n   |            ^^^^^^^^^\n17 |         return False\n18 |     finally:\n   |\n\nB018 Found useless attribute access. Either assign it to a variable or remove it.\n  --> tests/test_update.py:46:5\n   |\n44 | def test_update_invalid_pk(fresh_db, pk, update_pk):\n45 |     table = fresh_db[\"table\"]\n46 |     table.insert({\"id1\": 5, \"id2\": 3, \"v\": 1}, pk=pk).last_pk\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n47 |     with pytest.raises(NotFoundError):\n48 |         table.update(update_pk, {\"v\": 2})\n   |\n```\n\nUnsurprisingly, given Astral's [new home at OpenAI](https://simonwillison.net/2026/Mar/19/openai-acquiring-astral/), this output provides everything a coding agent would need to fix the problems.\n\nI had Codex (GPT-5.6 Sol high) [upgrade LLM](https://github.com/simonw/llm/pull/1557) and [sqlite-utils](https://github.com/simonw/sqlite-utils/pull/814), and Claude Code (with Opus 5) [upgrade Datasette](https://github.com/simonw/datasette/pull/2857).", "url": "https://wpnews.pro/news/ruff-v0-16-0", "canonical_source": "https://simonwillison.net/2026/Jul/25/ruff/#atom-everything", "published_at": "2026-07-25 22:44:05+00:00", "updated_at": "2026-07-25 22:55:43.817297+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Ruff", "Brent Westbrook", "Astral", "OpenAI", "Datasette", "sqlite-utils", "LLM", "Simon Willison"], "alternates": {"html": "https://wpnews.pro/news/ruff-v0-16-0", "markdown": "https://wpnews.pro/news/ruff-v0-16-0.md", "text": "https://wpnews.pro/news/ruff-v0-16-0.txt", "jsonld": "https://wpnews.pro/news/ruff-v0-16-0.jsonld"}}