)]}'
{
  "log": [
    {
      "commit": "b089d17e34a9f8037b9fe968ca9d536c0b875d7f",
      "tree": "05ad4e4c850e63274862a660b9e03fb1c4aea872",
      "parents": [
        "f9a7e8a171c090b15d6afb149c6549d9152cbfc7"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Nov 12 04:44:33 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 12 04:44:33 2026 +0000"
      },
      "message": "build(deps-dev): Bump the \"dev-only\" group with 1 update across multiple ecosystems (#4479)\n\nBumps the dev-only group with 1 update in the /examples/wheel directory:\n[pypiserver](https://github.com/pypiserver/pypiserver).\nBumps the dev-only group with 1 update in the\n/tests/integration/unified_pypi directory:\n[colorama](https://github.com/tartley/colorama).\nBumps the dev-only group with 1 update in the /tests/multi_pypi/alpha\ndirectory:\n[more-itertools](https://github.com/more-itertools/more-itertools).\nBumps the dev-only group with 1 update in the /tests/multi_pypi/beta\ndirectory:\n[more-itertools](https://github.com/more-itertools/more-itertools).\n\nUpdates `pypiserver` from 2.4.2 to 2.4.3\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/releases\"\u003epypiserver\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev2.4.3\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e[!NOTE]\nA few maintenance updates and fixes.\nThanks to all who helped improving the repo these times!\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2\u003eSummary:\u003c/h2\u003e\n\u003cp\u003eCore focus:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eimportant version updates\u003c/li\u003e\n\u003cli\u003ebug fixes in version lookup\u003c/li\u003e\n\u003cli\u003eupdate in documentation\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2\u003eWhat\u0027s Changed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003echore: Bump urllib3 from 2.7.0 to 2.8.0 by \u003ca\nhref\u003d\"https://github.com/dependabot\"\u003e\u003ccode\u003e@​dependabot\u003c/code\u003e\u003c/a\u003e[bot]\nin \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/737\"\u003epypiserver/pypiserver#737\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003echore: Bump setuptools from 80.10.2 to 84.1.0 by \u003ca\nhref\u003d\"https://github.com/dependabot\"\u003e\u003ccode\u003e@​dependabot\u003c/code\u003e\u003c/a\u003e[bot]\nin \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/739\"\u003epypiserver/pypiserver#739\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003echore: Bump certifi from 2026.2.25 to 2026.10.19 by \u003ca\nhref\u003d\"https://github.com/dependabot\"\u003e\u003ccode\u003e@​dependabot\u003c/code\u003e\u003c/a\u003e[bot]\nin \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/738\"\u003epypiserver/pypiserver#738\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eDocs: update ad-hoc authentication example to use roots by \u003ca\nhref\u003d\"https://github.com/rohansharmacode\"\u003e\u003ccode\u003e@​rohansharmacode\u003c/code\u003e\u003c/a\u003e\nin \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/734\"\u003epypiserver/pypiserver#734\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003efix: normalize project names in find_version for remove_pkg by \u003ca\nhref\u003d\"https://github.com/r3wretrhy\"\u003e\u003ccode\u003e@​r3wretrhy\u003c/code\u003e\u003c/a\u003e in \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/735\"\u003epypiserver/pypiserver#735\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003echore(auto-release-candidate-2026-11-08) by \u003ca\nhref\u003d\"https://github.com/github-actions\"\u003e\u003ccode\u003e@​github-actions\u003c/code\u003e\u003c/a\u003e[bot]\nin \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/742\"\u003epypiserver/pypiserver#742\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eNew Contributors\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/rohansharmacode\"\u003e\u003ccode\u003e@​rohansharmacode\u003c/code\u003e\u003c/a\u003e\nmade their first contribution in \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/734\"\u003epypiserver/pypiserver#734\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/r3wretrhy\"\u003e\u003ccode\u003e@​r3wretrhy\u003c/code\u003e\u003c/a\u003e\nmade their first contribution in \u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/pull/735\"\u003epypiserver/pypiserver#735\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eFull Changelog\u003c/strong\u003e: \u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/compare/v2.4.2...v2.4.3\"\u003ehttps://github.com/pypiserver/pypiserver/compare/v2.4.2...v2.4.3\u003c/a\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/blob/main/CHANGES.rst\"\u003epypiserver\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e2.4.3 (2026-11-08)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003edeedae4 FIX: fix: passing formatting flags in CI\u003c/li\u003e\n\u003cli\u003e4885eea FIX: fix: normalize project names in find_version for\nremove_pkg (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/735\"\u003e#735\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eaf839b9 MAINT: Docs: update ad-hoc authentication example to use\nroots (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/734\"\u003e#734\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e57eb6a6 MAINT: chore: Bump certifi from 2026.2.25 to 2026.10.19 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/738\"\u003e#738\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e37dc266 MAINT: chore: Bump setuptools from 80.10.2 to 84.1.0 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/739\"\u003e#739\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e69f750c MAINT: chore: Bump urllib3 from 2.7.0 to 2.8.0 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/737\"\u003e#737\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/14d1e994dc4160ffb1cd36191a72dc5005cb9aef\"\u003e\u003ccode\u003e14d1e99\u003c/code\u003e\u003c/a\u003e\nchore(ver): bump 2.4.2--\u0026gt;2.4.3\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/7ebc668a04bcfa6869482e75aa2d838b40a462cd\"\u003e\u003ccode\u003e7ebc668\u003c/code\u003e\u003c/a\u003e\nchore(auto-release-candidate-2026-11-08) (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/742\"\u003e#742\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/deedae4f2a9c6a0a4f582d98bc58622febc1fcbb\"\u003e\u003ccode\u003edeedae4\u003c/code\u003e\u003c/a\u003e\nfix: passing formatting flags in CI\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/4885eea587675d26bd60c81a543b9fed3cd062c9\"\u003e\u003ccode\u003e4885eea\u003c/code\u003e\u003c/a\u003e\nfix: normalize project names in find_version for remove_pkg (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/735\"\u003e#735\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/af839b9d80b4103b83cbbc32c6de80358aaaddaf\"\u003e\u003ccode\u003eaf839b9\u003c/code\u003e\u003c/a\u003e\nDocs: update ad-hoc authentication example to use roots (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/734\"\u003e#734\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/57eb6a6d4d802e63f280403e34ee53c4d0fb6fa1\"\u003e\u003ccode\u003e57eb6a6\u003c/code\u003e\u003c/a\u003e\nchore: Bump certifi from 2026.2.25 to 2026.10.19 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/738\"\u003e#738\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/37dc26619d0ad94e313a3879ec74525b0d64f5e5\"\u003e\u003ccode\u003e37dc266\u003c/code\u003e\u003c/a\u003e\nchore: Bump setuptools from 80.10.2 to 84.1.0 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/739\"\u003e#739\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/commit/69f750cd8fe5d8ad827fb4a19ee7b37ad0147622\"\u003e\u003ccode\u003e69f750c\u003c/code\u003e\u003c/a\u003e\nchore: Bump urllib3 from 2.7.0 to 2.8.0 (\u003ca\nhref\u003d\"https://redirect.github.com/pypiserver/pypiserver/issues/737\"\u003e#737\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/pypiserver/pypiserver/compare/v2.4.2...v2.4.3\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `colorama` from 0.4.5 to 0.4.6\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/tartley/colorama/blob/master/CHANGELOG.rst\"\u003ecolorama\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e0.4.6 Current release\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/tartley/colorama/pull/139\"\u003etartley/colorama#139\u003c/a\u003e\nAdd alternative to \u0027init()\u0027,\ncalled \u0027just_fix_windows_console\u0027. This fixes many longstanding problems\nwith \u0027init\u0027, such as working incorrectly on modern Windows terminals,\nand\nwonkiness when init gets called multiple times. The intention is that it\njust makes all Windows terminals treat ANSI the same way as other\nterminals\ndo. Many thanks the njsmith for fixing our messes.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/tartley/colorama/pull/352\"\u003etartley/colorama#352\u003c/a\u003e\nSupport Windows 10\u0027s ANSI/VT\nconsole. This didn\u0027t exist when Colorama was created, and avoiding us\ncausing havok there is long overdue. Thanks to segeviner for the initial\napproach, and to njsmith for getting it merged.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/tartley/colorama/pull/338\"\u003etartley/colorama#338\u003c/a\u003e\nInternal overhaul of package\nmetadata declaration, which abolishes our use of the now heavily\ndiscouraged setuptools (and hence setup.py, setup.cfg and MANIFEST.in),\nin\nfavor of hatchling (and hence pyproject.toml), generously contributed by\nofek (author of hatchling). This includes dropping support Python3.5 and\n3.6, which are EOL, and were already dropped from setuptools, so this\nshould not affect our users.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/tartley/colorama/pull/353\"\u003etartley/colorama#353\u003c/a\u003e\nAttention to detail award to\nLqdBcnAtWork for a spelling fix in demo06\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/3de9f013df4b470069d03d250224062e8cf15c49\"\u003e\u003ccode\u003e3de9f01\u003c/code\u003e\u003c/a\u003e\nbump version 0.4.6\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/a45949b3252633060261c9666b6aada4b2f2f020\"\u003e\u003ccode\u003ea45949b\u003c/code\u003e\u003c/a\u003e\nFormat the CHANGELOG bullet list, no content change\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/f55f72e9d3950276679da91ba6dc713cefc603db\"\u003e\u003ccode\u003ef55f72e\u003c/code\u003e\u003c/a\u003e\ncomment need for a fix after recent MP broke it\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/cb83041b25a6962d8124647e8741cfa0ab139994\"\u003e\u003ccode\u003ecb83041\u003c/code\u003e\u003c/a\u003e\nfix test-release after recent MPs broke it\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/832f14ce9a4d00c2dfb88e8cb02e2defadb76ba9\"\u003e\u003ccode\u003e832f14c\u003c/code\u003e\u003c/a\u003e\nREADME tweaks\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/54b89c33b2448a1a0fab67ab020a902622b9a932\"\u003e\u003ccode\u003e54b89c3\u003c/code\u003e\u003c/a\u003e\nBump version to 0.4.6rc1\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/7991d34773c72db791eb09d9ec349212d080fbc0\"\u003e\u003ccode\u003e7991d34\u003c/code\u003e\u003c/a\u003e\n\u0027make bootstrap\u0027 uses system python3, not pinned v3.8\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/0ae5ef2f9ab89335fb5b50933b75323178cb38bc\"\u003e\u003ccode\u003e0ae5ef2\u003c/code\u003e\u003c/a\u003e\nCHANGELOG updates for upcoming 0.4.6 release\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/52f4cfd7af3a779b0ba8a7ee320d99c0bfec9ce8\"\u003e\u003ccode\u003e52f4cfd\u003c/code\u003e\u003c/a\u003e\nTweak ordering of release checklist\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/tartley/colorama/commit/ab64cfac23fd70b9bf2944acd985e3673a1f09e1\"\u003e\u003ccode\u003eab64cfa\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/tartley/colorama/issues/353\"\u003e#353\u003c/a\u003e\nfrom LqdBcnAtWork/patch-1\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/tartley/colorama/compare/0.4.5...0.4.6\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `more-itertools` from 9.1.0 to 11.2.1\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/releases\"\u003emore-itertools\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003eVersion 11.2.1\u003c/h2\u003e\n\u003cp\u003eThis release includes \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1331\"\u003e#1331\u003c/a\u003e,\na packaging-related change. No module code changed.\u003c/p\u003e\n\u003ch2\u003eVersion 11.2.0\u003c/h2\u003e\n\u003cp\u003eHighlights:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eNew \u003ccode\u003erandom_ordered_range\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003esubfactorial\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003ePython 3.10 is no longer officially supported\u003c/li\u003e\n\u003cli\u003ePython 3.15 is now officially supported\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSee the \u003ca\nhref\u003d\"https://raw.githubusercontent.com/more-itertools/more-itertools/737c261c21271e1a6eb949f7d188297bebe8b125/docs/versions.rst\"\u003erelease\nnotes\u003c/a\u003e for details.\u003c/p\u003e\n\u003ch2\u003eVersion 11.1.0\u003c/h2\u003e\n\u003cp\u003eChanges:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003enumeric_range\u003c/code\u003e was updated to fix its handling of empty\nranges (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epeekable\u003c/code\u003e was updated to fix typing issues (thanks to\nDORI2001, powellnorma, Pandede, m9810223, and rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eislice_extended\u003c/code\u003e was optimized for memory usage and\nspeed (thanks to ben42code, rhettinger, and pochmann)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eserialize\u003c/code\u003e now supports the generator methods\n\u003ccode\u003ethrow\u003c/code\u003e, \u003ccode\u003esend\u003c/code\u003e, and \u003ccode\u003eclose\u003c/code\u003e (thanks to\nrhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eseekable\u003c/code\u003e now supports implements\n\u003ccode\u003e__getitem__\u003c/code\u003e for cached elements (thanks to SAY-5,\njenstroeger, and JamesParrott)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eVersion 11.0.2\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eThe changes to the type hints for \u003ccode\u003ealways_iterable\u003c/code\u003e in\n11.0.0 have been reverted due to reported problems (thanks to ngoldbaum\nand rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ezip_equal\u003c/code\u003e was removed in 11.0.0. It had been deprecated\nand raising \u003ccode\u003eDeprecationWarning\u003c/code\u003e since 2021, but it\u0027s removal\nshoul have been documented in 11.0.0\u0027s release notes. We regret the\nerror.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erunning_statistics\u003c/code\u003e has been moved from\n\u003ccode\u003emore_itertools.more\u003c/code\u003e to \u003ccode\u003emore_itertools.recipes\u003c/code\u003e.\nIts docstring was also improved (thanks to mastash3ff and\nrhettinger)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eVersion 11.0.1\u003c/h2\u003e\n\u003cp\u003eThis release restores \u003ccode\u003epairwise\u003c/code\u003e, which was mistakenly\nremoved in 11.0.0 instead of being deprecated. It is now marked as\ndeprecated and will be removed in a future major release. Use\n\u003ccode\u003eitertools.pairwise\u003c/code\u003e as a replacement.\u003c/p\u003e\n\u003ch2\u003eVersion 11.0.0\u003c/h2\u003e\n\u003ch3\u003ePotentially breaking changes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003ePython 3.9 support was dropped, since it went EOL on 2025-10-31\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecallback_iter\u003c/code\u003e is deprecated. It will be removed in a\nfuture major release.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eiequals\u003c/code\u003e no longer returns \u003ccode\u003eTrue\u003c/code\u003e when called\nwith \u003ccode\u003e([], [ANY])\u003c/code\u003e (thanks to rhettinger and pochmann3)\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003epred\u003c/code\u003e argument for \u003ccode\u003elocate\u003c/code\u003e and\n\u003ccode\u003ereplace\u003c/code\u003e must now be able to\nhandle a variable number of arguments. See their docstrings for details.\n(thanks to veeceey, james-wasson, and pochmann3)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eunique_everseen\u003c/code\u003e now raises \u003ccode\u003eTypeError\u003c/code\u003e when\ninput elements are not hashable.\nThe silent fallback mechanism for unhashable inputs has been removed.\n(thanks to rhettinger and karlicoss)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewindowed\u003c/code\u003e now raises \u003ccode\u003eValueError\u003c/code\u003e when given\na window size of \u003ccode\u003e0\u003c/code\u003e (thanks to rhettinger and brevzin)\u003c/li\u003e\n\u003cli\u003eParameter names for \u003ccode\u003eflatten\u003c/code\u003e, \u003ccode\u003eiter_except\u003c/code\u003e,\n\u003ccode\u003erepeatfunc\u003c/code\u003e, \u003ccode\u003eprepend\u003c/code\u003e, \u003ccode\u003etranspose\u003c/code\u003e,\nand \u003ccode\u003esum_of_squares\u003c/code\u003e have been changed. Code that uses these\nfunctions will need to be updated if it\nuses keywords for positional arguments. (thanks to rhettinger)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eNew functions\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003econcurrent_tee\u003c/code\u003e: similar to \u003ccode\u003etee\u003c/code\u003e, but with\nguaranteed threading\nsemantics (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erandom_derangement\u003c/code\u003e: returns a random derangement of\nelements from an\niterable (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erunning_mean\u003c/code\u003e: yields the mean of values in an iterable,\nor in a sliding\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/4aeb4338ae1407d8da9723e86da99efeb446f719\"\u003e\u003ccode\u003e4aeb433\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1331\"\u003e#1331\u003c/a\u003e\nfrom more-itertools/flit-4-sdist\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/da864da6d8beaa49d693b719cbc21a5d88dfb475\"\u003e\u003ccode\u003eda864da\u003c/code\u003e\u003c/a\u003e\nVersion 11.2.1: Include additional files in sdist\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/737c261c21271e1a6eb949f7d188297bebe8b125\"\u003e\u003ccode\u003e737c261\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1314\"\u003e#1314\u003c/a\u003e\nfrom more-itertools/version-11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/909b70336ce229088bbc253d300190c99fb8411a\"\u003e\u003ccode\u003e909b703\u003c/code\u003e\u003c/a\u003e\nBump version to 11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/6ad55cbedd2cd722a9c029e5823177622910771a\"\u003e\u003ccode\u003e6ad55cb\u003c/code\u003e\u003c/a\u003e\nSwap 310 for 315 in tox\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/787bcb5c9faf800da3fdc72c1023c1aab24572dc\"\u003e\u003ccode\u003e787bcb5\u003c/code\u003e\u003c/a\u003e\nDrop typing_extensions for more.pyi\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/68a52e07369f3515bd9a0d5f31555429e16fcc54\"\u003e\u003ccode\u003e68a52e0\u003c/code\u003e\u003c/a\u003e\nUpdate versions.rst\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/be6ecc015e03f48c0a50f07ce6079f636c9753a4\"\u003e\u003ccode\u003ebe6ecc0\u003c/code\u003e\u003c/a\u003e\nChangelog tweaks\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/45c65a3dc532dadf014d53bcaa0c2f38cbeacfe1\"\u003e\u003ccode\u003e45c65a3\u003c/code\u003e\u003c/a\u003e\nEven more WIP release notes for 11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/56a469cd7f3522d2f391060957b02be81809afb5\"\u003e\u003ccode\u003e56a469c\u003c/code\u003e\u003c/a\u003e\nMore WIP release ntoes 11.2.0\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/compare/v9.1.0...v11.2.1\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `more-itertools` from 9.0.0 to 11.2.1\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/releases\"\u003emore-itertools\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003eVersion 11.2.1\u003c/h2\u003e\n\u003cp\u003eThis release includes \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1331\"\u003e#1331\u003c/a\u003e,\na packaging-related change. No module code changed.\u003c/p\u003e\n\u003ch2\u003eVersion 11.2.0\u003c/h2\u003e\n\u003cp\u003eHighlights:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eNew \u003ccode\u003erandom_ordered_range\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003eNew \u003ccode\u003esubfactorial\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003ePython 3.10 is no longer officially supported\u003c/li\u003e\n\u003cli\u003ePython 3.15 is now officially supported\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSee the \u003ca\nhref\u003d\"https://raw.githubusercontent.com/more-itertools/more-itertools/737c261c21271e1a6eb949f7d188297bebe8b125/docs/versions.rst\"\u003erelease\nnotes\u003c/a\u003e for details.\u003c/p\u003e\n\u003ch2\u003eVersion 11.1.0\u003c/h2\u003e\n\u003cp\u003eChanges:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003enumeric_range\u003c/code\u003e was updated to fix its handling of empty\nranges (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epeekable\u003c/code\u003e was updated to fix typing issues (thanks to\nDORI2001, powellnorma, Pandede, m9810223, and rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eislice_extended\u003c/code\u003e was optimized for memory usage and\nspeed (thanks to ben42code, rhettinger, and pochmann)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eserialize\u003c/code\u003e now supports the generator methods\n\u003ccode\u003ethrow\u003c/code\u003e, \u003ccode\u003esend\u003c/code\u003e, and \u003ccode\u003eclose\u003c/code\u003e (thanks to\nrhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eseekable\u003c/code\u003e now supports implements\n\u003ccode\u003e__getitem__\u003c/code\u003e for cached elements (thanks to SAY-5,\njenstroeger, and JamesParrott)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eVersion 11.0.2\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eThe changes to the type hints for \u003ccode\u003ealways_iterable\u003c/code\u003e in\n11.0.0 have been reverted due to reported problems (thanks to ngoldbaum\nand rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ezip_equal\u003c/code\u003e was removed in 11.0.0. It had been deprecated\nand raising \u003ccode\u003eDeprecationWarning\u003c/code\u003e since 2021, but it\u0027s removal\nshoul have been documented in 11.0.0\u0027s release notes. We regret the\nerror.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erunning_statistics\u003c/code\u003e has been moved from\n\u003ccode\u003emore_itertools.more\u003c/code\u003e to \u003ccode\u003emore_itertools.recipes\u003c/code\u003e.\nIts docstring was also improved (thanks to mastash3ff and\nrhettinger)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eVersion 11.0.1\u003c/h2\u003e\n\u003cp\u003eThis release restores \u003ccode\u003epairwise\u003c/code\u003e, which was mistakenly\nremoved in 11.0.0 instead of being deprecated. It is now marked as\ndeprecated and will be removed in a future major release. Use\n\u003ccode\u003eitertools.pairwise\u003c/code\u003e as a replacement.\u003c/p\u003e\n\u003ch2\u003eVersion 11.0.0\u003c/h2\u003e\n\u003ch3\u003ePotentially breaking changes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003ePython 3.9 support was dropped, since it went EOL on 2025-10-31\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecallback_iter\u003c/code\u003e is deprecated. It will be removed in a\nfuture major release.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eiequals\u003c/code\u003e no longer returns \u003ccode\u003eTrue\u003c/code\u003e when called\nwith \u003ccode\u003e([], [ANY])\u003c/code\u003e (thanks to rhettinger and pochmann3)\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003epred\u003c/code\u003e argument for \u003ccode\u003elocate\u003c/code\u003e and\n\u003ccode\u003ereplace\u003c/code\u003e must now be able to\nhandle a variable number of arguments. See their docstrings for details.\n(thanks to veeceey, james-wasson, and pochmann3)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eunique_everseen\u003c/code\u003e now raises \u003ccode\u003eTypeError\u003c/code\u003e when\ninput elements are not hashable.\nThe silent fallback mechanism for unhashable inputs has been removed.\n(thanks to rhettinger and karlicoss)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewindowed\u003c/code\u003e now raises \u003ccode\u003eValueError\u003c/code\u003e when given\na window size of \u003ccode\u003e0\u003c/code\u003e (thanks to rhettinger and brevzin)\u003c/li\u003e\n\u003cli\u003eParameter names for \u003ccode\u003eflatten\u003c/code\u003e, \u003ccode\u003eiter_except\u003c/code\u003e,\n\u003ccode\u003erepeatfunc\u003c/code\u003e, \u003ccode\u003eprepend\u003c/code\u003e, \u003ccode\u003etranspose\u003c/code\u003e,\nand \u003ccode\u003esum_of_squares\u003c/code\u003e have been changed. Code that uses these\nfunctions will need to be updated if it\nuses keywords for positional arguments. (thanks to rhettinger)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eNew functions\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003econcurrent_tee\u003c/code\u003e: similar to \u003ccode\u003etee\u003c/code\u003e, but with\nguaranteed threading\nsemantics (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erandom_derangement\u003c/code\u003e: returns a random derangement of\nelements from an\niterable (thanks to rhettinger)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erunning_mean\u003c/code\u003e: yields the mean of values in an iterable,\nor in a sliding\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/4aeb4338ae1407d8da9723e86da99efeb446f719\"\u003e\u003ccode\u003e4aeb433\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1331\"\u003e#1331\u003c/a\u003e\nfrom more-itertools/flit-4-sdist\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/da864da6d8beaa49d693b719cbc21a5d88dfb475\"\u003e\u003ccode\u003eda864da\u003c/code\u003e\u003c/a\u003e\nVersion 11.2.1: Include additional files in sdist\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/737c261c21271e1a6eb949f7d188297bebe8b125\"\u003e\u003ccode\u003e737c261\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/more-itertools/more-itertools/issues/1314\"\u003e#1314\u003c/a\u003e\nfrom more-itertools/version-11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/909b70336ce229088bbc253d300190c99fb8411a\"\u003e\u003ccode\u003e909b703\u003c/code\u003e\u003c/a\u003e\nBump version to 11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/6ad55cbedd2cd722a9c029e5823177622910771a\"\u003e\u003ccode\u003e6ad55cb\u003c/code\u003e\u003c/a\u003e\nSwap 310 for 315 in tox\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/787bcb5c9faf800da3fdc72c1023c1aab24572dc\"\u003e\u003ccode\u003e787bcb5\u003c/code\u003e\u003c/a\u003e\nDrop typing_extensions for more.pyi\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/68a52e07369f3515bd9a0d5f31555429e16fcc54\"\u003e\u003ccode\u003e68a52e0\u003c/code\u003e\u003c/a\u003e\nUpdate versions.rst\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/be6ecc015e03f48c0a50f07ce6079f636c9753a4\"\u003e\u003ccode\u003ebe6ecc0\u003c/code\u003e\u003c/a\u003e\nChangelog tweaks\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/45c65a3dc532dadf014d53bcaa0c2f38cbeacfe1\"\u003e\u003ccode\u003e45c65a3\u003c/code\u003e\u003c/a\u003e\nEven more WIP release notes for 11.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/commit/56a469cd7f3522d2f391060957b02be81809afb5\"\u003e\u003ccode\u003e56a469c\u003c/code\u003e\u003c/a\u003e\nMore WIP release ntoes 11.2.0\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/more-itertools/more-itertools/compare/v9.1.0...v11.2.1\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore \u003cdependency name\u003e major version` will close this\ngroup update PR and stop Dependabot creating any more for the specific\ndependency\u0027s major version (unless you unignore this specific\ndependency\u0027s major version or upgrade to it yourself)\n- `@dependabot ignore \u003cdependency name\u003e minor version` will close this\ngroup update PR and stop Dependabot creating any more for the specific\ndependency\u0027s minor version (unless you unignore this specific\ndependency\u0027s minor version or upgrade to it yourself)\n- `@dependabot ignore \u003cdependency name\u003e` will close this group update PR\nand stop Dependabot creating any more for the specific dependency\n(unless you unignore this specific dependency or upgrade to it yourself)\n- `@dependabot unignore \u003cdependency name\u003e` will remove all of the ignore\nconditions of the specified dependency\n- `@dependabot unignore \u003cdependency name\u003e \u003cignore condition\u003e` will\nremove the ignore condition of the specified dependency and ignore\nconditions\n\n\n\u003c/details\u003e\n\n---------\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "f9a7e8a171c090b15d6afb149c6549d9152cbfc7",
      "tree": "da36869ef35c4cd44d769478c322080e96a6d265",
      "parents": [
        "71573b1e3f4c8946c5db2f5292b1815b7c9a96dd"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Nov 10 22:03:31 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 10 22:03:31 2026 -0800"
      },
      "message": "workflows: use ubuntu-latest in release_build_artifacts.yaml (#4475)\n\nPinning `ubuntu-24.04` in `release_build_artifacts.yaml` diverges from\nthe rest of our GitHub Actions workflows, which use `ubuntu-latest`.\n\nSwitch the Ubuntu jobs in `release_build_artifacts.yaml` to\n`ubuntu-latest`. Linux release binaries cross-compile statically against\n`musl` rather than linking against host `glibc`, so runner OS upgrades\ndo not affect binary compatibility."
    },
    {
      "commit": "71573b1e3f4c8946c5db2f5292b1815b7c9a96dd",
      "tree": "61ae9f9c22ac4d882c98f2378e0e110b442b3c32",
      "parents": [
        "aa81a7722b8291bbca6fada6337b292d2fddcd0b"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Nov 10 22:01:48 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 10 22:01:48 2026 -0800"
      },
      "message": "workflows: use pull_request instead of pull_request_target (#4474)\n\n`pull_request_target` runs in the privileged base-branch context,\nwhich is unnecessary and risky for checks that only read PR labels,\ndescriptions, and diff filenames.\n\nSwitch the PR metadata checks workflow trigger to `pull_request` so\nchecks run in the unprivileged pull request context."
    },
    {
      "commit": "aa81a7722b8291bbca6fada6337b292d2fddcd0b",
      "tree": "171557d907c77420e2247017cd3615d856f5416a",
      "parents": [
        "05e93bc86f1ac918ba562f69541d59bbd7938e34"
      ],
      "author": {
        "name": "vadikmironov",
        "email": "77026200+vadikmironov@users.noreply.github.com",
        "time": "Wed Nov 11 04:49:56 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 11 04:49:56 2026 +0000"
      },
      "message": "feat(toolchains): support debug runtimes on Linux and macOS (#4471)\n\nFollow-up to #4442.\n\npython-build-standalone debug (`Py_DEBUG`) archives for Linux and macOS\nadd a `d` ABI flag to some names: `include/python3.14d` and\n`lib/libpython3.14d.so` (`.dylib` on macOS), or `td` for free-threaded\ndebug builds. The runtime repo only knows the release names, so a debug\nruntime registered with `python.single_version_platform_override` does\nnot work for C code: `current_py_cc_headers` fails with\n`Python.h: No such file or directory` and `current_py_cc_libs` with\n`missing input file \u0027...//:lib/libpython3.14.so\u0027`. On a macOS host, the\nrepo rule\u0027s `install_name_tool` step also looks for the release dylib.\n\nTo fix, the repo rule checks the extracted archive for the `d` include\ndir and passes that to the runtime macro, which uses the `d` names. The\nmacro also sets `abi_flags` on `py_runtime` and `py_cc_toolchain`,\nbecause `\u003cAUTO\u003e` only derives `t`. Extensions built against the debug\nheaders need a debug interpreter, so they get the debug SOABI (for\nexample `cpython-314d-x86_64-linux-gnu`) and wheel ABI tag (`cp314d`).\n\nWindows debug archives use other names (`python_d.exe`,\n`python314_d.dll`) and are not handled here. Will be addressed\nseparately.\n\n* Also registers a debug runtime for tests in `MODULE.bazel` and adds\n  `//tests/toolchains:debug_runtime_test`, which builds an extension\n  against it and imports it.\n\n---------\n\nCo-authored-by: Claude Fable 5.2 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "05e93bc86f1ac918ba562f69541d59bbd7938e34",
      "tree": "0c9db20fbd12f69e8e354f10f7dbc5008e5c2e6a",
      "parents": [
        "53400d34969031776cccb6615ae2a34f10813cdf"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Nov 10 20:53:31 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 10 20:53:31 2026 -0800"
      },
      "message": "build: deduplicate sub-workspace downloader configs (#4467)\n\nMaintaining 23 duplicate copies of `downloader_config.cfg` across\nexample and integration test sub-workspaces adds file churn whenever\nmirror rules change.\n\nDelete the redundant sub-workspace `downloader_config.cfg` files and\npoint each sub-workspace\u0027s `.bazelrc` to its parent module\u0027s\n`downloader_config.cfg` (`//:downloader_config.cfg`,\n`gazelle/downloader_config.cfg`, or\n`sphinxdocs/downloader_config.cfg`). Include `downloader_config.cfg`\nin `//:distribution` so `tests/integration` sandboxes can resolve it."
    },
    {
      "commit": "53400d34969031776cccb6615ae2a34f10813cdf",
      "tree": "080c04fd480dd5a4d038242a5f0880556b6698ec",
      "parents": [
        "f66b6c3aba0f92d7e24612f7146fb7f8b63715b5"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Wed Nov 11 01:34:17 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 11 01:34:17 2026 +0000"
      },
      "message": "chore(release): sync changelog for v2.5.0 backports (#4464)\n\nUpdates CHANGELOG.md and removes news files for backports:\n- #4286\n\nWork towards #4388\nRelease-Tracking-Issue: #4388\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "f66b6c3aba0f92d7e24612f7146fb7f8b63715b5",
      "tree": "25520f2f60eae764e66ecf15fffd236048f47f25",
      "parents": [
        "84031fffd3f3956e916ab3dd90293a3bc4446d69"
      ],
      "author": {
        "name": "Kayce Basques",
        "email": "kaycebasques@gmail.com",
        "time": "Wed Nov 11 00:49:57 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 11 00:49:57 2026 +0000"
      },
      "message": "fix(sphinxdocs): stop hardcoding --show-traceback in sphinx_docs (#4470)\n\nHardcoding `--show-traceback` in `sphinx_docs` produces noisy Python\nstack traces on failed documentation builds and prevents opting out of\nthem.\n\nRemove `--show-traceback` from the default `sphinx_docs` build and\n`.run` arguments so Sphinx uses its default error output unless callers\npass `extra_opts \u003d [\"--show-traceback\"]`.\n\nFixes #4469"
    },
    {
      "commit": "84031fffd3f3956e916ab3dd90293a3bc4446d69",
      "tree": "c176741cf8a96ed54fc22bf542e1e16887cefa52",
      "parents": [
        "f1c86994fe89e529bdd21cabc115881801476ad7"
      ],
      "author": {
        "name": "Kayce Basques",
        "email": "kaycebasques@gmail.com",
        "time": "Tue Nov 10 23:22:24 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 10 23:22:24 2026 +0000"
      },
      "message": "build(deps-dev): sync manifests, lockfiles, and tests after #4463 (#4473)\n\nDependabot commit 4689a40b (#4463) updated dev, example, and test\ndependencies without regenerating derived Gazelle manifests, Bazel\nlockfiles, or `lock()` constraint comments, and collapsed distinct\npackage versions in multi-hub test fixtures. It also bumped `pyelftools`\nto 0.33 and `yamllint` to 1.38.0, failing `pyrefly` section type checks\nand the `pip_parse` entry-point version check.\n\nRegenerate the out-of-date Gazelle manifests, `MODULE.bazel.lock`, and\n`tests/uv/lock` requirements output, narrow `.dynsym` to\n`SymbolTableSection` for `pyrefly`, update the expected `yamllint`\nversion, and restore the distinct version pins in `multi_pypi` and\n`unified_pypi`."
    },
    {
      "commit": "f1c86994fe89e529bdd21cabc115881801476ad7",
      "tree": "d030adf5400f4e582eba9330e4b3d11ddfb87cd9",
      "parents": [
        "062a81c49c93f5392416a55232493394c08d08ca"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Nov 10 09:34:47 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 10 09:34:47 2026 -0800"
      },
      "message": "agents: document Bzlmod cycle, BUILD macro, lockfile, and PR rules (#4468)\n\nLoading `@rules_python_internal` from files transitively loaded by\n`config.bzl` triggers a Bzlmod Skyframe cycle, top-level ternary target\ninstantiations in `BUILD` files break `buildifier` and `buildozer`\nprocessing, and unpinned or conflicted `MODULE.bazel.lock` updates fail\nBazel 9 lockfile checks. In addition, `gh pr merge --auto` exits `0` on\nconflicting PRs without entering the merge queue, and single-choice PR\nreview prompts prevented combining comments, approvals, and fixes.\n\nDocument `@rules_python_internal` cycle avoidance, canonical toolchain\ntype paths, `.bzl` helper macros for conditional targets, and\n`USE_BAZEL_VERSION`-pinned lockfile regeneration and conflict recovery\nin the agent rules and Starlark review prompt. Update the merge and\nreview skills to check PR mergeability before enabling auto-merge and\noffer multi-select review actions with review thread resolution."
    },
    {
      "commit": "062a81c49c93f5392416a55232493394c08d08ca",
      "tree": "218ebf2d9d56d1499feefc8c19cd301345e2609c",
      "parents": [
        "4689a40bfe8d96ff22f1e017d58e8f1f1534b8ab"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 20:25:45 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 20:25:45 2026 -0800"
      },
      "message": "agents: add mirror, ifttt-lint, and Bazel 5xx flake rules (#4465)\n\nPlain `# Keep in sync` comments drift without automated checks,\nsingle-URL tool downloads fail during upstream outages, and CI triage\nmisclassified transient Bazel HTTP 5xx and I/O download errors as code\nbugs.\n\nRequire `LINT.IfChange` / `LINT.ThenChange` directives for paired\nsections and verified mirror URLs for tool downloads in agent style and\nreview rules. Detect transient Bazel download failures in CI log triage\nand suggest checking `mirror.bazel.build`, with unit tests."
    },
    {
      "commit": "4689a40bfe8d96ff22f1e017d58e8f1f1534b8ab",
      "tree": "f6d8f08760b80178c7b43093f109a20118ad51f9",
      "parents": [
        "b03080ff6aafdeaf8b3152138e9af3b090cbae77"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Nov 09 20:19:59 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 20:19:59 2026 -0800"
      },
      "message": "build(deps-dev): Bump the \"dev-only\" group with 1 update across multiple ecosystems (#4463)\n\nBumps the dev-only group with 5 updates in the /dev directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [absl-py](https://github.com/abseil/abseil-py) | `2.4.0` | `2.5.1` |\n| [typing-extensions](https://github.com/python/typing_extensions) |\n`4.15.0` | `4.16.0` |\n| [pyelftools](https://github.com/eliben/pyelftools) | `0.32` | `0.33` |\n| [markupsafe](https://github.com/pallets/markupsafe) | `3.0.3` |\n`3.0.4` |\n| [pytest](https://github.com/pytest-dev/pytest) | `9.1.1` | `9.2.0` |\n\nBumps the dev-only group with 3 updates in the /examples/bzlmod\ndirectory: [s3cmd](http://s3tools.org),\n[tabulate](https://github.com/astanin/python-tabulate) and\n[pylint](https://github.com/pylint-dev/pylint).\nBumps the dev-only group with 2 updates in the /examples/pip_parse\ndirectory: [s3cmd](http://s3tools.org) and\n[yamllint](https://github.com/adrienverge/yamllint).\nBumps the dev-only group with 5 updates in the\n/gazelle/examples/bzlmod_build_file_generation directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [s3cmd](http://s3tools.org) | `2.1.0` | `2.4.0` |\n| [tabulate](https://github.com/astanin/python-tabulate) | `0.9.0` |\n`0.10.0` |\n| [pylint](https://github.com/pylint-dev/pylint) | `4.0.10` | `4.1.3` |\n| [python-dateutil](https://github.com/dateutil/dateutil) | `3.0.0` |\n`4.0.0` |\n| [django](https://github.com/django/django) | `5.2.18` | `5.2.19` |\n\nBumps the dev-only group with 1 update in the /tests directory:\n[attrs](https://github.com/python-attrs/attrs).\nBumps the dev-only group with 1 update in the\n/tests/integration/bzlmod_lockfile directory:\n[pycparser](https://github.com/eliben/pycparser).\nBumps the dev-only group with 1 update in the\n/tests/integration/unified_pypi directory:\n[colorama](https://github.com/tartley/colorama).\nBumps the dev-only group with 1 update in the /tests/multi_pypi/alpha\ndirectory:\n[more-itertools](https://github.com/more-itertools/more-itertools).\nBumps the dev-only group with 1 update in the /tests/multi_pypi/beta\ndirectory:\n[more-itertools](https://github.com/more-itertools/more-itertools).\nBumps the dev-only group with 1 update in the /tests/multiple_inputs\ndirectory: [attrs](https://github.com/python-attrs/attrs).\nBumps the dev-only group with 7 updates in the /tests/uv/lock directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [certifi](https://github.com/certifi/python-certifi) | `2025.1.31` |\n`2026.10.23` |\n| [idna](https://github.com/kjd/idna) | `3.15` | `3.20` |\n| [charset-normalizer](https://github.com/jawah/charset_normalizer) |\n`3.4.0` | `3.5.2` |\n| [click](https://github.com/pallets/click) | `8.4.1` | `8.5.1` |\n| [mypy-extensions](https://github.com/python/mypy_extensions) | `1.1.0`\n| `1.2.0` |\n| [packaging](https://github.com/pypa/packaging) | `26.2` | `26.3` |\n| [platformdirs](https://github.com/tox-dev/platformdirs) | `4.10.0` |\n`4.14.5` |\n\nBumps the dev-only group with 2 updates in the\n/tests/uv/lock/pyproject_toml directory:\n[certifi](https://github.com/certifi/python-certifi) and\n[idna](https://github.com/kjd/idna).\nBumps the dev-only group with 3 updates in the /tests/uv/lock/testdata\ndirectory: [certifi](https://github.com/certifi/python-certifi),\n[idna](https://github.com/kjd/idna) and\n[charset-normalizer](https://github.com/jawah/charset_normalizer).\nBumps the dev-only group with 6 updates in the /tests/uv/lock/workspaces\ndirectory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [idna](https://github.com/kjd/idna) | `3.15` | `3.20` |\n| [charset-normalizer](https://github.com/jawah/charset_normalizer) |\n`3.4.7` | `3.5.2` |\n| [click](https://github.com/pallets/click) | `8.4.1` | `8.5.1` |\n| [mypy-extensions](https://github.com/python/mypy_extensions) | `1.1.0`\n| `1.2.0` |\n| [packaging](https://github.com/pypa/packaging) | `26.2` | `26.3` |\n| [platformdirs](https://github.com/tox-dev/platformdirs) | `4.10.0` |\n`4.14.5` |\n\n\nUpdates `absl-py` from 2.4.0 to 2.5.1\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/releases\"\u003eabsl-py\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev2.5.1\u003c/h2\u003e\n\u003ch3\u003eAdded\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(testing) Add \u003ccode\u003eassertIsSubclass\u003c/code\u003e and\n\u003ccode\u003eassertNotIsSubclass\u003c/code\u003e to \u003ccode\u003eabsltest.TestCase\u003c/code\u003e,\nmatching the \u003ccode\u003eunittest.TestCase\u003c/code\u003e methods added in Python\n3.14.\u003c/li\u003e\n\u003cli\u003e(flags) Add support for disabling \u003ccode\u003eReloadDetector\u003c/code\u003e via\nthe \u003ccode\u003eABSL_RELOAD_DETECTOR\u003c/code\u003e environment variable.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eChanged\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(testing) Include argument \u003ccode\u003erepr\u003c/code\u003e in\n\u003ccode\u003eabsltest.TestCase.assertDataclassEqual\u003c/code\u003e failure message when\nan argument is not a dataclass instance.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eFixed\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(app) Add \u003ccode\u003e__init__\u003c/code\u003e to the \u003ccode\u003eapp.UsageError\u003c/code\u003e\ntype stub.\u003c/li\u003e\n\u003cli\u003e(logging) Fix the type signature of\n\u003ccode\u003elogging.skip_log_prefix\u003c/code\u003e to preserve the decorated\nfunction\u0027s return type.\u003c/li\u003e\n\u003cli\u003e(testing) Strip ANSI escape sequences from test output before XML\nescaping in \u003ccode\u003exml_reporter\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003ev2.5.0\u003c/h2\u003e\n\u003ch3\u003eAdded\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(app) Add support for enabling Python profiling via the\n\u003ccode\u003eABSL_PYTHON_PROFILE_FILE\u003c/code\u003e environment variable.\u003c/li\u003e\n\u003cli\u003e(flags) Introduce \u003ccode\u003e--only_check_flags\u003c/code\u003e built-in flag to\nvalidate flag definitions without executing \u003ccode\u003emain()\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e(flagsaver) Add support for \u003ccode\u003easync\u003c/code\u003e test functions in\n\u003ccode\u003e@flagsaver.flagsaver\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e(testing) Add \u003ccode\u003erecord_property\u003c/code\u003e and\n\u003ccode\u003eget_recorded_properties\u003c/code\u003e methods to\n\u003ccode\u003eabsltest.TestCase\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eChanged\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(flags) Apply defensive copying in \u003ccode\u003esave_flag_values\u003c/code\u003e to\nprevent dictionary mutation flakiness.\u003c/li\u003e\n\u003cli\u003e(logging) Update type signatures for \u003ccode\u003eabsl.logging\u003c/code\u003e\nfunctions to support standard \u003ccode\u003elogging\u003c/code\u003e arguments\n(\u003ccode\u003eexc_info\u003c/code\u003e, \u003ccode\u003estack_info\u003c/code\u003e,\n\u003ccode\u003estacklevel\u003c/code\u003e, \u003ccode\u003eextra\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003e(cleanup) Expand usage of \u003ccode\u003eFlagHolder\u003c/code\u003e objects in\n\u003ccode\u003eapp\u003c/code\u003e and \u003ccode\u003eabsltest\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eFixed\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(flags) Improve formatting and clarity of\n\u003ccode\u003eDuplicateFlagError\u003c/code\u003e message.\u003c/li\u003e\n\u003cli\u003e(testing) Fix assertion logic in\n\u003ccode\u003eabsltest.TestCase.create_file\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e(typechecking) Fix type annotations and compatibility with MyPy and\nPyrefly.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/blob/main/CHANGELOG.md\"\u003eabsl-py\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e2.5.1 (2026-10-09)\u003c/h2\u003e\n\u003ch3\u003eAdded\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(testing) Add \u003ccode\u003eassertIsSubclass\u003c/code\u003e and\n\u003ccode\u003eassertNotIsSubclass\u003c/code\u003e to\n\u003ccode\u003eabsltest.TestCase\u003c/code\u003e, matching the\n\u003ccode\u003eunittest.TestCase\u003c/code\u003e methods added in\nPython 3.14.\u003c/li\u003e\n\u003cli\u003e(flags) Add support for disabling \u003ccode\u003eReloadDetector\u003c/code\u003e via\nthe\n\u003ccode\u003eABSL_RELOAD_DETECTOR\u003c/code\u003e environment variable.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eChanged\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(testing) Include argument \u003ccode\u003erepr\u003c/code\u003e in\n\u003ccode\u003eabsltest.TestCase.assertDataclassEqual\u003c/code\u003e failure message when\nan argument is\nnot a dataclass instance.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eFixed\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(app) Add \u003ccode\u003e__init__\u003c/code\u003e to the \u003ccode\u003eapp.UsageError\u003c/code\u003e\ntype stub.\u003c/li\u003e\n\u003cli\u003e(logging) Fix the type signature of\n\u003ccode\u003elogging.skip_log_prefix\u003c/code\u003e to preserve\nthe decorated function\u0027s return type.\u003c/li\u003e\n\u003cli\u003e(testing) Strip ANSI escape sequences from test output before XML\nescaping\nin \u003ccode\u003exml_reporter\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e2.5.0 (2026-07-03)\u003c/h2\u003e\n\u003ch3\u003eAdded\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(app) Add support for enabling Python profiling via the\n\u003ccode\u003eABSL_PYTHON_PROFILE_FILE\u003c/code\u003e environment variable.\u003c/li\u003e\n\u003cli\u003e(flags) Introduce \u003ccode\u003e--only_check_flags\u003c/code\u003e built-in flag to\nvalidate flag\ndefinitions without executing \u003ccode\u003emain()\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e(flagsaver) Add support for \u003ccode\u003easync\u003c/code\u003e test functions in\n\u003ccode\u003e@flagsaver.flagsaver\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e(testing) Add \u003ccode\u003erecord_property\u003c/code\u003e and\n\u003ccode\u003eget_recorded_properties\u003c/code\u003e methods to\n\u003ccode\u003eabsltest.TestCase\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eChanged\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(flags) Apply defensive copying in \u003ccode\u003esave_flag_values\u003c/code\u003e to\nprevent dictionary\nmutation flakiness.\u003c/li\u003e\n\u003cli\u003e(logging) Update type signatures for \u003ccode\u003eabsl.logging\u003c/code\u003e\nfunctions to support\nstandard \u003ccode\u003elogging\u003c/code\u003e arguments (\u003ccode\u003eexc_info\u003c/code\u003e,\n\u003ccode\u003estack_info\u003c/code\u003e, \u003ccode\u003estacklevel\u003c/code\u003e,\n\u003ccode\u003eextra\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003e(cleanup) Expand usage of \u003ccode\u003eFlagHolder\u003c/code\u003e objects in\n\u003ccode\u003eapp\u003c/code\u003e and \u003ccode\u003eabsltest\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eFixed\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e(flags) Improve formatting and clarity of\n\u003ccode\u003eDuplicateFlagError\u003c/code\u003e message.\u003c/li\u003e\n\u003cli\u003e(testing) Fix assertion logic in\n\u003ccode\u003eabsltest.TestCase.create_file\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/23b2c75e57966ba8389fc056b261ebc33ceb5658\"\u003e\u003ccode\u003e23b2c75\u003c/code\u003e\u003c/a\u003e\nRelease Abseil-py 2.5.1\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/0918a3046ff49ef7eb03459693835ab9ce3458e6\"\u003e\u003ccode\u003e0918a30\u003c/code\u003e\u003c/a\u003e\nInclude repr when assertDataclassEqual arg is not a dataclass\ninstance\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/16358a089941e07d5ef01b9390952caf4ff31451\"\u003e\u003ccode\u003e16358a0\u003c/code\u003e\u003c/a\u003e\nReplace \u003ccode\u003e# pytype: disable\u003c/code\u003e suppressions with \u003ccode\u003e#\npyrefly: ignore\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/f5eadb09e775ac29a10115f715734884bee48d9e\"\u003e\u003ccode\u003ef5eadb0\u003c/code\u003e\u003c/a\u003e\nReplace \u003ccode\u003e# pytype: disable\u003c/code\u003e suppressions with \u003ccode\u003e#\npyrefly: ignore\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/87523671c43233c1c5feaa11d446685ab2c67c91\"\u003e\u003ccode\u003e8752367\u003c/code\u003e\u003c/a\u003e\nAdd an option to disable ReloadDetector with an env variable\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/86e4f1ea43872911db408891cc07126bb3cf411d\"\u003e\u003ccode\u003e86e4f1e\u003c/code\u003e\u003c/a\u003e\nAdd assertIsSubclass and assertNotIsSubclass to absltest.TestCase.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/097f7c2ccac6c4636c3c5d233682e64affe1eb2f\"\u003e\u003ccode\u003e097f7c2\u003c/code\u003e\u003c/a\u003e\nAdd \u003cstrong\u003einit\u003c/strong\u003e to the absl app.UsageError type stub.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/3e459074c71cb79f3d29ccf14e41113b1133f3dd\"\u003e\u003ccode\u003e3e45907\u003c/code\u003e\u003c/a\u003e\nStrip ANSI escape sequences from test output before XML escaping in the\nJUnit...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/a2150fe10a48b69d9fcc4baa74125a7d667a021a\"\u003e\u003ccode\u003ea2150fe\u003c/code\u003e\u003c/a\u003e\nUpdate versions of Github actions and Python version in actions\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/commit/7e6d9c15692ab300ac88a2c88e59f59816dc0900\"\u003e\u003ccode\u003e7e6d9c1\u003c/code\u003e\u003c/a\u003e\nRemove obsolete Pyrefly suppression comments\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/abseil/abseil-py/compare/v2.4.0...v2.5.1\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `typing-extensions` from 4.15.0 to 4.16.0\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/python/typing_extensions/releases\"\u003etyping-extensions\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e4.16.0\u003c/h2\u003e\n\u003cp\u003eNo changes since 4.16.0rc2.\u003c/p\u003e\n\u003cp\u003eChanges since 4.15.0:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eMake \u003ccode\u003etyping_extensions.TypeAliasType\u003c/code\u003e\u0027s\n\u003ccode\u003e__module__\u003c/code\u003e attribute writable. Backport of CPython PR \u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/149172\"\u003e#149172\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFix setting of \u003ccode\u003e__required_keys__\u003c/code\u003e and\n\u003ccode\u003e__optional_keys__\u003c/code\u003e when inheriting keys with the same\nname.\u003c/li\u003e\n\u003cli\u003eAdd support for \u003ccode\u003eAsyncIterator\u003c/code\u003e, \u003ccode\u003eio.Reader\u003c/code\u003e,\n\u003ccode\u003eio.Writer\u003c/code\u003e and \u003ccode\u003eos.PathLike\u003c/code\u003e protocols as bases\nfor other protocols.\u003c/li\u003e\n\u003cli\u003eFix incorrect behaviour on Python 3.9 and Python 3.10 that meant\nthat calling \u003ccode\u003eisinstance\u003c/code\u003e with\n\u003ccode\u003etyping_extensions.Concatenate[...]\u003c/code\u003e or\n\u003ccode\u003etyping_extensions.Unpack[...]\u003c/code\u003e as the first argument could\nhave a different result in some situations depending on whether or not a\nprofiling function had been set using \u003ccode\u003esys.setprofile\u003c/code\u003e. This\naffected both CPython and PyPy implementations. Patch by Brian\nSchubert.\u003c/li\u003e\n\u003cli\u003eFix \u003ccode\u003e__init_subclass__()\u003c/code\u003e behavior in the presence of\nmultiple inheritance involving an \u003ccode\u003e@deprecated\u003c/code\u003e-decorated\nbase class. Backport of CPython PR \u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/138210\"\u003e#138210\u003c/a\u003e\nby Brian Schubert.\u003c/li\u003e\n\u003cli\u003eRaise \u003ccode\u003eTypeError\u003c/code\u003e when attempting to subclass\n\u003ccode\u003etyping_extensions.ParamSpec\u003c/code\u003e on Python 3.9. The\n\u003ccode\u003etyping\u003c/code\u003e implementation has always raised an error, and the\n\u003ccode\u003etyping_extensions\u003c/code\u003e implementation has raised an error on\nPython 3.10+ since \u003ccode\u003etyping_extensions\u003c/code\u003e v4.6.0. Patch by Brian\nSchubert.\u003c/li\u003e\n\u003cli\u003eAdd the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e, and \u003ccode\u003einfer_variance\u003c/code\u003e parameters\nto \u003ccode\u003eTypeVarTuple\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eOfficially support the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e and \u003ccode\u003einfer_variance\u003c/code\u003e parameters to\n\u003ccode\u003eParamSpec\u003c/code\u003e. Improve the validation of these parameters at\nruntime.\u003c/li\u003e\n\u003cli\u003eRename \u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e to\n\u003ccode\u003etyping_extensions.sentinel\u003c/code\u003e, following the name that has\nbeen adopted for \u003ccode\u003ebuiltins.sentinel\u003c/code\u003e on Python 3.15.\n\u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e is retained as a soft-deprecated\nalias for backwards compatibility.\u003c/li\u003e\n\u003cli\u003eAdd support for pickling sentinels.\u003c/li\u003e\n\u003cli\u003eSentinels now preserve their identity when copied or\ndeep-copied.\u003c/li\u003e\n\u003cli\u003eDeprecate passing \u003ccode\u003ename\u003c/code\u003e as a keyword argument or\n\u003ccode\u003erepr\u003c/code\u003e as a positional argument to the \u003ccode\u003esentinel\u003c/code\u003e\nconstructor.\u003c/li\u003e\n\u003cli\u003eThe default repr of a sentinel \u003ccode\u003eX \u003d\nsentinel(\u0026quot;X\u0026quot;)\u003c/code\u003e is now \u003ccode\u003eX\u003c/code\u003e rather than\n\u003ccode\u003e\u0026lt;X\u0026gt;\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDeprecate arbitrary attribute assignments to sentinels.\u003c/li\u003e\n\u003cli\u003eDeprecate subclassing sentinels.\u003c/li\u003e\n\u003cli\u003eAdd support for Python 3.15.\u003c/li\u003e\n\u003cli\u003eAvoid a \u003ccode\u003eDeprecationWarning\u003c/code\u003e when \u003ccode\u003edeprecated\u003c/code\u003e\nis applied to a coroutine function on Python 3.14.0.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e4.16.0rc2\u003c/h2\u003e\n\u003cp\u003eChanges since 4.16.0rc1:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eAvoid a \u003ccode\u003eDeprecationWarning\u003c/code\u003e when \u003ccode\u003edeprecated\u003c/code\u003e\nis applied to a coroutine function on Python 3.14.0.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eChanges since 4.15.0:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eMake \u003ccode\u003etyping_extensions.TypeAliasType\u003c/code\u003e\u0027s\n\u003ccode\u003e__module__\u003c/code\u003e attribute writable. Backport of CPython PR \u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/149172\"\u003e#149172\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFix setting of \u003ccode\u003e__required_keys__\u003c/code\u003e and\n\u003ccode\u003e__optional_keys__\u003c/code\u003e when inheriting keys with the same\nname.\u003c/li\u003e\n\u003cli\u003eAdd support for \u003ccode\u003eAsyncIterator\u003c/code\u003e, \u003ccode\u003eio.Reader\u003c/code\u003e,\n\u003ccode\u003eio.Writer\u003c/code\u003e and \u003ccode\u003eos.PathLike\u003c/code\u003e protocols as bases\nfor other protocols.\u003c/li\u003e\n\u003cli\u003eFix incorrect behaviour on Python 3.9 and Python 3.10 that meant\nthat calling \u003ccode\u003eisinstance\u003c/code\u003e with\n\u003ccode\u003etyping_extensions.Concatenate[...]\u003c/code\u003e or\n\u003ccode\u003etyping_extensions.Unpack[...]\u003c/code\u003e as the first argument could\nhave a different result in some situations depending on whether or not a\nprofiling function had been set using \u003ccode\u003esys.setprofile\u003c/code\u003e. This\naffected both CPython and PyPy implementations. Patch by Brian\nSchubert.\u003c/li\u003e\n\u003cli\u003eFix \u003ccode\u003e__init_subclass__()\u003c/code\u003e behavior in the presence of\nmultiple inheritance involving an \u003ccode\u003e@deprecated\u003c/code\u003e-decorated\nbase class. Backport of CPython PR \u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/138210\"\u003e#138210\u003c/a\u003e\nby Brian Schubert.\u003c/li\u003e\n\u003cli\u003eRaise \u003ccode\u003eTypeError\u003c/code\u003e when attempting to subclass\n\u003ccode\u003etyping_extensions.ParamSpec\u003c/code\u003e on Python 3.9. The\n\u003ccode\u003etyping\u003c/code\u003e implementation has always raised an error, and the\n\u003ccode\u003etyping_extensions\u003c/code\u003e implementation has raised an error on\nPython 3.10+ since \u003ccode\u003etyping_extensions\u003c/code\u003e v4.6.0. Patch by Brian\nSchubert.\u003c/li\u003e\n\u003cli\u003eAdd the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e, and \u003ccode\u003einfer_variance\u003c/code\u003e parameters\nto \u003ccode\u003eTypeVarTuple\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eOfficially support the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e and \u003ccode\u003einfer_variance\u003c/code\u003e parameters to\n\u003ccode\u003eParamSpec\u003c/code\u003e. Improve the validation of these parameters at\nruntime.\u003c/li\u003e\n\u003cli\u003eRename \u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e to\n\u003ccode\u003etyping_extensions.sentinel\u003c/code\u003e, following the name that has\nbeen adopted for \u003ccode\u003ebuiltins.sentinel\u003c/code\u003e on Python 3.15.\n\u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e is retained as a soft-deprecated\nalias for backwards compatibility.\u003c/li\u003e\n\u003cli\u003eAdd support for pickling sentinels.\u003c/li\u003e\n\u003cli\u003eSentinels now preserve their identity when copied or\ndeep-copied.\u003c/li\u003e\n\u003cli\u003eDeprecate passing \u003ccode\u003ename\u003c/code\u003e as a keyword argument or\n\u003ccode\u003erepr\u003c/code\u003e as a positional argument to the \u003ccode\u003esentinel\u003c/code\u003e\nconstructor.\u003c/li\u003e\n\u003cli\u003eThe default repr of a sentinel \u003ccode\u003eX \u003d\nsentinel(\u0026quot;X\u0026quot;)\u003c/code\u003e is now \u003ccode\u003eX\u003c/code\u003e rather than\n\u003ccode\u003e\u0026lt;X\u0026gt;\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDeprecate arbitrary attribute assignments to sentinels.\u003c/li\u003e\n\u003cli\u003eDeprecate subclassing sentinels.\u003c/li\u003e\n\u003cli\u003eAdd support for Python 3.15.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e4.16.0rc1\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMake \u003ccode\u003etyping_extensions.TypeAliasType\u003c/code\u003e\u0027s\n\u003ccode\u003e__module__\u003c/code\u003e attribute writable. Backport of CPython PR \u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/149172\"\u003e#149172\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFix setting of \u003ccode\u003e__required_keys__\u003c/code\u003e and\n\u003ccode\u003e__optional_keys__\u003c/code\u003e when inheriting keys with the same\nname.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/python/typing_extensions/blob/main/CHANGELOG.md\"\u003etyping-extensions\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch1\u003eRelease 4.16.0 (July 2, 2026)\u003c/h1\u003e\n\u003cp\u003eNo user-facing changes since 4.16.0rc2.\u003c/p\u003e\n\u003ch1\u003eRelease 4.16.0rc2 (June 25, 2026)\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eAvoid a \u003ccode\u003eDeprecationWarning\u003c/code\u003e when \u003ccode\u003edeprecated\u003c/code\u003e\nis applied to a coroutine function on\nPython 3.14.0.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1\u003eRelease 4.16.0rc1 (June 24, 2026)\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eMake \u003ccode\u003etyping_extensions.TypeAliasType\u003c/code\u003e\u0027s\n\u003ccode\u003e__module__\u003c/code\u003e attribute writable.\nBackport of CPython PR\n\u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/149172\"\u003e#149172\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003eFix setting of \u003ccode\u003e__required_keys__\u003c/code\u003e and\n\u003ccode\u003e__optional_keys__\u003c/code\u003e when inheriting\nkeys with the same name.\u003c/li\u003e\n\u003cli\u003eAdd support for \u003ccode\u003eAsyncIterator\u003c/code\u003e, \u003ccode\u003eio.Reader\u003c/code\u003e,\n\u003ccode\u003eio.Writer\u003c/code\u003e and \u003ccode\u003eos.PathLike\u003c/code\u003e protocols\nas bases for other protocols.\u003c/li\u003e\n\u003cli\u003eFix incorrect behaviour on Python 3.9 and Python 3.10 that meant\nthat\ncalling \u003ccode\u003eisinstance\u003c/code\u003e with\n\u003ccode\u003etyping_extensions.Concatenate[...]\u003c/code\u003e or\n\u003ccode\u003etyping_extensions.Unpack[...]\u003c/code\u003e as the first argument could\nhave a different\nresult in some situations depending on whether or not a profiling\nfunction had been\nset using \u003ccode\u003esys.setprofile\u003c/code\u003e. This affected both CPython and\nPyPy implementations.\nPatch by Brian Schubert.\u003c/li\u003e\n\u003cli\u003eFix \u003ccode\u003e__init_subclass__()\u003c/code\u003e behavior in the presence of\nmultiple inheritance involving\nan \u003ccode\u003e@deprecated\u003c/code\u003e-decorated base class. Backport of CPython PR\n\u003ca\nhref\u003d\"https://redirect.github.com/python/cpython/pull/138210\"\u003e#138210\u003c/a\u003e\nby Brian Schubert.\u003c/li\u003e\n\u003cli\u003eRaise \u003ccode\u003eTypeError\u003c/code\u003e when attempting to subclass\n\u003ccode\u003etyping_extensions.ParamSpec\u003c/code\u003e on\nPython 3.9. The \u003ccode\u003etyping\u003c/code\u003e implementation has always raised an\nerror, and the\n\u003ccode\u003etyping_extensions\u003c/code\u003e implementation has raised an error on\nPython 3.10+ since\n\u003ccode\u003etyping_extensions\u003c/code\u003e v4.6.0. Patch by Brian Schubert.\u003c/li\u003e\n\u003cli\u003eAdd the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e, and \u003ccode\u003einfer_variance\u003c/code\u003e parameters\nto \u003ccode\u003eTypeVarTuple\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eOfficially support the \u003ccode\u003ebound\u003c/code\u003e, \u003ccode\u003ecovariant\u003c/code\u003e,\n\u003ccode\u003econtravariant\u003c/code\u003e and \u003ccode\u003einfer_variance\u003c/code\u003e\nparameters to \u003ccode\u003eParamSpec\u003c/code\u003e. Improve the validation of these\nparameters at runtime.\u003c/li\u003e\n\u003cli\u003eRename \u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e to\n\u003ccode\u003etyping_extensions.sentinel\u003c/code\u003e, following the\nname that has been adopted for \u003ccode\u003ebuiltins.sentinel\u003c/code\u003e on Python\n3.15.\n\u003ccode\u003etyping_extensions.Sentinel\u003c/code\u003e is retained as a soft-deprecated\nalias for backwards\ncompatibility.\u003c/li\u003e\n\u003cli\u003eAdd support for pickling sentinels.\u003c/li\u003e\n\u003cli\u003eSentinels now preserve their identity when copied or\ndeep-copied.\u003c/li\u003e\n\u003cli\u003eDeprecate passing \u003ccode\u003ename\u003c/code\u003e as a keyword argument or\n\u003ccode\u003erepr\u003c/code\u003e as a positional argument\nto the \u003ccode\u003esentinel\u003c/code\u003e constructor.\u003c/li\u003e\n\u003cli\u003eThe default repr of a sentinel \u003ccode\u003eX \u003d\nsentinel(\u0026quot;X\u0026quot;)\u003c/code\u003e is now \u003ccode\u003eX\u003c/code\u003e rather than\n\u003ccode\u003e\u0026lt;X\u0026gt;\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDeprecate arbitrary attribute assignments to sentinels.\u003c/li\u003e\n\u003cli\u003eDeprecate subclassing sentinels.\u003c/li\u003e\n\u003cli\u003eAdd support for Python 3.15.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/f29cd28d8ed7642cafb1d18daf5aa41be6a5c0aa\"\u003e\u003ccode\u003ef29cd28\u003c/code\u003e\u003c/a\u003e\nPrepare relase 4.16.0 (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/774\"\u003e#774\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/43174610ec0c407ce05ad750077c4e62b9192b2b\"\u003e\u003ccode\u003e4317461\u003c/code\u003e\u003c/a\u003e\nBump version to 4.16.0rc2.dev (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/772\"\u003e#772\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/4f71098e5be84798d36416bbca0e776223ee40f9\"\u003e\u003ccode\u003e4f71098\u003c/code\u003e\u003c/a\u003e\nPrepare release 4.16.0rc2 (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/771\"\u003e#771\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/37ed08a11f3b7c05234f8963ab97e3ebdbdc16a2\"\u003e\u003ccode\u003e37ed08a\u003c/code\u003e\u003c/a\u003e\nRemove use of \u003ccode\u003easyncio.coroutines.iscoroutinefunction()\u003c/code\u003e (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/769\"\u003e#769\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/8dcc5594cbe5a4e348245fea6ce160ce93ed6601\"\u003e\u003ccode\u003e8dcc559\u003c/code\u003e\u003c/a\u003e\nImprove \u003ccode\u003eTypedDict\u003c/code\u003e documentation (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/770\"\u003e#770\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/224f8d50551d26f0d603093596c3a47a7302a46f\"\u003e\u003ccode\u003e224f8d5\u003c/code\u003e\u003c/a\u003e\nPost-release followups for 3.16.0rc1 (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/767\"\u003e#767\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/777de3eb5f4562e2054d1d7ce707f098b1f4fd2f\"\u003e\u003ccode\u003e777de3e\u003c/code\u003e\u003c/a\u003e\nPrepare release 4.16.0rc1 (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/766\"\u003e#766\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/890be90f1545e7d5fa904dfa3154d5f03c96782c\"\u003e\u003ccode\u003e890be90\u003c/code\u003e\u003c/a\u003e\nType variable tuple variance (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/741\"\u003e#741\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/0e0545866d78458b668dc52d2edc411f6e39540d\"\u003e\u003ccode\u003e0e05458\u003c/code\u003e\u003c/a\u003e\nPin SQLAlchemy third-party tests to pytest\u003d\u003d9.0.3 (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/765\"\u003e#765\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/typing_extensions/commit/d2777468c274202ec290103b34313e50cf040229\"\u003e\u003ccode\u003ed277746\u003c/code\u003e\u003c/a\u003e\ndocs: add version compatibility table (\u003ca\nhref\u003d\"https://redirect.github.com/python/typing_extensions/issues/733\"\u003e#733\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/python/typing_extensions/compare/4.15.0...4.16.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `pyelftools` from 0.32 to 0.33\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/52ce435186022bd6b32012a998931fe86c985ec8\"\u003e\u003ccode\u003e52ce435\u003c/code\u003e\u003c/a\u003e\nBump version\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/f8c3b725744eafb45890da2d7f7f3d1e83b93c26\"\u003e\u003ccode\u003ef8c3b72\u003c/code\u003e\u003c/a\u003e\nRefactor hacking guide for better structure\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/8c9c31d11a6b1a3a03d3c9251b04942e44f0477c\"\u003e\u003ccode\u003e8c9c31d\u003c/code\u003e\u003c/a\u003e\nRevise user guide formatting and section titles\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/486f6274de17fd527031de8a1b94ca017b363d06\"\u003e\u003ccode\u003e486f627\u003c/code\u003e\u003c/a\u003e\nConvert user\u0027s guide and hacking guide to markdown\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/8ec946fa4d70f0232ae1de221a722e74053f7aeb\"\u003e\u003ccode\u003e8ec946f\u003c/code\u003e\u003c/a\u003e\nRefactor README.md with improved structure\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/a0c0a649a1aa315ba8a9e2c9f8be0d8a73046d43\"\u003e\u003ccode\u003ea0c0a64\u003c/code\u003e\u003c/a\u003e\nConvert README file to markdown\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/be53814762491796d428a7fd8211aeebb94ce60b\"\u003e\u003ccode\u003ebe53814\u003c/code\u003e\u003c/a\u003e\nSet up uv in CI before running it\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/2b15c813e82cfbc21c90d4cb3c8963fc79e87651\"\u003e\u003ccode\u003e2b15c81\u003c/code\u003e\u003c/a\u003e\nAdd Makefile for \u0027make check\u0027 and \u0027make test\u0027 and use it in CI\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/e383a2538fe133648ced0a0324d78ec814bd4c56\"\u003e\u003ccode\u003ee383a25\u003c/code\u003e\u003c/a\u003e\nAdd type hints (\u003ca\nhref\u003d\"https://redirect.github.com/eliben/pyelftools/issues/611\"\u003e#611\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/commit/14c46c2d8bff5e7e8e0a8a4c00d66ad68728e3d2\"\u003e\u003ccode\u003e14c46c2\u003c/code\u003e\u003c/a\u003e\nelf/section: Remove \u003cstrong\u003ehash\u003c/strong\u003e (\u003ca\nhref\u003d\"https://redirect.github.com/eliben/pyelftools/issues/659\"\u003e#659\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/eliben/pyelftools/compare/v0.32...v0.33\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `markupsafe` from 3.0.3 to 3.0.4\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/releases\"\u003emarkupsafe\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e3.0.4\u003c/h2\u003e\n\u003cp\u003eThis is the MarkupSafe 3.0.4 fix release, which fixes bugs but does\nnot otherwise change behavior and should not result in breaking changes\ncompared to the latest feature release.\u003c/p\u003e\n\u003cp\u003ePyPI: \u003ca\nhref\u003d\"https://pypi.org/project/MarkupSafe/3.0.4/\"\u003ehttps://pypi.org/project/MarkupSafe/3.0.4/\u003c/a\u003e\nChanges: \u003ca\nhref\u003d\"https://markupsafe.palletsprojects.com/page/changes/#version-3-0-4\"\u003ehttps://markupsafe.palletsprojects.com/page/changes/#version-3-0-4\u003c/a\u003e\nMilestone: \u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/milestone/17?closed\u003d1\"\u003ehttps://github.com/pallets/markupsafe/milestone/17?closed\u003d1\u003c/a\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eBuild Python 3.15, armv7l, ppc64le, Android, and iOS wheels.\u003c/li\u003e\n\u003cli\u003eImprove performance of \u003ccode\u003estriptags\u003c/code\u003e. \u003ca\nhref\u003d\"https://redirect.github.com/pallets/markupsafe/issues/521\"\u003e#521\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/blob/main/CHANGES.rst\"\u003emarkupsafe\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003eVersion 3.0.4\u003c/h2\u003e\n\u003cp\u003eReleased 2026-10-02\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eBuild Python 3.15, armv7l, ppc64le, Android, and iOS wheels.\u003c/li\u003e\n\u003cli\u003eImprove performance of \u003ccode\u003estriptags\u003c/code\u003e.\n:issue:\u003ccode\u003e521\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/ece26078ec168ebac69f02877238e68d4b376c91\"\u003e\u003ccode\u003eece2607\u003c/code\u003e\u003c/a\u003e\nrelease version 3.0.4\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/620bc809d748de3a7848bdf7e27b1c2a2903aaf5\"\u003e\u003ccode\u003e620bc80\u003c/code\u003e\u003c/a\u003e\nsplit archs\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/73c3be1596906daf3e642e51852af5a019c5e1ea\"\u003e\u003ccode\u003e73c3be1\u003c/code\u003e\u003c/a\u003e\nfix wheel builds (\u003ca\nhref\u003d\"https://redirect.github.com/pallets/markupsafe/issues/536\"\u003e#536\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/d8ae19e6e45b5512472b74fe5c60b7f6aa18d70f\"\u003e\u003ccode\u003ed8ae19e\u003c/code\u003e\u003c/a\u003e\nfix wheel builds\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/ff1eaff921f92db57327752bbc37472d37fb9b21\"\u003e\u003ccode\u003eff1eaff\u003c/code\u003e\u003c/a\u003e\nBuild Android and iOS wheels (\u003ca\nhref\u003d\"https://redirect.github.com/pallets/markupsafe/issues/516\"\u003e#516\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/87e64f9628c574bf91898f8642a21356cccaa58c\"\u003e\u003ccode\u003e87e64f9\u003c/code\u003e\u003c/a\u003e\nbuild Android and iOS wheels\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/bc33c55cb3078ba9f9b0950babb32f8d842f1267\"\u003e\u003ccode\u003ebc33c55\u003c/code\u003e\u003c/a\u003e\nBuild ppc64le wheels (\u003ca\nhref\u003d\"https://redirect.github.com/pallets/markupsafe/issues/518\"\u003e#518\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/0ddd6eac9b20df52c75fae9181c0e73e195fa8d1\"\u003e\u003ccode\u003e0ddd6ea\u003c/code\u003e\u003c/a\u003e\nbuild ppc64le wheels\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/3e0775809b92150b10d1671ce1821ea6eb56be0c\"\u003e\u003ccode\u003e3e07758\u003c/code\u003e\u003c/a\u003e\nBuild armv7l wheels (\u003ca\nhref\u003d\"https://redirect.github.com/pallets/markupsafe/issues/514\"\u003e#514\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/commit/39b9aae5f1e70edc33f380b47d1bef0e281746b5\"\u003e\u003ccode\u003e39b9aae\u003c/code\u003e\u003c/a\u003e\nbuild armv7l wheels\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pallets/markupsafe/compare/3.0.3...3.0.4\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `pytest` from 9.1.1 to 9.2.0\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/releases\"\u003epytest\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e9.2.0\u003c/h2\u003e\n\u003ch1\u003epytest 9.2.0 (2026-10-27)\u003c/h1\u003e\n\u003ch2\u003eRemovals and backward incompatible breaking changes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14716\"\u003e#14716\u003c/a\u003e:\n\u003ccode\u003e-c\u003c/code\u003e now raises a usage error for a path that does not exist,\nis a directory, or is in a format pytest has no loader for. Such paths\nwere previously either ignored or reported as an unhandled\n\u003ccode\u003eFileNotFoundError\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/8593\"\u003e#8593\u003c/a\u003e:\nThe \u003ccode\u003eindirect\u003c/code\u003e, \u003ccode\u003eids\u003c/code\u003e and \u003ccode\u003escope\u003c/code\u003e\narguments of \u003ccode\u003eMetafunc.parametrize()\n\u0026lt;pytest.Metafunc.parametrize\u0026gt;\u003c/code\u003e -- and therefore of\n\u003ccode\u003e@pytest.mark.parametrize \u0026lt;pytest.mark.parametrize\nref\u0026gt;\u003c/code\u003e -- are now keyword-only.\u003c/p\u003e\n\u003cp\u003ePassing them positionally was a common source of confusing errors,\ne.g. \u003ccode\u003eparametrize(\u0026quot;arg1\u0026quot;, \u0026quot;arg2\u0026quot;, [(1,\n2)])\u003c/code\u003e made the argvalues land in \u003ccode\u003eindirect\u003c/code\u003e and failed\nwith \u003ccode\u003eindirect fixture \u0027(1, 2)\u0027 doesn\u0027t exist\u003c/code\u003e; such mistakes\nnow fail with an understandable \u003ccode\u003eTypeError\u003c/code\u003e. The type\nannotations have always declared these arguments as keyword-only.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/993\"\u003e#993\u003c/a\u003e:\nPlugin import failures at startup are now reported and classified\ninstead of escaping as a raw traceback with the accidental exit code\n\u003ccode\u003e1\u003c/code\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ea plugin that cannot be found -- via \u003ccode\u003e-p\u003c/code\u003e,\n\u003ccode\u003epytest_plugins\u003c/code\u003e or \u003ccode\u003ePYTEST_PLUGINS\u003c/code\u003e -- exits with\n\u003ccode\u003epytest.ExitCode\u003c/code\u003e \u003ccode\u003eUSAGE_ERROR\u003c/code\u003e (\u003ccode\u003e4\u003c/code\u003e),\nlike a \u003ccode\u003econftest.py\u003c/code\u003e that fails to import;\u003c/li\u003e\n\u003cli\u003ea plugin that is found but raises while importing -- including a\nbroken \u003ccode\u003epytest11\u003c/code\u003e entry point or a missing plugin dependency\n-- exits with \u003ccode\u003epytest.ExitCode\u003c/code\u003e \u003ccode\u003eINTERNAL_ERROR\u003c/code\u003e\n(\u003ccode\u003e3\u003c/code\u003e), with the traceback preserved.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003ccode\u003epytest.main\u003c/code\u003e now returns these codes instead of raising\n\u003ccode\u003eImportError\u003c/code\u003e. Also fixed an \u003ccode\u003eIndexError\u003c/code\u003e from\npytest\u0027s own internals when the plugin raised an exception with no\narguments.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eDeprecations (removal in next major release)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14742\"\u003e#14742\u003c/a\u003e:\nThe private \u003ccode\u003e_pytest.python.CallSpec2\u003c/code\u003e name has been renamed\nto \u003ccode\u003eCallSpec\u003c/code\u003e.\nThe old \u003ccode\u003eCallSpec2\u003c/code\u003e alias remains available for now and will\nbe removed in pytest 10 or 11.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14755\"\u003e#14755\u003c/a\u003e:\nSchedule \u003cem\u003eyield_fixture\u003c/em\u003e decorator for removal in pytest 10 or\n11.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14774\"\u003e#14774\u003c/a\u003e:\nSimilarly to the deprecation of class-scoped fixtures defined as\ninstance methods in pytest 9.1,\n\u003cem\u003eall\u003c/em\u003e higher-scoped fixtures (\u003ccode\u003emodule\u003c/code\u003e,\n\u003ccode\u003epackage\u003c/code\u003e, and \u003ccode\u003esession\u003c/code\u003e) defined\nas instance methods are now deprecated.\u003c/p\u003e\n\u003cp\u003eThey suffer from the same issue the original deprecation only fixed\nfor\nclass-scoped fixtures, see \u003ccode\u003e10819\u003c/code\u003e and\n\u003ccode\u003e14011\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14808\"\u003e#14808\u003c/a\u003e:\nPassing a non-string value to a \u003ccode\u003estring\u003c/code\u003e-typed ini option now\nemits a \u003ccode\u003epytest.PytestRemovedIn10Warning\u003c/code\u003e. This affects\n\u003ccode\u003e[tool.pytest.ini_options]\u003c/code\u003e in \u003ccode\u003epyproject.toml\u003c/code\u003e.\nIn pytest 10 this will raise a \u003ccode\u003eTypeError\u003c/code\u003e, matching the\nbehavior of the corresponding TOML config path.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/7323\"\u003e#7323\u003c/a\u003e:\nPassing \u003ccode\u003ebytes\u003c/code\u003e to \u003ccode\u003eTerminalReporter.write_line()\u003c/code\u003e\nis now deprecated, pass a \u003ccode\u003estr\u003c/code\u003e instead.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eNew features\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/14743\"\u003e#14743\u003c/a\u003e:\n\u003c!-- raw HTML omitted --\u003eFull diff:\u003c!-- raw HTML omitted --\u003e now\ncontains a legend explaining the \u003c!-- raw HTML omitted --\u003e+\u003c!-- raw HTML\nomitted --\u003e \u0026amp; \u003c!-- raw HTML omitted --\u003e-\u003c!-- raw HTML omitted --\u003e\nsymbols in diff output.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/2781\"\u003e#2781\u003c/a\u003e:\nWhen \u003ccode\u003estrict_markers\u003c/code\u003e is enabled, marker names used in\n\u003ccode\u003e-m\u003c/code\u003e expressions are now validated against registered\nmarkers.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/6881\"\u003e#6881\u003c/a\u003e:\nAdded the \u003ccode\u003eparametrize_long_str_id_strategy\u003c/code\u003e configuration\noption to control how long \u003ccode\u003estr\u003c/code\u003e/\u003ccode\u003ebytes\u003c/code\u003e parameter\nvalues are handled in auto-generated test IDs. Explicit IDs set via\n\u003ccode\u003eids\u003d[...]\u003c/code\u003e or \u003ccode\u003epytest.param(..., id\u003d...)\u003c/code\u003e are not\naffected. Available strategies: \u003ccode\u003eshort\u003c/code\u003e (default, values over\n100 chars fall back to \u003ccode\u003eargname+index\u003c/code\u003e), \u003ccode\u003esha256\u003c/code\u003e\n(SHA-256 hex digest), \u003ccode\u003elegacy\u003c/code\u003e (keep full value), and\n\u003ccode\u003edisallow\u003c/code\u003e (error requesting explicit IDs).\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eImprovements in existing functionality\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/10745\"\u003e#10745\u003c/a\u003e:\nA \u003ccode\u003eRecursionError\u003c/code\u003e whose recursion origin cannot be located\nnow shows only the\nfirst and last 10 stack frames, matching what pytest already did when\nlocating\nthe origin failed outright. Previously the full traceback -- often\naround a\nthousand near-identical frames -- was rendered, which was both slow and\nunreadable. Pass \u003ccode\u003e--full-trace\u003c/code\u003e to see every frame.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/ae1d0ff57b8bd4252da9ade7353523ac0ac73281\"\u003e\u003ccode\u003eae1d0ff\u003c/code\u003e\u003c/a\u003e\nPrepare release version 9.2.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/143ce31dea9b12ff2ab6add04361ee01ab114931\"\u003e\u003ccode\u003e143ce31\u003c/code\u003e\u003c/a\u003e\npre-commit: exclude codespell on generated release announcements\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/532dc5fc78f57de5115c5ecc9c6c29257787ada7\"\u003e\u003ccode\u003e532dc5f\u003c/code\u003e\u003c/a\u003e\ntox: add attrs dependency to regen, needed in reportingdemo.rst\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/a7b2446ee41a7298d3a0bc22c52f3b8bacae1566\"\u003e\u003ccode\u003ea7b2446\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/15245\"\u003e#15245\u003c/a\u003e\nfrom pytest-dev/claude/project-thread-9jcf91\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/679d09c6945156746e17e9ec0b1c8309bbde3ad3\"\u003e\u003ccode\u003e679d09c\u003c/code\u003e\u003c/a\u003e\n[pre-commit.ci] pre-commit autoupdate (\u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/15266\"\u003e#15266\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/41d12cdbb4a35a7877768d93d8dc50a9117a8d8c\"\u003e\u003ccode\u003e41d12cd\u003c/code\u003e\u003c/a\u003e\ndocs: clarify typing for yield fixtures\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/b9022ba04a33bfc76b5c9aefb8974755a80bf5ce\"\u003e\u003ccode\u003eb9022ba\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/15182\"\u003e#15182\u003c/a\u003e\nfrom 1871698/docs/improve-getting-started-description\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/16f87a7f364a7362fbfbb204c79a47ad567b4fbd\"\u003e\u003ccode\u003e16f87a7\u003c/code\u003e\u003c/a\u003e\ndocs: improve getting-started.rst test execution description\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/082ed70e314ee8e1ab117763d17fe801648f7508\"\u003e\u003ccode\u003e082ed70\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/15255\"\u003e#15255\u003c/a\u003e\nfrom pytest-dev/claude/project-thread-eoi3d6\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/commit/ae37a013763e9c4a143245eda1acdc3c27961685\"\u003e\u003ccode\u003eae37a01\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/pytest-dev/pytest/issues/15227\"\u003e#15227\u003c/a\u003e\nfrom pytest-dev/claude/project-thread-4etye4\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pytest-dev/pytest/compare/9.1.1...9.2.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `s3cmd` from 2.1.0 to 2.4.0\n\nUpdates `tabulate` from 0.9.0 to 0.10.0\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/blob/master/CHANGELOG\"\u003etabulate\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e0.10.0: Add support for Python 3.11, 3.12, 3.13, 3.14.\nDrop support for Python 3.7, 3.8, 3.9.\nPRESERVE_STERILITY global is replaced with preserve_sterility function\nargument.\nNew formatting options: headersglobalalign, headersalign,\ncolglobalalign.\nNew output format: \u003ccode\u003ecolon_grid\u003c/code\u003e (Pandoc grid_tables with\nalignment)\nVarious bug fixes.\nImproved error messages.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/3b4cd509820e4c45cd2aaba833aa585ea6308b94\"\u003e\u003ccode\u003e3b4cd50\u003c/code\u003e\u003c/a\u003e\nupdate HOWTOPUBLISH\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/35ee0f61544b53067247cfe8fd8b7547b7e1c1e2\"\u003e\u003ccode\u003e35ee0f6\u003c/code\u003e\u003c/a\u003e\nupdate mini-benchmark table\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/37ac76e9365fa3694e92c8ab651a2cc694438983\"\u003e\u003ccode\u003e37ac76e\u003c/code\u003e\u003c/a\u003e\nrestore tabulate.\u003cstrong\u003eversion\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/37e1ed089f779ed5a962e287b12dc9c15e61c7ff\"\u003e\u003ccode\u003e37e1ed0\u003c/code\u003e\u003c/a\u003e\nmove # nowa: E931 to a different line (flake8)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/7bacc90422f416f61034c6aeb45be32dc67bafdf\"\u003e\u003ccode\u003e7bacc90\u003c/code\u003e\u003c/a\u003e\nrun pre-commit hooks (black)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/1b69704b12b13c70b1fa42f942e84d9c134a5763\"\u003e\u003ccode\u003e1b69704\u003c/code\u003e\u003c/a\u003e\nRemove spurious cast in string interpolation\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/4d535af12d2de46ee5a87329d2bc5810a386ef89\"\u003e\u003ccode\u003e4d535af\u003c/code\u003e\u003c/a\u003e\nUse specific noqa directives\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/76c3d37a5f51546b2bfba8d3e0648ebcda05b436\"\u003e\u003ccode\u003e76c3d37\u003c/code\u003e\u003c/a\u003e\nRemove spurious space from error message\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/13508e7a75783af650a2b76065dac28e06d1fa34\"\u003e\u003ccode\u003e13508e7\u003c/code\u003e\u003c/a\u003e\nUnnecessary \u003ccode\u003elist\u003c/code\u003e call\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/69f67cd72de4c7990bc7a25200b89ab9b2bdd870\"\u003e\u003ccode\u003e69f67cd\u003c/code\u003e\u003c/a\u003e\nDo not call \u003ccode\u003egetattr\u003c/code\u003e with a constant value\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/compare/v0.9.0...v0.10.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `pylint` from 4.0.9 to 4.1.3\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/releases\"\u003epylint\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.1.3\u003c/h2\u003e\n\u003ch2\u003eWhat\u0027s new in Pylint 4.1.3?\u003c/h2\u003e\n\u003cp\u003eRelease date: 2026-10-11\u003c/p\u003e\n\u003ch2\u003eFalse Positives Fixed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFixed a false positive for\n\u003ccode\u003eattribute-defined-outside-init\u003c/code\u003e when an\nattribute is assigned inside the setter of an old-style, non-decorator\n\u003ccode\u003eproperty(fget, fset)\u003c/code\u003e call. The decorator form\n(\u003ccode\u003e@property\u003c/code\u003e /\n\u003ccode\u003e@x.setter\u003c/code\u003e) was already exempted by the fix for \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/409\"\u003e#409\u003c/a\u003e;\nthe classic\ncall form was not.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/3325\"\u003e#3325\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eused-before-assignment\u003c/code\u003e when a\nname bound by an earlier\ntarget of the same assignment is used by a later target, as in \u003ccode\u003ea \u003d\nb[a] \u003d 0\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/5955\"\u003e#5955\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a \u003ccode\u003eno-member\u003c/code\u003e false positive in a comprehension inside\na branch that\ncannot run, such as \u003ccode\u003eif sys.platform \u003d\u003d \u0026quot;win32\u0026quot;:\u003c/code\u003e\non Linux. Like the rest of\nthe branch, the comprehension is no longer checked for missing\nmembers.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7240\"\u003e#7240\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eused-before-assignment\u003c/code\u003e when a\nname bound by a tuple\nor list target of a \u003ccode\u003ewith\u003c/code\u003e item is used by a later item of\nthe same \u003ccode\u003ewith\u003c/code\u003e statement.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7545\"\u003e#7545\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix false positives such as \u003ccode\u003enot-callable\u003c/code\u003e,\n\u003ccode\u003enot-an-iterable\u003c/code\u003e,\n\u003ccode\u003eunpacking-non-sequence\u003c/code\u003e and \u003ccode\u003eno-member\u003c/code\u003e on the\nresult of a function whose\nbody is only \u003ccode\u003e...\u003c/code\u003e, like \u003ccode\u003e@overload\u003c/code\u003e and\n\u003ccode\u003e.pyi\u003c/code\u003e stubs. Such calls were\ninferred as returning \u003ccode\u003eNone\u003c/code\u003e. This affected\n\u003ccode\u003esqlalchemy.func\u003c/code\u003e,\n\u003ccode\u003epydantic.Field\u003c/code\u003e, and the \u003ccode\u003etorch\u003c/code\u003e functions\nwrapped by \u003ccode\u003e_add_docstr\u003c/code\u003e,\nsuch as \u003ccode\u003etorch.linalg.qr\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/8138\"\u003e#8138\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9218\"\u003e#9218\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9354\"\u003e#9354\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/10087\"\u003e#10087\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eprotected-access\u003c/code\u003e when a\nsubclass of a subscripted\ngeneric base, such as \u003ccode\u003eclass Child(Parent[T])\u003c/code\u003e, accesses a\nprotected member\nthrough that base, such as \u003ccode\u003eParent._foo(self)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/8600\"\u003e#8600\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e75de10c69103381c875601f638d4b977ff0fcaf\"\u003e\u003ccode\u003ee75de10\u003c/code\u003e\u003c/a\u003e\nBump pylint to 4.1.3, update changelog (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11637\"\u003e#11637\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/591f6e2b9a258f3a069df9b9af56eb730bcea825\"\u003e\u003ccode\u003e591f6e2\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix protected-access false positive through\na su...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/a537920085b9d92abd54000b674d941063e52030\"\u003e\u003ccode\u003ea537920\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Ignore discard variable type redefinitions\n(\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11635\"\u003e#11635\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/4a8f61ca7c216f8cde5b98faca5590154487eb00\"\u003e\u003ccode\u003e4a8f61c\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix duplicate-code crash when\nmin-similarity-lin...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/41fa1c4ccf7f24ff7e653846a76305500df9ae66\"\u003e\u003ccode\u003e41fa1c4\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] [pyreverse] Fix hang/RecursionError with\n--all-a...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/a05e2f340808daab0fa775cbc39c3ce00e89f576\"\u003e\u003ccode\u003ea05e2f3\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix \u003ccode\u003eused-before-assignment\u003c/code\u003e\nfalse positive for ...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/ea7996b00280e3b8e5fcd9dc4e8e122466abff6a\"\u003e\u003ccode\u003eea7996b\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Error when several output formats write to\nstdou...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/479c0379366e482cda6d842b5d4cca0a52370939\"\u003e\u003ccode\u003e479c037\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix IndexError when Enum\n\u003cstrong\u003einit\u003c/strong\u003e has no argumen...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e6aa780ba6e393a517556000cc81961996585cad\"\u003e\u003ccode\u003ee6aa780\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix unreachable false positive for raising\ngener...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/fc58d0b4aa48eedc03776416998d70dda61dfe48\"\u003e\u003ccode\u003efc58d0b\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix pyreverse crash on classes with\nEmptyNode in...\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/compare/v4.0.9...v4.1.3\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `s3cmd` from 2.1.0 to 2.4.0\n\nUpdates `yamllint` from 1.28.0 to 1.38.0\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/blob/master/CHANGELOG.rst\"\u003eyamllint\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e1.38.0 (2026-01-13)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eAdd support for Python 3.14, drop support for Python 3.9\u003c/li\u003e\n\u003cli\u003eRequire pathspec ≥ 1.0.0\u003c/li\u003e\n\u003cli\u003eConfig: Follow gitignore implementation in \u003ccode\u003eyaml-files\u003c/code\u003e\nand \u003ccode\u003eignore\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eConfig: Use \u0026quot;mapping\u0026quot; instead of \u0026quot;dict\u0026quot; for\nuser-facing errors\u003c/li\u003e\n\u003cli\u003eRule \u003ccode\u003eindentation\u003c/code\u003e: Fix error message for\n\u003ccode\u003echeck-multi-line-strings\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eRule \u003ccode\u003equoted-strings\u003c/code\u003e: Add \u003ccode\u003equote-type:\nconsistent\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eDocs: Update the name of BSD ports\u003c/li\u003e\n\u003cli\u003eDocs: Enhance wording of recursive directory lint in README\u003c/li\u003e\n\u003cli\u003eDocs: Add Alpine Linux installation instructions in README\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e1.37.1 (2025-05-04)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eRule \u003ccode\u003ecomments\u003c/code\u003e: tell how many spaces are expected\u003c/li\u003e\n\u003cli\u003eRule \u003ccode\u003equoted-strings\u003c/code\u003e: Fix \u003ccode\u003eonly-when-needed\u003c/code\u003e\non multiline with backslash\u003c/li\u003e\n\u003cli\u003eConfig: Report if \u003ccode\u003erules\u003c/code\u003e is not a dict\u003c/li\u003e\n\u003cli\u003eFix \u003ccode\u003etest_codec_built_in_equivalent()\u003c/code\u003e test when run with\npytest\u003c/li\u003e\n\u003cli\u003eCI: Fix TestPyPI \u0026quot;dev0\u0026quot; versions for master commits on\ntags\u003c/li\u003e\n\u003cli\u003eDocs: Add links to GitHub repository and releases\u003c/li\u003e\n\u003cli\u003eDocs: Fix GitLab integration example\u003c/li\u003e\n\u003cli\u003eDocs: Fix GitLab integration link\u003c/li\u003e\n\u003cli\u003eFix the tests badge link on the README\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e1.37.0 (2025-03-23)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eAutomatically detect Unicode character encoding of files\u003c/li\u003e\n\u003cli\u003ePublish pushes to master branch to TestPyPI\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e1.36.2 (2025-03-17)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eBuild: Restore missing documentation and tests in sdist\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e1.36.1 (2025-03-15)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ePublish PyPI releases using GitHub Actions workflows\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e1.36.0 (2025-03-11)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eAdd support for Python 3.13, drop support for Python 3.8\u003c/li\u003e\n\u003cli\u003eRule \u003ccode\u003ekey-ordering\u003c/code\u003e: add \u003ccode\u003eignored-keys\u003c/code\u003e\noption\u003c/li\u003e\n\u003cli\u003eRule \u003ccode\u003equoted-strings\u003c/code\u003e: fix \u003ccode\u003eonly-when-needed\u003c/code\u003e\nand escaped special chars\u003c/li\u003e\n\u003cli\u003eFix TTY-related tests on Python 3.14\u003c/li\u003e\n\u003cli\u003eDocs: fix import of \u003ccode\u003eyamllint.config\u003c/code\u003e rather than\n\u003ccode\u003eyamllint\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/cba56bcde1fdd01c1deb3f945e69764c291a6530\"\u003e\u003ccode\u003ecba56bc\u003c/code\u003e\u003c/a\u003e\nyamllint version 1.38.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/9dc506b5a1e22a728a95321a7cdb829ba17de0e0\"\u003e\u003ccode\u003e9dc506b\u003c/code\u003e\u003c/a\u003e\nRequire pathspec ≥ 1.0.0 and follow Git\u0027s gitignore implementation\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/73b9c0b54270076e2c76e2e6bfd428aa4203ed3a\"\u003e\u003ccode\u003e73b9c0b\u003c/code\u003e\u003c/a\u003e\nDrop support for Python 3.9\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/22d07edd4903c71c4ea63d2e2e3880adde4604d6\"\u003e\u003ccode\u003e22d07ed\u003c/code\u003e\u003c/a\u003e\nindentation: Fix error message for check-multi-line-strings\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/cfbfe9b076b877fb9276a22ffb3d2726ead5866d\"\u003e\u003ccode\u003ecfbfe9b\u003c/code\u003e\u003c/a\u003e\nREADME: Add Alpine Linux installation instructions\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/a3b3bb31bb0e79fb6c43676314c89de00c667334\"\u003e\u003ccode\u003ea3b3bb3\u003c/code\u003e\u003c/a\u003e\nREADME: Enhance wording of recursive directory lint\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/e3b72f585b1bf8c779b7bae2f773b11a5fb80eb1\"\u003e\u003ccode\u003ee3b72f5\u003c/code\u003e\u003c/a\u003e\nquoted-strings: Add missing quote-type: consistent docs\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/e3d54cc100f892fe79eac820ce35cfd633603e37\"\u003e\u003ccode\u003ee3d54cc\u003c/code\u003e\u003c/a\u003e\nquoted-strings: Add quote-type: consistent\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/0b4ddc88c05ab3f20e3f8e5ffca7d04eccd290d6\"\u003e\u003ccode\u003e0b4ddc8\u003c/code\u003e\u003c/a\u003e\nCI: Update GitHub Actions\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/commit/866f805cbfaa4c89de8b92c3839eb80d46001eda\"\u003e\u003ccode\u003e866f805\u003c/code\u003e\u003c/a\u003e\nbuild: Remove license-files from pyproject.toml\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/adrienverge/yamllint/compare/v1.28.0...v1.38.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `s3cmd` from 2.1.0 to 2.4.0\n\nUpdates `tabulate` from 0.9.0 to 0.10.0\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/blob/master/CHANGELOG\"\u003etabulate\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e0.10.0: Add support for Python 3.11, 3.12, 3.13, 3.14.\nDrop support for Python 3.7, 3.8, 3.9.\nPRESERVE_STERILITY global is replaced with preserve_sterility function\nargument.\nNew formatting options: headersglobalalign, headersalign,\ncolglobalalign.\nNew output format: \u003ccode\u003ecolon_grid\u003c/code\u003e (Pandoc grid_tables with\nalignment)\nVarious bug fixes.\nImproved error messages.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/3b4cd509820e4c45cd2aaba833aa585ea6308b94\"\u003e\u003ccode\u003e3b4cd50\u003c/code\u003e\u003c/a\u003e\nupdate HOWTOPUBLISH\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/35ee0f61544b53067247cfe8fd8b7547b7e1c1e2\"\u003e\u003ccode\u003e35ee0f6\u003c/code\u003e\u003c/a\u003e\nupdate mini-benchmark table\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/37ac76e9365fa3694e92c8ab651a2cc694438983\"\u003e\u003ccode\u003e37ac76e\u003c/code\u003e\u003c/a\u003e\nrestore tabulate.\u003cstrong\u003eversion\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/37e1ed089f779ed5a962e287b12dc9c15e61c7ff\"\u003e\u003ccode\u003e37e1ed0\u003c/code\u003e\u003c/a\u003e\nmove # nowa: E931 to a different line (flake8)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/7bacc90422f416f61034c6aeb45be32dc67bafdf\"\u003e\u003ccode\u003e7bacc90\u003c/code\u003e\u003c/a\u003e\nrun pre-commit hooks (black)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/1b69704b12b13c70b1fa42f942e84d9c134a5763\"\u003e\u003ccode\u003e1b69704\u003c/code\u003e\u003c/a\u003e\nRemove spurious cast in string interpolation\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/4d535af12d2de46ee5a87329d2bc5810a386ef89\"\u003e\u003ccode\u003e4d535af\u003c/code\u003e\u003c/a\u003e\nUse specific noqa directives\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/76c3d37a5f51546b2bfba8d3e0648ebcda05b436\"\u003e\u003ccode\u003e76c3d37\u003c/code\u003e\u003c/a\u003e\nRemove spurious space from error message\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/13508e7a75783af650a2b76065dac28e06d1fa34\"\u003e\u003ccode\u003e13508e7\u003c/code\u003e\u003c/a\u003e\nUnnecessary \u003ccode\u003elist\u003c/code\u003e call\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/commit/69f67cd72de4c7990bc7a25200b89ab9b2bdd870\"\u003e\u003ccode\u003e69f67cd\u003c/code\u003e\u003c/a\u003e\nDo not call \u003ccode\u003egetattr\u003c/code\u003e with a constant value\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/astanin/python-tabulate/compare/v0.9.0...v0.10.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `pylint` from 4.0.10 to 4.1.3\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/releases\"\u003epylint\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.1.3\u003c/h2\u003e\n\u003ch2\u003eWhat\u0027s new in Pylint 4.1.3?\u003c/h2\u003e\n\u003cp\u003eRelease date: 2026-10-11\u003c/p\u003e\n\u003ch2\u003eFalse Positives Fixed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFixed a false positive for\n\u003ccode\u003eattribute-defined-outside-init\u003c/code\u003e when an\nattribute is assigned inside the setter of an old-style, non-decorator\n\u003ccode\u003eproperty(fget, fset)\u003c/code\u003e call. The decorator form\n(\u003ccode\u003e@property\u003c/code\u003e /\n\u003ccode\u003e@x.setter\u003c/code\u003e) was already exempted by the fix for \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/409\"\u003e#409\u003c/a\u003e;\nthe classic\ncall form was not.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/3325\"\u003e#3325\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eused-before-assignment\u003c/code\u003e when a\nname bound by an earlier\ntarget of the same assignment is used by a later target, as in \u003ccode\u003ea \u003d\nb[a] \u003d 0\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/5955\"\u003e#5955\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a \u003ccode\u003eno-member\u003c/code\u003e false positive in a comprehension inside\na branch that\ncannot run, such as \u003ccode\u003eif sys.platform \u003d\u003d \u0026quot;win32\u0026quot;:\u003c/code\u003e\non Linux. Like the rest of\nthe branch, the comprehension is no longer checked for missing\nmembers.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7240\"\u003e#7240\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eused-before-assignment\u003c/code\u003e when a\nname bound by a tuple\nor list target of a \u003ccode\u003ewith\u003c/code\u003e item is used by a later item of\nthe same \u003ccode\u003ewith\u003c/code\u003e statement.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7545\"\u003e#7545\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix false positives such as \u003ccode\u003enot-callable\u003c/code\u003e,\n\u003ccode\u003enot-an-iterable\u003c/code\u003e,\n\u003ccode\u003eunpacking-non-sequence\u003c/code\u003e and \u003ccode\u003eno-member\u003c/code\u003e on the\nresult of a function whose\nbody is only \u003ccode\u003e...\u003c/code\u003e, like \u003ccode\u003e@overload\u003c/code\u003e and\n\u003ccode\u003e.pyi\u003c/code\u003e stubs. Such calls were\ninferred as returning \u003ccode\u003eNone\u003c/code\u003e. This affected\n\u003ccode\u003esqlalchemy.func\u003c/code\u003e,\n\u003ccode\u003epydantic.Field\u003c/code\u003e, and the \u003ccode\u003etorch\u003c/code\u003e functions\nwrapped by \u003ccode\u003e_add_docstr\u003c/code\u003e,\nsuch as \u003ccode\u003etorch.linalg.qr\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/8138\"\u003e#8138\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9218\"\u003e#9218\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9354\"\u003e#9354\u003c/a\u003e\nCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/10087\"\u003e#10087\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eprotected-access\u003c/code\u003e when a\nsubclass of a subscripted\ngeneric base, such as \u003ccode\u003eclass Child(Parent[T])\u003c/code\u003e, accesses a\nprotected member\nthrough that base, such as \u003ccode\u003eParent._foo(self)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/8600\"\u003e#8600\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e75de10c69103381c875601f638d4b977ff0fcaf\"\u003e\u003ccode\u003ee75de10\u003c/code\u003e\u003c/a\u003e\nBump pylint to 4.1.3, update changelog (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11637\"\u003e#11637\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/591f6e2b9a258f3a069df9b9af56eb730bcea825\"\u003e\u003ccode\u003e591f6e2\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix protected-access false positive through\na su...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/a537920085b9d92abd54000b674d941063e52030\"\u003e\u003ccode\u003ea537920\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Ignore discard variable type redefinitions\n(\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11635\"\u003e#11635\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/4a8f61ca7c216f8cde5b98faca5590154487eb00\"\u003e\u003ccode\u003e4a8f61c\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix duplicate-code crash when\nmin-similarity-lin...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/41fa1c4ccf7f24ff7e653846a76305500df9ae66\"\u003e\u003ccode\u003e41fa1c4\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] [pyreverse] Fix hang/RecursionError with\n--all-a...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/a05e2f340808daab0fa775cbc39c3ce00e89f576\"\u003e\u003ccode\u003ea05e2f3\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix \u003ccode\u003eused-before-assignment\u003c/code\u003e\nfalse positive for ...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/ea7996b00280e3b8e5fcd9dc4e8e122466abff6a\"\u003e\u003ccode\u003eea7996b\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Error when several output formats write to\nstdou...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/479c0379366e482cda6d842b5d4cca0a52370939\"\u003e\u003ccode\u003e479c037\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix IndexError when Enum\n\u003cstrong\u003einit\u003c/strong\u003e has no argumen...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e6aa780ba6e393a517556000cc81961996585cad\"\u003e\u003ccode\u003ee6aa780\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix unreachable false positive for raising\ngener...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/fc58d0b4aa48eedc03776416998d70dda61dfe48\"\u003e\u003ccode\u003efc58d0b\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.1.x] Fix pyreverse crash on classes with\nEmptyNode in...\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/compare/v4.0.9...v4.1.3\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `python-dateutil` from 3.0.0 to 4.0.0\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/dateutil/dateutil/releases\"\u003epython-dateutil\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e4.0.0\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003edateutil\u003c/code\u003e 4.0 requires Python 3.11 or later and no longer\ndepends on \u003ccode\u003esix\u003c/code\u003e. Apart from that, the changes in this\nrelease are bug fixes, but note that \u003ccode\u003eisoparse\u003c/code\u003e is now\nstricter about the numeric fields it accepts (see below).\u003c/p\u003e\n\u003ch2\u003eDeprecations\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDropped support for Python versions older than 3.11 and removed the\ndependency on \u003ccode\u003esix\u003c/code\u003e, along with Python 2 compatibility\nhelpers that were never part of the public API, such as\n\u003ccode\u003edateutil.tz.tzname_in_python2\u003c/code\u003e. (gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1625\"\u003e#1625\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eBugfixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eparser.isoparse\u003c/code\u003e, and the \u003ccode\u003eisoparser\u003c/code\u003e methods\n\u003ccode\u003eparse_isodate\u003c/code\u003e, \u003ccode\u003eparse_isotime\u003c/code\u003e and\n\u003ccode\u003eparse_tzstr\u003c/code\u003e, now require each numeric field to be exactly\nthe expected number of ASCII digits. Strings that were previously\naccepted, such as \u003ccode\u003e20200728121240\u003c/code\u003e (read as 21:24),\n\u003ccode\u003e2014- 4-21\u003c/code\u003e and \u003ccode\u003e2_14-04-21\u003c/code\u003e, and offsets such as\n\u003ccode\u003e+-1:00\u003c/code\u003e, now raise \u003ccode\u003eValueError\u003c/code\u003e.\n\u003ccode\u003etzical\u003c/code\u003e applies the same check to \u003ccode\u003eTZOFFSETFROM\u003c/code\u003e\nand \u003ccode\u003eTZOFFSETTO\u003c/code\u003e. Reported by \u003ca\nhref\u003d\"https://github.com/janos-gonye\"\u003e\u003ccode\u003e@​janos-gonye\u003c/code\u003e\u003c/a\u003e (gh\nissue \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1074\"\u003e#1074\u003c/a\u003e).\nFixed by \u003ca\nhref\u003d\"https://github.com/varun3257\"\u003e\u003ccode\u003e@​varun3257\u003c/code\u003e\u003c/a\u003e (gh pr\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1617\"\u003e#1617\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003eFixed an issue where iterating over a cached \u003ccode\u003errule\u003c/code\u003e or\n\u003ccode\u003erruleset\u003c/code\u003e could hang forever if another iterator over the\nsame rule had already completed the cache, for example when a cached\n\u003ccode\u003errule\u003c/code\u003e was included twice in an \u003ccode\u003erruleset\u003c/code\u003e.\nReported by \u003ca\nhref\u003d\"https://github.com/bysiber\"\u003e\u003ccode\u003e@​bysiber\u003c/code\u003e\u003c/a\u003e (gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1455\"\u003e#1455\u003c/a\u003e).\nFixed by \u003ca\nhref\u003d\"https://github.com/pganssle\"\u003e\u003ccode\u003e@​pganssle\u003c/code\u003e\u003c/a\u003e (gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1655\"\u003e#1655\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003eUnpickling a \u003ccode\u003etzutc\u003c/code\u003e now gives the\n\u003ccode\u003edateutil.tz.UTC\u003c/code\u003e singleton, and unpickling a\n\u003ccode\u003etzoffset\u003c/code\u003e gives the same object as calling\n\u003ccode\u003etzoffset(name, offset)\u003c/code\u003e. Previously unpickling bypassed the\nsingleton-generation logic. Reported and fixed by \u003ca\nhref\u003d\"https://github.com/masipcat\"\u003e\u003ccode\u003e@​masipcat\u003c/code\u003e\u003c/a\u003e (gh issue\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1051\"\u003e#1051\u003c/a\u003e,\ngh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1053\"\u003e#1053\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erelativedelta(yearday\u003d366)\u003c/code\u003e now resolves to December 31\nin leap years. Previously it gave December 30, the same date as\n\u003ccode\u003eyearday\u003d365\u003c/code\u003e. Reported and fixed by \u003ca\nhref\u003d\"https://github.com/Master-Norna\"\u003e\u003ccode\u003e@​Master-Norna\u003c/code\u003e\u003c/a\u003e\n(gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1583\"\u003e#1583\u003c/a\u003e).\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eMisc\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eThe build backend is now Hatchling, and the package metadata is in\n\u003ccode\u003epyproject.toml\u003c/code\u003e. Versions are still derived from Git tags\nand exposed as \u003ccode\u003edateutil.__version__\u003c/code\u003e. This mainly affects\npeople building \u003ccode\u003edateutil\u003c/code\u003e from source. (gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1637\"\u003e#1637\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1638\"\u003e#1638\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eChanges to CI, tests and release tooling that do not affect users of\nthe package: gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1636\"\u003e#1636\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1644\"\u003e#1644\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1645\"\u003e#1645\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1646\"\u003e#1646\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1648\"\u003e#1648\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1649\"\u003e#1649\u003c/a\u003e,\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1650\"\u003e#1650\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/dateutil/dateutil/blob/master/NEWS\"\u003epython-dateutil\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch1\u003eVersion 4.0.0 (2026-11-01)\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003edateutil\u003c/code\u003e 4.0 requires Python 3.11 or later and no longer\ndepends on\n\u003ccode\u003esix\u003c/code\u003e. Apart from that, the changes in this release are bug\nfixes, but note\nthat \u003ccode\u003eisoparse\u003c/code\u003e is now stricter about the numeric fields it\naccepts (see\nbelow).\u003c/p\u003e\n\u003ch2\u003eDeprecations\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDropped support for Python versions older than 3.11 and removed the\ndependency\non \u003ccode\u003esix\u003c/code\u003e, along with Python 2 compatibility helpers that were\nnever part of\nthe public API, such as \u003ccode\u003edateutil.tz.tzname_in_python2\u003c/code\u003e. (gh\npr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1625\"\u003e#1625\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eBugfixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eparser.isoparse\u003c/code\u003e, and the \u003ccode\u003eisoparser\u003c/code\u003e methods\n\u003ccode\u003eparse_isodate\u003c/code\u003e,\n\u003ccode\u003eparse_isotime\u003c/code\u003e and \u003ccode\u003eparse_tzstr\u003c/code\u003e, now require\neach numeric field to be\nexactly the expected number of ASCII digits. Strings that were\npreviously\naccepted, such as \u003ccode\u003e20200728121240\u003c/code\u003e (read as 21:24),\n\u003ccode\u003e2014- 4-21\u003c/code\u003e and\n\u003ccode\u003e2_14-04-21\u003c/code\u003e, and offsets such as \u003ccode\u003e+-1:00\u003c/code\u003e, now\nraise \u003ccode\u003eValueError\u003c/code\u003e.\n\u003ccode\u003etzical\u003c/code\u003e applies the same check to \u003ccode\u003eTZOFFSETFROM\u003c/code\u003e\nand \u003ccode\u003eTZOFFSETTO\u003c/code\u003e.\nReported by \u003ca\nhref\u003d\"https://github.com/janos-gonye\"\u003e\u003ccode\u003e@​janos-gonye\u003c/code\u003e\u003c/a\u003e (gh\nissue \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1074\"\u003e#1074\u003c/a\u003e).\nFixed by \u003ca\nhref\u003d\"https://github.com/varun3257\"\u003e\u003ccode\u003e@​varun3257\u003c/code\u003e\u003c/a\u003e (gh pr\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1617\"\u003e#1617\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003eFixed an issue where iterating over a cached \u003ccode\u003errule\u003c/code\u003e or\n\u003ccode\u003erruleset\u003c/code\u003e could\nhang forever if another iterator over the same rule had already\ncompleted the\ncache, for example when a cached \u003ccode\u003errule\u003c/code\u003e was included twice\nin an\n\u003ccode\u003erruleset\u003c/code\u003e. Reported by \u003ca\nhref\u003d\"https://github.com/bysiber\"\u003e\u003ccode\u003e@​bysiber\u003c/code\u003e\u003c/a\u003e (gh pr \u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1455\"\u003e#1455\u003c/a\u003e).\nFixed by \u003ca\nhref\u003d\"https://github.com/pganssle\"\u003e\u003ccode\u003e@​pganssle\u003c/code\u003e\u003c/a\u003e (gh pr\n\u003ca\nhref\u003d\"https://redirect.github.com/dateutil/dateutil/issues/1655\"\u003e#1655\u003c/a\u003e).\u003c/li\u003e\n\u003cli\u003eUnpickling a \u003ccode\u003etzutc\u003c/code\u003e now gives the\n\u003ccode\u003edateutil.tz.UTC\u003c/code\u003e singleton, and\nunpickling a \u003ccode\u003etzoffset\u003c/code\u003e gives the same object as calling\n\u003ccode\u003et...\n\n_Description has been truncated_\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "b03080ff6aafdeaf8b3152138e9af3b090cbae77",
      "tree": "510018694da8249cf14c51d75f6fef4a53509067",
      "parents": [
        "03e3dfff74c82d5bb01b5e2437ed2055a1227f1b"
      ],
      "author": {
        "name": "vadikmironov",
        "email": "77026200+vadikmironov@users.noreply.github.com",
        "time": "Mon Nov 09 21:03:37 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 21:03:37 2026 +0000"
      },
      "message": "fix(toolchains): prefer non-debug builds from runtime manifests (#4442)\n\nRuntime manifests added with\n`python.override(add_runtime_manifest_urls \u003d ...)` or\n`add_runtime_manifest_files` can list python-build-standalone debug\n(`Py_DEBUG`) builds; the upstream `SHA256SUMS` does. It is sorted by\nname, so for each platform the `debug-full` archive comes before the\noptimized `full` one. The first entry for a platform key wins and the\nsort ignores the build flavor, so:\n\n- `--@rules_python//python/config_settings:py_pbs_distribution\u003dfull`\n  selects the debug archive. With PBS 20261026 that is every `-full`\n  key, 132 of them for 3.11 to 3.16.0a1.\n- In releases that ship free-threaded runtimes only as `full` archives\n  (for example 20241016 and 20250115), the free-threaded keys get the\n  debug archive under the default distribution too.\n\nA debug archive has a different layout (`include/python3.14d`,\n`libpython3.14d.so`, `python_d.exe`) that the runtime repo does not\nhandle. For example, a `cc_library` on `current_py_cc_headers` fails\nwith `Python.h: No such file or directory`.\n\nRank debug builds (`-debug` and `+debug` flavors) last when sorting\nparsed runtime manifest entries, so non-debug archives are preferred\nwhenever available.\n\nRelated to #1823.\n\n---------\n\nCo-authored-by: Claude Opus 5.5 \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "03e3dfff74c82d5bb01b5e2437ed2055a1227f1b",
      "tree": "a9add64f7e807c0d3c63a1e976fc770602bfc661",
      "parents": [
        "c4ac0a608696624573fce03225d4b103f888807f"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 12:53:27 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 12:53:27 2026 -0800"
      },
      "message": "build(crates): migrate crate_universe to Cargo.toml for Dependabot (#4461)\n\nDependabot fails to evaluate Rust dependencies because the repository\ntracks `crates/Cargo.lock` without a `/crates/Cargo.toml` manifest.\n\nMigrate `crate_universe` from `from_specs` to `from_cargo` backed by a\nchecked-in `crates/Cargo.toml` manifest, update `sha2` to `0.11.1` and\n`zip` to `~9.0.5`, repin the Cargo and Bazel lockfiles, and adapt the\nzipper test for `zip` 9.0\u0027s fallible `entry.name()` API.\n\nCap `zip` below `9.1.0` and configure Dependabot to ignore\n`zip \u003e\u003d 9.1.0` updates. Newer `zip` releases add target-conditional\nOS dependencies that fail on `powerpc64le-unknown-linux-musl` until\n`rules_rust` supports `powerpc64le` platform selection."
    },
    {
      "commit": "c4ac0a608696624573fce03225d4b103f888807f",
      "tree": "147df7c1b5c961eb6adadf63c5aefdc68d099bf2",
      "parents": [
        "de341ed2071371bdaf579df62e155ffd430a0fff"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 12:32:56 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 12:32:56 2026 -0800"
      },
      "message": "ci: mirror downloader dependencies across sub-workspaces (#4459)\n\nTransient 504 gateway timeouts and external download failures cause\nflaky CI builds, especially in examples and integration tests that did\nnot configure Bazel\u0027s downloader rewrite rules.\n\nAdd `mirror.bazel.build` rewrite rules to `downloader_config.cfg`, copy\nthe downloader config into each sub-workspace, and configure\n`--experimental_downloader_config` and retry flags in sub-workspace\n`.bazelrc` files.\n\nDeduplicating shared `.bazelrc` settings and adding tests to verify that\ndownloader configs stay in sync will be addressed in a follow-up PR."
    },
    {
      "commit": "de341ed2071371bdaf579df62e155ffd430a0fff",
      "tree": "aa1edfd09cc0e5673d409f001f688c271f59631c",
      "parents": [
        "68052f29662f0d5d4e87fce6541e8f77deceb744"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 12:06:52 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 12:06:52 2026 -0800"
      },
      "message": "agents: update workflow, Python, and CI skill guidelines (#4462)\n\nWorkflow rules and CI skills lacked guidance for `download-tool`\ncaching, `/.github/actions/*` Dependabot globs, HTTP gateway timeouts,\nand draft PR webhook behavior, causing noisy reviews and misclassified\nCI flakes.\n\nDocument `download-tool`, Dependabot glob, `asyncio`, and docstring\nconventions in the workflow and Python rules. Teach CI failure analysis\nto accept ANSI escape codes from `gh api` and classify HTTP 502/503/504\ngateway errors and Read the Docs `exit-code: 2` failures as flakes.\nUpdate CI monitoring and merge skills to cover timer polling, outage\nbackoff, targeted job retries, and `gh pr ready` webhook sequencing."
    },
    {
      "commit": "68052f29662f0d5d4e87fce6541e8f77deceb744",
      "tree": "e7aed44e498cecffd198f551a517173db552ff48",
      "parents": [
        "1bf79e9fa348aaf5f09161103a95117d16d7dbe2"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 11:58:29 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 11:58:29 2026 -0800"
      },
      "message": "build: enforce ifttt-lint in pre-commit and CI (#4460)\n\nAd-hoc \"Keep in sync\" comments drift silently because no automated\ncheck verifies that paired sections are updated together.\n\nConfigure `ifttt-lint` in `.pre-commit-config.yaml` and\n`.github/workflows/ci.yaml` (extending `download-tool` to extract\narchive members) and convert existing sync comments to\n`LINT.IfChange` and `LINT.ThenChange` directives."
    },
    {
      "commit": "1bf79e9fa348aaf5f09161103a95117d16d7dbe2",
      "tree": "5e0eba19fc3a99238da489b7ce68f4d525b52b65",
      "parents": [
        "1d5ae0ea339e95a9bd1e7130f6eaae326a24a923"
      ],
      "author": {
        "name": "Fabian Meumertzheim",
        "email": "fabian@meumertzhe.im",
        "time": "Mon Nov 09 18:17:26 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 18:17:26 2026 +0000"
      },
      "message": "refactor(toolchains): define the Python toolchain type in rules_python (#4404)\n\n`//python:toolchain_type` is an alias of the type in `@bazel_tools`. To\nmove the type out of `@bazel_tools`, Bazel will forward\n`@bazel_tools//tools/python:toolchain_type` to this target\n(bazelbuild/bazel#32412), which requires it to be the actual type on\nthose Bazel versions.\n\n`//python:toolchain_type` is now a `toolchain_type` if a new value in\nthe `@rules_python_internal` config is set and remains an alias\notherwise, so both labels always refer to the same type. The `config`\nextension sets the value from a `bazel_features` flag, which is `False`\nfor now, so nothing changes yet. WORKSPACE builds leave it unset, as\nBazel versions that forward the type no longer support WORKSPACE. This\nalso avoids requiring `bazel_features` in WORKSPACE builds.\n\nWork towards bazelbuild/bazel#32428\n\n---------\n\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "1d5ae0ea339e95a9bd1e7130f6eaae326a24a923",
      "tree": "8d70cf8b256a87f5eec062a98cf3710c3b9d6433",
      "parents": [
        "c1507d87f71e932604d89100abcf927beff898bd"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Mon Nov 09 09:16:55 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 09:16:55 2026 -0800"
      },
      "message": "chore(release): sync changelog for v2.5.0 backports (#4454)\n\nUpdates CHANGELOG.md and removes news files for backports:\n- #4438\n- #4451\n\nWork towards #4388\nRelease-Tracking-Issue: #4388\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "c1507d87f71e932604d89100abcf927beff898bd",
      "tree": "51b23468f78c24e4b4f77029380ee4248b08cfcc",
      "parents": [
        "071977350ba4a875282e2eba1e16de3801e7040b"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 02:31:30 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 02:31:30 2026 -0800"
      },
      "message": "build: enforce keep-sorted in pre-commit and CI (#4453)\n\nSeveral files use `# keep-sorted` directives, but nothing verified or\nsorted them automatically, allowing stale markers and unsorted blocks\nto slip in.\n\nAdd `google/keep-sorted` to `.pre-commit-config.yaml` and a cached\n`keep-sorted` lint job in GitHub Actions CI, backed by a shared\n`.github/actions/download-tool` action and verified download module\nreused by `setup-bazel`. Also fix existing `keep-sorted` directives so\nall tracked files pass."
    },
    {
      "commit": "071977350ba4a875282e2eba1e16de3801e7040b",
      "tree": "bbd30653535d3529425f5e2750cb3e8a12085044",
      "parents": [
        "3dd56ab0054d9d24ed96a919dfa9cfd348dd95b2"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 00:33:50 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 00:33:50 2026 -0800"
      },
      "message": "docs: speed up Read the Docs builds with RBE and Bazelisk (#4452)\n\nRead the Docs builds previously installed Node.js and npm to fetch\nBazelisk, ran all build actions locally without remote caching, and\npassed container-specific environment variables and unconditional\nstamping that busted action cache keys.\n\nDownload Bazelisk directly via an async Python script, enable BuildBuddy\nremote cache and remote execution (using CAS-only presubmit keys for PRs\nand read/write postsubmit keys for branches and tags), disable lint\naspects and intermediate artifact downloads for RTD builds, and restrict\nforwarded environment variables and stamping to avoid cache busting."
    },
    {
      "commit": "3dd56ab0054d9d24ed96a919dfa9cfd348dd95b2",
      "tree": "2c4f549047801d2f43d4b7ed02e1623b5a811c75",
      "parents": [
        "ab7da31c405b8ab8395e40e24776f6de3166c863"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 09 06:30:04 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 06:30:04 2026 +0000"
      },
      "message": "refactor(pypi): migrate requirements.txt lockfiles to uv.lock (#4379)\n\nMaintaining platform- and version-specific `requirements.txt` files\nalongside `uv.lock` duplicated lockfile targets across `MODULE.bazel`\nand `WORKSPACE` builds.\n\nWith `uv_lock` available in `WORKSPACE` `pip_parse` (#4416) and\n`multi_pip_parse` (#4430), replace the remaining `uv`-generated\n`requirements.txt` lockfiles in `dev`, `tools/publish`, `examples`, and\n`tests/multi_pypi` with unified `uv.lock` files.\n\nCo-authored-by: Ignas Anikevicius \u003c240938+aignas@users.noreply.github.com\u003e"
    },
    {
      "commit": "ab7da31c405b8ab8395e40e24776f6de3166c863",
      "tree": "cf00f27125f4dff73f30960e363e7219c89017e7",
      "parents": [
        "18f52010b1563224cf081ef8f2bbdf48965672ba"
      ],
      "author": {
        "name": "David Sanderson",
        "email": "32687193+dws@users.noreply.github.com",
        "time": "Mon Nov 09 04:28:54 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 09 04:28:54 2026 +0000"
      },
      "message": "fix: stop rules_python from warning about its own implicit __init__.py creation (#4451)\n\nWhen rules_python is used as a Bzlmod dependency without\n--incompatible_default_to_explicit_init_py (which is deprecated in\nBazel 10), rules_python emits implicit __init__.py deprecation\nwarnings for its own internal targets (//tools:wheelmaker,\n//python/private:py_wheel_dist,\n//python/private:py_console_script_gen_py, and\n//tools/publish:twine).\n\nEnable rules_python_config.explicit_init_py(default \u003d True) in\nMODULE.bazel so all targets in rules_python default to explicit\n__init__.py behavior.\n\nCloses #4448"
    },
    {
      "commit": "18f52010b1563224cf081ef8f2bbdf48965672ba",
      "tree": "5a512f71b1b96443d0a52562a1e86eacb1ed8cd4",
      "parents": [
        "44aa9f6c8ca28993c6b766177a50b15c25317b56"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 19:19:20 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 19:19:20 2026 -0800"
      },
      "message": "docs: filter env output in Read the Docs build (#4450)\n\nLogging all environment variables during Read the Docs builds dumps\nnoisy and potentially sensitive unrelated variables into build logs.\n\nFilter `env` output to `READTHEDOC*` variables so logs retain the\nRead the Docs context needed for debugging builds."
    },
    {
      "commit": "44aa9f6c8ca28993c6b766177a50b15c25317b56",
      "tree": "bd5922abf462f258fa168bbab0cb25e4fd764163",
      "parents": [
        "0a309da3a433a792199690d6463dd43bfda75912"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 19:04:54 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 19:04:54 2026 -0800"
      },
      "message": "ci: replace EOL debian11 platform with debian13 (#4443)\n\n`debian11` is end-of-life and triggers an EOL platform warning in Bazel\nCI.\n\nMigrate Debian presubmit and BCR test jobs from `debian11` to\n`debian13`."
    },
    {
      "commit": "0a309da3a433a792199690d6463dd43bfda75912",
      "tree": "e27e8a9575c2d55da56abe6d3234362e24f0c35e",
      "parents": [
        "9fbcb5a2e1b750bc4fea213418a85b35dc0e9281"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 18:55:44 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 18:55:44 2026 -0800"
      },
      "message": "agents: prefix conversation title with \"done \" after cleanup (#4449)\n\nCompleted conversations remain indistinguishable from active ones in the\nconversation list after `conversation-done` reclaims their worktree,\nbranches, and Bazel output bases.\n\nUpdate `.agents/skills/conversation-done/scripts/cleanup.py` and\n`SKILL.md` to prepend `\"done \"` to the active conversation title (up to\n70 characters, without duplicating an existing prefix) via the local\nLanguage Server API once cleanup finishes without errors."
    },
    {
      "commit": "9fbcb5a2e1b750bc4fea213418a85b35dc0e9281",
      "tree": "a490a30ba80badd16c7dc9a2f7692277f0eca906",
      "parents": [
        "d2c47ce28fa422e7d0450cb80e2f22bff756e0df"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 18:28:51 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 18:28:51 2026 -0800"
      },
      "message": "agents: preserve documented rule findings during review-code synthesis (#4447)\n\nInstruct the `review-code` synthesis gate to keep every sub-agent\nfinding backed by `.agents/rules/` or `AGENTS.md` in `## Open Issues`,\nregardless of `NIT` severity or legacy patterns in existing files."
    },
    {
      "commit": "d2c47ce28fa422e7d0450cb80e2f22bff756e0df",
      "tree": "d549f1deb901606bd82061c90a2edfca4bb62967",
      "parents": [
        "f45711741e0e6f4731d2da12509a2ec31e85c41e"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 23:50:06 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 23:50:06 2026 +0000"
      },
      "message": "tests(coverage): use runfiles.CreateOrRaise() and rf.root() in coverage_collection_test (#4446)\n\nUse `runfiles.CreateOrRaise()` and `rf.root()` path navigation instead\nof `runfiles.Create()` with manual `None` assertions and `Rlocation()`\nin `coverage_collection_test.py`.\n\nFollow-up to #4417"
    },
    {
      "commit": "f45711741e0e6f4731d2da12509a2ec31e85c41e",
      "tree": "53cada2a27562de11ef452342502ec88bb62ea28",
      "parents": [
        "01fedb2279e5174bcc9e63f8cdd7ac7ebad72f21"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 22:48:19 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 22:48:19 2026 +0000"
      },
      "message": "fix(pypi): only expose uv.lock packages present on all platforms (#4444)\n\nPreviously, `_parse_uv_lock_json` in\n`python/private/pypi/parse_requirements.bzl`\nset `is_exposed \u003d bool(info[\"resolved_srcs\"])`, which exposed any\npackage that resolved on at least one configured platform in\n`all_requirements` / `all_whl_requirements`. When a `uv.lock` file\nincluded platform-specific dependencies (such as `pywin32-ctypes` on\nWindows), targets depending on `all_requirements` failed to build on\nother platforms with a `_no_matching_repository` error.\n\nUpdate `_parse_uv_lock_json` to compute `is_exposed` using\n`bool(all_platforms) and len(resolved_platforms) \u003d\u003d len(all_platforms)`,\nmatching the multi-platform exposure behavior of\n`_parse_requirements_from_req_files` when `requirements_by_platform` is\nused."
    },
    {
      "commit": "01fedb2279e5174bcc9e63f8cdd7ac7ebad72f21",
      "tree": "95415869d41b80853d0964da72d1a1e6969d9540",
      "parents": [
        "d6cb4504e2e51594d057e3d469bf51743c207e61"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 14:24:49 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 14:24:49 2026 -0800"
      },
      "message": "agents: add Comment Readability Editor pass to review-code (#4445)\n\nDraft review comments from domain auditors sometimes contain dense\nmulti-clause paragraphs, omit concrete suggested wording from\n`Draft Comment`, or wrap lists of identifiers in individual backticks\nthat make rendered Markdown jarring to read.\n\nAdd a `Comment Readability Editor` sub-agent pass and update\n`review-report-format.md` and `SKILL.md` to enforce concise 1-2 sentence\nissue descriptions, include concrete replacement wording under\n`Suggested fix:`, avoid excessive inline backtick switching and outer\nbacktick wrappers, and include a clickable PR link and 2-sentence\noverview at the top of `code-review-results.md`."
    },
    {
      "commit": "d6cb4504e2e51594d057e3d469bf51743c207e61",
      "tree": "7f55ad970d079310d45919a04c67eebd8d776ffc",
      "parents": [
        "cf828825aab6a0426a032105210584e7b5872e2f"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Sun Nov 08 21:15:07 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 21:15:07 2026 +0000"
      },
      "message": "refactor(toolchain): select bundled coverage wheels with select_whl (#4414)\n\nrefactor(toolchain): select bundled coverage wheels with select_whl\n\nBefore this change the coverage wheels bundled with the hermetic\ntoolchain\nwere stored as a nested dict keyed by the python ABI and the toolchain\nplatform, and the platform filtering was done in the Python update\nscript.\n\nNow the update script stores all of the wheels as a flat list using a\nformat similar to `uv.lock` - `struct(url \u003d ..., hash \u003d \"sha256:...\")` -\nand\nthe Starlark side uses `select_whl` to pick the wheel that is compatible\nwith\nthe python version and the toolchain platform. The update script no\nlonger\ndoes any filtering, but it accepts multiple coverage versions, each with\nan\noptional PEP 508 marker for when it should be used, because newer\ncoverage\nreleases drop support for older python versions, e.g.:\n\n```\nbazel run //dev/update_deps:update_coverage_deps -- \\\n    \"7.10.7; python_full_version \u003c \u00273.15\u0027\" \\\n    \"7.17.0; python_full_version \u003e\u003d \u00273.15\u0027\"\n```\n\nThe marker is stored on each wheel and is evaluated against the python\nversion of the toolchain before selecting the wheel.\n\nThe wheel that is selected for each toolchain is unchanged, except for\nthe\npython 3.15+ toolchains on the platforms without a platform specific\nwheel,\nwhich now fall back to the `py3-none-any` wheel of coverage 7.17.0\ninstead of\n7.10.7.\n\nThis prepares for selecting the platform specific wheels for more of the\ntoolchain platforms.\n\nWork towards #3902"
    },
    {
      "commit": "cf828825aab6a0426a032105210584e7b5872e2f",
      "tree": "60c19a30a4c133a2fe8671713416c5049bbc520c",
      "parents": [
        "a476005ea860a4269994d3e92439a9440ecc84e4"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Sun Nov 08 21:06:17 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 21:06:17 2026 +0000"
      },
      "message": "test(coverage): check the coverage collection with the bundled coverage tool (#4417)\n\ntest(coverage): check the coverage collection with the bundled coverage\ntool\n\nBefore this change the coverage collection was only exercised by running\n`bazel coverage` on a few targets in CI and the collected data was not\nchecked.\n\nThis adds tests that run as part of `bazel test`. A `py_reconfig_test`\nis\nbuilt with `--collect_code_coverage` for a Python 3.12 toolchain that\nhas the\nbundled coverage tool configured, and `coverage_collection_test` runs it\nonce\nwith the same environment variables that `bazel coverage` sets. The\nseparate\ntest cases then check the produced lcov file, e.g. that the executed\nlines are\ncovered, that a skipped branch, an uncalled function and an uncalled\nmethod\nare not covered, that the `if` statement has partial branch coverage and\nthat\nthe instrumented files are reported with relative paths.\n\n* Adds the `collect_code_coverage` attribute to `py_reconfig_*` rules.\n* Configures the bundled coverage tool for the Python 3.12.16 dev\ntoolchain.\nA full version is used so that it does not shadow the toolchains that\nare\n  checked in `//tests/toolchains`.\n\nWork towards #3902"
    },
    {
      "commit": "a476005ea860a4269994d3e92439a9440ecc84e4",
      "tree": "53102a281c684d34aa538b1db8198aa5e28800ee",
      "parents": [
        "d9736b2e9a7f30690934e36c03cc2ed580b8bbbe"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Sun Nov 08 20:58:29 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 20:58:29 2026 +0000"
      },
      "message": "fix(toolchain): keep the strip_prefix when single_version_override has no urls (#4435)\n\nKeep the `strip_prefix` of the existing archives when\n`python.single_version_override` does not override the `urls`.\n\nBefore this change, an override that only sets e.g. `libpython` or\n`distutils` reset the `strip_prefix` of every platform to the tag\ndefault\n`python`. Some versions (e.g. 3.13.0) use the `full` archives for the\nfreethreaded builds, which need `python/install`, so such an override\nbroke\nthose toolchains. The `strip_prefix` from the tag is still used for the\nplatforms whose `urls` and `sha256` are overridden.\n\nThis is needed for #4434, which makes `single_version_override` the way\nto set\nthe `coverage_tool` for all platforms of a version."
    },
    {
      "commit": "d9736b2e9a7f30690934e36c03cc2ed580b8bbbe",
      "tree": "ae0670bd5ecb0c1840d1d806694cbdb5c87ac23d",
      "parents": [
        "5f64d496c1da4a610c9feb8a0d19869b701d2b04"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Sun Nov 08 20:57:35 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 20:57:35 2026 +0000"
      },
      "message": "docs(gazelle): document the python_resolve_sibling_imports directive (#4437)\n\nDocument the `python_resolve_sibling_imports` gazelle directive, which\nonly had\na \"Detailed docs are not yet written\" placeholder.\n\nSince 1.6.0 (#3106) gazelle does not resolve absolute imports to sibling\nmodules by default, so e.g. `from typing import TYPE_CHECKING` next to a\n`typing.py` file resolves to the standard library. The docs explain this\ndefault, how to depend on the sibling module with a relative import, and\nhow\nto restore the previous behavior with\n`# gazelle:python_resolve_sibling_imports true`.\n\nThe README of the `sibling_imports` test case claimed that resolving\nsibling\nimports is the default, which is fixed as well.\n\nFixes #3097"
    },
    {
      "commit": "5f64d496c1da4a610c9feb8a0d19869b701d2b04",
      "tree": "2122c777bbff3628ce715e07c76a2ff53843994d",
      "parents": [
        "bc65d5e3baebc423d355c1e1ed48e1a1f299e5a2"
      ],
      "author": {
        "name": "David Sanderson",
        "email": "32687193+dws@users.noreply.github.com",
        "time": "Sun Nov 08 14:06:18 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 14:06:18 2026 +0000"
      },
      "message": "fix(pypi): enable pip.default.envsubst for pip.default.index_url (#4438)\n\nIt turns out that pip.parse.envsubst could not reasonably be used\ntogether\nwith pip.default.index_url, as there could be multiple pip.parse tags\nwith varying contents, so pip.default.index_url would not always be\nprocessed in the same way.\n\nTo cope with this, we here introduce pip.default.envsubst, which can\neffectively be used together with pip.default.index_url.\n\nThis also fixes a testing bug where envsubst was not a list.\n\nCloses #4123\n\n---------\n\nCo-authored-by: Ignas Anikevicius \u003c240938+aignas@users.noreply.github.com\u003e"
    },
    {
      "commit": "bc65d5e3baebc423d355c1e1ed48e1a1f299e5a2",
      "tree": "5a70f526ac5ceb96f8d1f2e4ecf175d810723a44",
      "parents": [
        "8a3b77ca63e2db53a65aea55e999be3de9101831"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 23:18:47 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 23:18:47 2026 -0800"
      },
      "message": "docs: use install_only_stripped runtime for Read the Docs builds (#4439)\n\nReduce the Python runtime download size during Read the Docs builds.\nConfigure the `rtd` Bazel config to use the stripped runtime via\n`--//python/config_settings:py_pbs_distribution\u003dinstall_only_stripped`."
    },
    {
      "commit": "8a3b77ca63e2db53a65aea55e999be3de9101831",
      "tree": "9744ef08c134cf0fb1ae15ae44449eb652628930",
      "parents": [
        "30f81a09648c8537eb4885bdb24184989b2c27b4"
      ],
      "author": {
        "name": "Karlo Delalic",
        "email": "karlo.delalic1@gmail.com",
        "time": "Sun Nov 08 01:47:45 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 01:47:45 2026 +0000"
      },
      "message": "fix(pypi): respect uv.lock dependency platform markers (#4286)\n\nFixes #4287.\n\n`pip.parse` can select Linux-only dependencies on macOS because it\nignores platform conditions on dependency edges in `uv.lock`. For\nexample, `uvloop; sys_platform \u003d\u003d \u0027linux\u0027` incorrectly selects a source\narchive on macOS.\n\nThis change follows dependencies from the workspace roots and keeps each\npackage only on the platforms where it is reachable. It preserves\nsupport for optional extras and development dependency groups.\n\nValidation:\n- All 94 parser and uv-lock tests pass, including regression coverage\nfor platform filtering, extras, and development groups.\n- The real uvloop reproduction now selects only the Linux wheel.\n- Buildifier and `git diff --check` pass.\n\nIncludes updated API documentation and a release note.\n\n---------\n\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "30f81a09648c8537eb4885bdb24184989b2c27b4",
      "tree": "c56612218c1b4f9ee0879a449f4b3181729aa87f",
      "parents": [
        "11f8870be06c4b9dfc506127bad030190d01ba0d"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 08 01:42:41 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 08 01:42:41 2026 +0000"
      },
      "message": "fix(pypi): make requirements_lock optional in multi_pip_parse (#4430)\n\n`multi_pip_parse` required `requirements_lock` as a positional\nargument, preventing `WORKSPACE` users from passing `uv_lock` instead.\n\nDefault `requirements_lock` to `None` in `multi_pip_parse` and forward\nit through `**kwargs` in the generated toolchain wrapper macro."
    },
    {
      "commit": "11f8870be06c4b9dfc506127bad030190d01ba0d",
      "tree": "9ef72e3b6f10656fca4794b4730c89c0c00247a7",
      "parents": [
        "9b057d186a510b041bbf3274c9cbda9afe1e5da1"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 17:31:47 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 17:31:47 2026 -0800"
      },
      "message": "workflows: forward human actor to publish-to-bcr for CLA compliance (#4432)\n\nDispatching release workflows via `gh workflow run` with `GITHUB_TOKEN`\nsets `github.actor` to `github-actions[bot]`, which fails the BCR CLA\ncheck when used as the commit author.\n\nForward `author_name` and `author_email` from `on_comment.yaml` through\n`release_create_rc.yaml`, `release_promote.yaml`, and\n`release_publish.yaml` to `publish.yml`, falling back to `github.actor`\nfor manual dispatches.\n\nWork towards #4388"
    },
    {
      "commit": "9b057d186a510b041bbf3274c9cbda9afe1e5da1",
      "tree": "72faa3826c07e11e3db7a6502a26faed072faae2",
      "parents": [
        "7a252640ce666e54797d274a4c0b7a39ad2daa38"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 10:11:49 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 10:11:49 2026 -0800"
      },
      "message": "agents: structure review-code draft comments with suggested fix and where (#4431)\n\nFree-form draft review comments can omit concrete remediation steps,\ninclude overly long code blocks, or fail to note other locations where\nthe same issue occurs.\n\nUpdate `.agents/skills/review-code/SKILL.md` and\n`review-report-format.md` to structure `Draft Comment` entries with a\nconcise issue description, a bounded `Suggested fix:` (under 20 lines /\n10 sentences), and a `Where:` line listing any additional locations."
    },
    {
      "commit": "7a252640ce666e54797d274a4c0b7a39ad2daa38",
      "tree": "2ae034841d8b8140a7875777c120849050d05fda",
      "parents": [
        "7de3ec5253c6b1b9507cd44c0827331b7c3a68ef"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 00:32:46 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 00:32:46 2026 -0800"
      },
      "message": "refactor(rust): upgrade workspace crates to edition 2024 (#4424)\n\nWorkspace Rust crates and toolchains targeted Edition 2021 (or omitted\nan explicit edition), leaving them misaligned with the project\u0027s Rust\n2024 standard, preventing `let`-chains, and running `rustfmt` under the\nolder style edition.\n\nSet `edition \u003d \"2024\"` on the default and release Rust toolchains and\nacross workspace Rust library, binary, and test targets. Flatten nested\nconditionals into `let`-chains and reformat sources under the 2024\nstyle edition."
    },
    {
      "commit": "7de3ec5253c6b1b9507cd44c0827331b7c3a68ef",
      "tree": "1e783b33a51326c980744c6d66c7463a1866c4aa",
      "parents": [
        "ca685344e4859d236df06f3b14015f1758ff4976"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 00:03:57 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 00:03:57 2026 -0800"
      },
      "message": "agents: document cross-branch workflow dispatch and draft PR merge (#4425)\n\nWhen workflows on `main` operate on another branch (such as\n`release/X.Y`), calling reusable workflows via `uses:` mixes `main`\nworkflow definitions with target-branch scripts. In addition, merging a\ndraft PR via `gh pr merge` fails unless the PR is marked ready first.\n\nDocument cross-branch `gh workflow run --ref` dispatch, fast-fail ref\nparsing, and contextual `::error::` reporting in the workflow rules and\nreview prompt, and instruct the merge skill to run `gh pr ready` before\nmerging draft PRs."
    },
    {
      "commit": "ca685344e4859d236df06f3b14015f1758ff4976",
      "tree": "69ac013284e00888cf6d0603bd1ebece5c4d8893",
      "parents": [
        "a832b2d175db979c0fdc84b20eb1cbbe6b5431c0"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Nov 06 23:46:24 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 06 23:46:24 2026 -0800"
      },
      "message": "workflows: dispatch release issue workflows against the release branch (#4422)\n\nWhen release commands (such as `/create-rc`, `/process-backports`,\n`/sync-changelog`, or `/promote`) are triggered via comments on a\nrelease tracking issue, `on_comment.yaml` runs on `main` and previously\ninvoked reusable workflows from `main` via `uses:`. When `main` diverges\nfrom the `release/X.Y` branch, workflow and script changes on `main` can\nfail against the older release branch.\n\nTo run the release branch\u0027s own workflow definitions, extract the\n`release/X.Y` branch name from the release issue title in\n`on_comment.py` and dispatch the post-branch release workflows\n(`create-rc`, `process-backports`, `sync-changelog`, and `promote`) on\nthat branch using `gh workflow run --ref`."
    },
    {
      "commit": "a832b2d175db979c0fdc84b20eb1cbbe6b5431c0",
      "tree": "80c1cb450f61d2461a19a1a8e48857d60b264298",
      "parents": [
        "4adca25a0558aa3f6f00784625eeddb3c5d272b7"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Nov 06 23:17:44 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 06 23:17:44 2026 -0800"
      },
      "message": "agents: add pipeline reuse, type uniformity, and WORKSPACE parity rules (#4421)\n\nAgent implementations of WORKSPACE features (such as #4374 vs. #4416)\npreviously invented parallel repository rules, format converters, and\nruntime union-type branches instead of reusing existing pipelines and\ncanonical data types. This duplicated Bzlmod logic, broke host\nportability for vendored `requirements.bzl` files, and modified\nunrelated code.\n\nCodify the design and Starlark rules from #4416 so agents:\n* Trace existing call graphs and extend existing `WORKSPACE` rules and\n  pipelines (`parse_requirements` -\u003e `requirements.bzl.tmpl.workspace`\n  -\u003e `whl_library`) at the narrowest seam rather than adding parallel\n  rules or format converters.\n* Extract pure helpers needed by both Bzlmod and `WORKSPACE` into\n  standalone Bzlmod-agnostic `.bzl` files.\n* Preserve host portability in vendored `requirements.bzl` by emitting\n  direct downloader attributes only when a package resolves to a single\n  cross-platform distribution, falling back to `--hash` flags for\n  platform-specific wheels.\n* Enforce uniform parameter, return, and collection types across callers\n  and test fixtures without runtime union-type branches.\n* Leave working code untouched unless required and decompose multi-stage\n  functions into focused helpers."
    },
    {
      "commit": "4adca25a0558aa3f6f00784625eeddb3c5d272b7",
      "tree": "65eaa97e3d363a9adf6572a23091c2aaff57ebde",
      "parents": [
        "d0d6e3288fc1e6710669c90b54dfe38addafc415"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Nov 06 22:59:21 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 06 22:59:21 2026 -0800"
      },
      "message": "refactor(rust): allow unwrap in tests; restyle expect messages (#4423)\n\nFollows up on post-merge review feedback on #4407\n\n(https://github.com/bazel-contrib/rules_python/pull/4407#discussion_r4500292802):\ntests should be free to panic, so unwrap() and expect() should not be\nlint errors there.\n\nTo do so, drop the global `-Dclippy::unwrap_used` flag and add a\n`.clippy.toml` with the `allow-*-in-tests` settings. Production crates\nkeep enforcing `deny(clippy::expect_used, clippy::unwrap_used)`\nthemselves via crate-level attributes.\n\nThe global flag has to go because clippy\u0027s `allow-*-in-tests` only\nrecognizes `#[test]` functions and `#[cfg(test)]` items. Helper\nfunctions in integration-test crates match neither, so a global\n`unwrap_used` would still flag them. Relying on crate-level `deny`\nattributes scopes the lint to production code only.\n\nTest `expect()` messages now follow std\u0027s recommended style: they state\nwhy the value should be `Ok` rather than naming the failed action.\n\nAlso records these conventions in `.agents/rules/rust.md`."
    },
    {
      "commit": "d0d6e3288fc1e6710669c90b54dfe38addafc415",
      "tree": "eb746b57f014ff2b3a2e7cdadb10bc23a4b51284",
      "parents": [
        "498fdca04a7cf88a8901236ce56c0e7089bad502"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Sat Nov 07 05:58:37 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 05:58:37 2026 +0000"
      },
      "message": "feat(pypi): support uv.lock in WORKSPACE pip_parse (#4416)\n\nfeat(pypi): support uv.lock in WORKSPACE pip_parse\n\nBefore this change `uv.lock` files could be generated with the `lock`\nrule\nunder `WORKSPACE`, but only `pip.parse` under bzlmod could consume them.\n\n`parse_requirements` already supports `uv.lock`, so this adds the\n`uv_lock`\nattribute to `pip_repository` (and thus `pip_parse`) and passes it\ntogether\nwith the TOML decoder to `parse_requirements`. The host platform now\ngets the\nwhl ABI and platform tags from the same default platforms that are used\nby\nbzlmod, which are moved out of `extension.bzl` into\n`default_platforms.bzl` so\nthat they can be loaded without bzlmod.\n\nThe generated `requirements.bzl` encodes the `urls`, `integrity` and\n`filename` of the distributions in a new `_package_srcs` dict that\n`install_deps` passes to `whl_library`, so that they are downloaded with\nthe\nBazel downloader. Because `requirements.bzl` may be vendored and used on\nany\nplatform, this is only done for distributions that are the same on all\nplatforms. For the other packages the requirement line includes the\nhashes of\nall of the locked distributions, so that `pip` selects the one for the\nhost\nplatform from the locked set.\n\n* Also switches `examples/pip_parse_vendored` to `uv.lock`."
    },
    {
      "commit": "498fdca04a7cf88a8901236ce56c0e7089bad502",
      "tree": "89302d49ae8caa0e6143c1988c89aa3f1ef1828b",
      "parents": [
        "21e26e1d2b7426e809a6f934feb46b813327d087"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Sat Nov 07 05:46:50 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 05:46:50 2026 +0000"
      },
      "message": "chore(release): sync changelog for v2.5.0 backports (#4419)\n\nUpdates CHANGELOG.md and removes news files for backports:\n- #4401\n\nWork towards #4388\nRelease-Tracking-Issue: #4388\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "21e26e1d2b7426e809a6f934feb46b813327d087",
      "tree": "2aa6ac77ca49ea4cd1e31ce3c930b474c6afb552",
      "parents": [
        "7fd5496f177699940dd57decc4ed7695d966d151"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 05:34:37 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 05:34:37 2026 +0000"
      },
      "message": "refactor(zipapp): port zipper to Rust and add it to the shrubbery toolchain (#4407)\n\nReplaces the Python zipper used by py_zipapp\u0027s PyZipAppCreateZip action\nwith a Rust implementation, so creating zipapps no longer requires a\nPython interpreter in the exec configuration.\n\nThe crates/zipper library mirrors tools/zipapp/zipper.py: same manifest\nformat, symlink-precedence sorting, sandboxed source symlink detection,\nfixed 1980-01-01 timestamps, and permission preservation. It is exposed\nas the `zipper` shrubbery subcommand and selected via\nget_shrubbery_tool,\nfalling back to the Python tool when shrubbery is unavailable.\n\nThe `zip` crate is pinned to 8.x: 9.x adds target-conditional OS deps\nthat fail on powerpc64le until rules_rust supports that platform (see\nthe NOTE in MODULE.bazel).\n\nError handling uses `anyhow` so failures name the manifest line or the\npath they concern. Rust code is linted in CI by a new `rust_lint`\nBazelCI task (`bazel build --config\u003drust-lint //...`), which runs\nclippy with warnings as errors and `unwrap()` forbidden, checks\nrustfmt, and denies `expect()` in the non-test crates.\n\n## Performance\n\nZip creation time only (x86_64 Linux, `-c opt`; median of 5 runs for\nthe small cases, single run for the large ones):\n\n```\nWorkload                            Comp  Python   Rust  Ratio\n3k .py + 5x8 MB blobs (46 MB)         0    0.43s  0.26s   1.6x\nsame                                  6    1.48s  1.59s   0.9x\n10k small .py files                   0    1.19s  0.70s   1.7x\nsame                                  6    1.42s  1.07s   1.3x\nCPython runtime + 10k .py (405 MB)    0    4.08s  1.19s   3.4x\n+ torch/CUDA wheels (7.3 GB, ZIP64)   0    9.7s   7.9s    1.2x\n+ torch/CUDA wheels                   6    335s   370s    0.9x\n```\n\nRust is faster on per-entry overhead, which dominates the default\nuncompressed case. Deflate throughput is ~10% slower because `flate2`\nuses the pure-Rust miniz_oxide backend (chosen so the tool\ncross-compiles for all `dev/platforms`); CPython\u0027s `zipfile` uses C\nzlib."
    },
    {
      "commit": "7fd5496f177699940dd57decc4ed7695d966d151",
      "tree": "88720d40b325a405800aea4837e79076853931d1",
      "parents": [
        "d15e1b0d81ee2700f6826ed86dfced0601d602b1"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Nov 07 04:41:48 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 07 04:41:48 2026 +0000"
      },
      "message": "workflows: publish gazelle in a separate BCR pull request (#4413)\n\nPublishing `rules_python` and `rules_python_gazelle_plugin` in a single\nBCR pull request couples `rules_python_gazelle_plugin` presubmit and\nreview to `rules_python` releases.\n\nRestrict the `publish` job to `.` and add a `publish_gazelle` job with\n`module_roots: gazelle` so `rules_python_gazelle_plugin` is submitted in\nits own BCR pull request."
    },
    {
      "commit": "d15e1b0d81ee2700f6826ed86dfced0601d602b1",
      "tree": "53905c2aeddea29a992e2c9717547cb481d71ff7",
      "parents": [
        "26b0a238d28e072b3617d7eccb9fd15f6580a5ab"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Nov 06 19:51:05 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Nov 06 19:51:05 2026 +0000"
      },
      "message": "docs(uv): clarify uv.lock WORKSPACE support and remove outdated caveat (#4410)\n\nThe lock documentation previously labeled `uv.lock` as bzlmod-only and\nwarned that `uv pip compile` had rough edges with private mirrors. In\npractice, the `lock` rule generates `uv.lock` files under both bzlmod\nand WORKSPACE, and only consuming `uv.lock` via `pip.parse.uv_lock`\nrequires bzlmod. The private mirror warning is also outdated.\n\nUpdate the lock documentation to distinguish between generating\n`uv.lock` (bzlmod and WORKSPACE) and consuming it (bzlmod only), and\nremove the obsolete private mirror warning."
    },
    {
      "commit": "26b0a238d28e072b3617d7eccb9fd15f6580a5ab",
      "tree": "f4d01e84115a56ebfd9709b3af66311e5380ff04",
      "parents": [
        "ed32477cde3f28e1bf90819b121fcfc9c8f50ff3"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Nov 05 23:12:27 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 05 23:12:27 2026 -0800"
      },
      "message": "docs(contributing): mention uv lock target for generated lock files (#4411)\n\nThe generated files guide in `CONTRIBUTING.md` only referenced\n`compile_pip_requirements`, omitting the `uv` `lock` rule used for dev\nand docs dependencies.\n\nUpdate the requirements lock files guidance to mention `lock` and its\n`.update` target alongside `compile_pip_requirements`."
    },
    {
      "commit": "ed32477cde3f28e1bf90819b121fcfc9c8f50ff3",
      "tree": "a4b43e76784c800342a36d7d62ee3b766c613e4a",
      "parents": [
        "c1d09ef447a679973178a79487909dbe757d7b3f"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Nov 05 21:28:42 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 05 21:28:42 2026 -0800"
      },
      "message": "agents: add Rust positional arg count and local execution rules (#4412)\n\nFixed-arity Rust CLI parsers used match guards and fixed-size array\n`try_from` conversions for positional argument counts, and per-mnemonic\n`--strategy\u003dRustc\u003dlocal` overrides caused host `glibc` version\nmismatches on remote test runners.\n\nRequire explicit length checks for fixed positional argument counts and\n`--spawn_strategy\u003dlocal` when overriding remote execution locally."
    },
    {
      "commit": "c1d09ef447a679973178a79487909dbe757d7b3f",
      "tree": "a9279a9ccdd7c4555bc301c57b4a70f43396d398",
      "parents": [
        "6442c45c9699f3ec860a7cdb7fbfd6c523a2cf73"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Nov 05 21:10:42 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 05 21:10:42 2026 -0800"
      },
      "message": "workflows: publish sphinxdocs in a separate BCR pull request (#4409)\n\nPublishing `rules_python`, `rules_python_gazelle_plugin`, and\n`sphinxdocs` in a single BCR pull request couples `sphinxdocs` presubmit\nand review to `rules_python` releases.\n\nBump `bazel-contrib/publish-to-bcr` to `v1.7.0`, restrict the `publish`\njob to `.` and `gazelle`, and add a `publish_sphinxdocs` job with\n`module_roots: sphinxdocs` so `sphinxdocs` is submitted in its own BCR\npull request."
    },
    {
      "commit": "6442c45c9699f3ec860a7cdb7fbfd6c523a2cf73",
      "tree": "d243444d2e1d151d074c9e703cc54fb5b3b4ddd0",
      "parents": [
        "33f3e58e3dfb7a54c06cde7bd259ad12f2322e8a"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Nov 05 21:05:31 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 05 21:05:31 2026 -0800"
      },
      "message": "refactor(exe_zip_maker): use lexopt for CLI argument parsing (#4406)\n\nHand-rolled positional slice indexing in `exe_zip_maker` provides no\nstructured flag handling or typed options.\n\nParse CLI arguments with `lexopt` into a typed `Options` struct and\ndelegate from `run_cli`.\n\nWork towards #4250"
    },
    {
      "commit": "33f3e58e3dfb7a54c06cde7bd259ad12f2322e8a",
      "tree": "a537122707ca886c1586ce97ac59f84a2cb977ae",
      "parents": [
        "a68dc327bb38766f02a3ae8e0d559a0cf39372ff"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Nov 05 20:55:13 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 05 20:55:13 2026 -0800"
      },
      "message": "docs(uv): update README and lock docs for uv.lock support (#4408)\n\nThe documentation still described `uv.lock` support as planned, even\nthough `pip.parse` and `lock` now support `uv.lock` files directly under\nBzlmod.\n\nUpdate the documentation to reflect current `uv.lock` support and note\nthat `uv.lock` already includes cross-platform distribution URLs and\nhashes, avoiding PyPI Simple API queries and storing hashes in\n`MODULE.bazel.lock`.\n\nWork towards #4278"
    },
    {
      "commit": "a68dc327bb38766f02a3ae8e0d559a0cf39372ff",
      "tree": "8317081721d7440ddd14bed5d558508f229a91b2",
      "parents": [
        "48d3a9aa5f300c6e730fe7b9f70cce89b68a0c8d"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Wed Nov 04 21:12:11 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 04 21:12:11 2026 -0800"
      },
      "message": "agents: add Rust coding rules and review-code auditor (#4405)\n\nRust tooling and crate dependencies lacked dedicated coding conventions\nand code review checks, allowing hand-rolled subsystems, unvetted or\noutdated crates, and non-idiomatic CLI or error handling to slip\nthrough.\n\nAdd `.agents/rules/rust.md` covering ecosystem crate usage over custom\nsubsystems, `crates.io` dependency vetting and versioning, feature\npruning for hermetic cross-compilation, and idiomatic Rust CLI and crate\nlayout. Add a `Rust Code Auditor` sub-agent prompt to `review-code` and\ninclude `*.rs` in cross-language code style checks."
    },
    {
      "commit": "48d3a9aa5f300c6e730fe7b9f70cce89b68a0c8d",
      "tree": "c41824b6f742fbb979b795fc010123ea2e4b6503",
      "parents": [
        "fb5ad02bacb7b33e95e74e5b3ce60fdc69218bc2"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Wed Nov 04 01:48:30 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 04 01:48:30 2026 +0000"
      },
      "message": "refactor(toolchains): generalize exe_zip_maker into shrubbery toolchain (#4402)\n\nSeparate per-tool Rust binaries and toolchains duplicate the Rust\nstandard library across release artifacts and require distinct toolchain\ntypes and flags for every converted build tool.\n\nReplace the standalone `exe_zip_maker` binary and toolchain with the\nunified `shrubbery` (\"Shell replacements for Bazel build tools in Rust\")\nsubcommand binary and `shrubbery_toolchain`\n(`--//python/private/toolchains:need_shrubbery`), and route both\n`py_zipapp` and `py_binary` self-executable zip creation through\n`get_shrubbery_tool`.\n\nWork towards #4250"
    },
    {
      "commit": "fb5ad02bacb7b33e95e74e5b3ce60fdc69218bc2",
      "tree": "12cb7e478ca2428da58a91b886f966106dd9a218",
      "parents": [
        "c0cc20677f9449b65970b0cb46474187099627f0"
      ],
      "author": {
        "name": "Jonathan Gopel",
        "email": "jgopel@gmail.com",
        "time": "Tue Nov 03 17:43:18 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 03 17:43:18 2026 +0000"
      },
      "message": "fix: make main_module work with precompiling (#4403)\n\nExecutables using `main_module` and `pyc_collection \u003d \"include_pyc\"`\nfail during analysis. This failure is due to the fact that the bytecode\ncollection handling expects a main file reference in the source to\nbytecode map, but `main_module` explicitly does not have this because\nmodule entrypoints are resolved at runtime.\n\nPython\u0027s import machinery resolves module entrypoints at runtime and\nsupports bytecode loading, so in that case there\u0027s no file entry point\nto find during analysis. Limit the analysis-time entrypoint substitution\nto file-based entrypoints.\n\n---------\n\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "c0cc20677f9449b65970b0cb46474187099627f0",
      "tree": "a06c8afe6f1632fc7ba5cdd368b359603207409b",
      "parents": [
        "3f3e7eaf4fdd47a587c4bc352f790726c664a938"
      ],
      "author": {
        "name": "Ignas Anikevicius",
        "email": "240938+aignas@users.noreply.github.com",
        "time": "Tue Nov 03 06:47:19 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 03 06:47:19 2026 +0000"
      },
      "message": "fix(bzlmod): use a minimalistic schema facilitating shallow merging (#4394)\n\nIt seems that the automatic bzlmod lockfile driver is doing only shallow\nmerging, let\u0027s use a different schema that is much more friendly towards\nsuch workflows. Before this PR users would have to manually resolve git\nconflicts or regenerate the lockfile from scratch, with this it will\nwork better as the bazel authors intended.\n\nFlatten `pip` extension lockfile facts (`v3`) to top-level per-package\nkeys (`\u003cpkg\u003e#\u003cindex_url\u003e` and `\u003croot_url\u003e \u003cdistribution\u003e`) with compact\npipe-delimited distribution metadata strings.\n\nFixes #4162\nRelated bazelbuild/bazel#31139\n\n---------\n\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e\nCo-authored-by: Claude Opus 5.5 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "3f3e7eaf4fdd47a587c4bc352f790726c664a938",
      "tree": "9a55a7d40bc30c09deaef9eaa59a79bebe07a142",
      "parents": [
        "822a3b77b3a869f17d647ab72eef3c099974b4d5"
      ],
      "author": {
        "name": "snakethatlovesstaticlibs",
        "email": "94087198+snakethatlovesstaticlibs@users.noreply.github.com",
        "time": "Tue Nov 03 03:26:00 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 03 03:26:00 2026 +0000"
      },
      "message": "fix(coverage): bundle Python 3.15 coverage wheels (#4401)\n\nPython 3.15 toolchains can run tests, but bazel coverage fails during\nanalysis when configure_coverage_tool \u003d True. Without cp315 entries, the\ncoverage dependency table selects a pure Python fallback wheel, causing\nthe generated BUILD file’s coverage/*.so glob to fail.\n\nAdd coverage.py 7.17.0 wheels for Python 3.15 on Linux and macOS,\nincluding free-threaded interpreters. Preserve existing wheels for older\nPython versions, since upgrading the entire table would drop Python 3.9\nand 3.10 support.\n\nUpdate the dependency generator to include cp315 and recognize the macOS\n10.15 x86_64 wheel tag."
    },
    {
      "commit": "822a3b77b3a869f17d647ab72eef3c099974b4d5",
      "tree": "d48294d63297176b6714bfb7fe781817d4d0369b",
      "parents": [
        "220231eefc84a435283afb59e011054624b9a73b"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Nov 02 10:32:27 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 02 10:32:27 2026 -0800"
      },
      "message": "agents: clarify PR disclosure trigger and field/path documentation rules (#4400)\n\nThe phrase \"creates or interacts on a PR\" caused agents to post\nstandalone AI disclosure comments when pushing commits to existing PRs\n(such as Dependabot PRs), and code style rules lacked explicit guidance\nfor documenting dataclass fields, Starlark `struct()` fields, and\nrelative path bases.\n\nUpdate `AGENTS.md`, `CONTRIBUTING.md`,\n`.github/PULL_REQUEST_TEMPLATE.md`, `.agents/rules/pr.md`, and\n`.agents/skills/create-pr/SKILL.md` to require a standalone AI\ndisclosure comment (explaining how PR comments will be handled) only\nwhen initially creating a PR, while using the per-comment italicized\nfooter when posting comments or replies. Add rules and `review-code`\nchecks in `.agents/rules/` (`python.md`, `code-style.md`, and\n`starlark.md`) requiring field comments above dataclass and returned\n`struct()` fields and documenting what relative paths are relative to."
    },
    {
      "commit": "220231eefc84a435283afb59e011054624b9a73b",
      "tree": "f8e0211b4b159b6fd22bd0a31b71d34610f74150",
      "parents": [
        "7e0885dfe3e295145e1b0e195e5893a27295e471"
      ],
      "author": {
        "name": "Kristian Hartikainen",
        "email": "kristian.hartikainen@gmail.com",
        "time": "Mon Nov 02 03:47:10 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 02 03:47:10 2026 +0000"
      },
      "message": "docs(gazelle): Clarify manifest paths in subdirectories (#4397)\n\nMy agent pointed out that #3133 is not actually a bug put just a user\nerror. Gazelle resolves the root manifest paths relative to each `BUILD`\nfile, so the directives in #3133 example need a `../` prefix.\n\nThis documents the path base and relative manifest lookup.\n\nCloses #3133.\n\n---------\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "7e0885dfe3e295145e1b0e195e5893a27295e471",
      "tree": "c0c499b3e77921dc0635da4446b29b32868f1ae7",
      "parents": [
        "95347ca1b5b9379f44d1d091514514c4ac32d029"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 01 13:45:26 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 13:45:26 2026 -0800"
      },
      "message": "workflows: resolve code-scanning alerts and harden security guardrails (#4399)\n\nAdd explicit least-privilege permissions across GitHub Actions workflows\nto resolve actions/missing-workflow-permissions findings (#23, #25, #30,\n#36, #37, #43).\n\nRemove workflow_dispatch from release_build_artifacts.yaml and drop\nfreeform input from publish_pypi.yaml to eliminate cache poisoning via\nuntrusted ref checkout (#40, #41). Validate release tags in\npublish_pypi.yaml prior to checkout and caching.\n\nSwitch URL substring checks in developer agent scripts to strict netloc\nverification via urllib.parse.urlsplit (#19, #20).\n\nRename mock tokens in uv_lock_pypi_server.py to avoid heuristic\nsensitive naming, and document intentional mock logging with CodeQL\nsuppressions (#17, #18).\n\nEnforce these security invariants in agent rules and code review\nprompts."
    },
    {
      "commit": "95347ca1b5b9379f44d1d091514514c4ac32d029",
      "tree": "477cc25339e3b4bb8bfd8283a87b34a1d4c29b28",
      "parents": [
        "889814431cfdcb2a1e2b195ee4096832d750a1b4"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 01 12:42:53 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 12:42:53 2026 -0800"
      },
      "message": "workflows: run release artifact build checks from ci.yaml (#4398)\n\nRelease workflows should not trigger directly on pull request or push\nevents; CI checks belong in the CI workflow.\n\nRemove the `pull_request` trigger from `release_build_artifacts.yaml`,\nmake its `workflow_call` `ref` input optional, and invoke it as a\nreusable workflow job from `ci.yaml`."
    },
    {
      "commit": "889814431cfdcb2a1e2b195ee4096832d750a1b4",
      "tree": "5b9cafe733867b2f6108465cab0e86a47de28ca1",
      "parents": [
        "58d180788817999c086d285898607e465c4f5119"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 01 12:08:54 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 12:08:54 2026 -0800"
      },
      "message": "agents: add merge-queue and soft-failure CI lessons (#4393)\n\nShepherding #4262 surfaced two agent mistakes: assuming merge-queue\nbuilds skip Buildkite\u0027s CI config approval step, and reporting\nsoft-failed jobs as passed. Raw `bk job log` output also defeated\nsimple greps.\n\nThe CI skills now cover finding and unblocking merge-queue builds,\nwhich changed files trigger the approval step, checking soft-failed\njobs against the latest main build, and cleaning job logs before\ngrepping."
    },
    {
      "commit": "58d180788817999c086d285898607e465c4f5119",
      "tree": "e7b38a5e6615eaca207a785b1ae539fddc2b1030",
      "parents": [
        "8f1569692ad3773c30ae327182ccc8863759a9a7"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 01 12:08:49 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 12:08:49 2026 -0800"
      },
      "message": "build: check presubmit.yml flag notation and diff task flags (#4392)\n\nUpstream #4263 made build_flags and test_flags mappings of `?` keys so\ntasks can merge shared flag sets. Nothing enforces that notation, and\na one-line edit to a shared anchor can change dozens of jobs without\nshowing which ones in the diff.\n\nA test now fails when a task writes its flags as a list or gives a `?`\nkey a value. A dev tool, `bazel run //dev/bazelci:diff_presubmit_flags`,\nshows each task\u0027s effective flags before and after an edit, resolving\nYAML merges the way bazelci.py does. A new agent rule for `.bazelci/`\ndocuments the conventions and points to both."
    },
    {
      "commit": "8f1569692ad3773c30ae327182ccc8863759a9a7",
      "tree": "6460898c74743092dd19c55e7cee8bf8d7cf010f",
      "parents": [
        "6f97c5f3e6e33af86412e954a01b2a17c6ab4906"
      ],
      "author": {
        "name": "Kristian Hartikainen",
        "email": "kristian@ekarobotics.com",
        "time": "Sun Nov 01 10:24:45 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 10:24:45 2026 +0000"
      },
      "message": "fix(pypi): include platform-specific packages in unified hub (#4172)\n\n(Done with help from an agent.)\n\nThe unified `@pypi` hub omits packages that appear only in some\nplatform-specific requirements files. Dependencies such as `@pypi//six`\ntherefore fail to resolve even on platforms where the selected concrete\nhub provides the package.\n\nThis PR collects unified aliases from each hub’s complete wheel map so\nthat platform-specific packages remain accessible. The concrete hub’s\naliases continue to enforce platform compatibility.\n\nCloses #4171.\n\n---------\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "6f97c5f3e6e33af86412e954a01b2a17c6ab4906",
      "tree": "63eb962b67ed9668ece20020baf36b467b38cf60",
      "parents": [
        "54b62051d4c93b340f73ec0df9ebef3e0e2d40f9"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Nov 01 01:42:10 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 01 01:42:10 2026 -0700"
      },
      "message": "build(release): switch x86_64 Linux release artifacts to musl (#4391)\n\nPreviously, `x86_64` Linux release artifacts linked static `glibc`,\ninflating `exe_zip_maker` to 1.37 MB with over 840 KB of static\n`glibc` code and tables.\n\nSwitch the `x86_64` Linux release platform and toolchain registration\nto `x86_64-unknown-linux-musl` linked with `rust-lld`. This matches\nthe other Linux architectures, avoids host `glibc` and `ld.bfd` quirks,\nand shrinks the statically linked binary to ~603 KB while preserving\nportability across Linux distributions.\n\nWork towards #4216"
    },
    {
      "commit": "54b62051d4c93b340f73ec0df9ebef3e0e2d40f9",
      "tree": "586ebae7d4fe128d0b132a5ff18a94e8b801f706",
      "parents": [
        "ca713c1f0485024ec72fadae2c433f68a5555c9f"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sat Oct 31 22:13:36 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 31 22:13:36 2026 -0700"
      },
      "message": "build(release): upload artifacts_manifest.json to GitHub releases (#4390)\n\nSwitching the release manifest generator to emit\n`artifacts_manifest.bzl` (#4370) dropped the standalone\n`artifacts_manifest.json` output, and the publish workflow never\ndownloaded `release-manifest` to attach it to the GitHub release.\n\nGenerate both `artifacts_manifest.bzl` (bundled into the source\narchive) and `artifacts_manifest.json` via explicit `--bzl-output` and\n`--json-output` flags, upload `artifacts_manifest.json` in the\n`release-manifest` workflow artifact, and download and attach it to the\nGitHub release during publishing.\n\nWork towards #4250"
    },
    {
      "commit": "ca713c1f0485024ec72fadae2c433f68a5555c9f",
      "tree": "61ecf16da78b58e1c13b41860831c46fcec09417",
      "parents": [
        "6fee02b2b1e989692af0109add5ff951f616b1b3"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Oct 30 22:59:06 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 22:59:06 2026 -0700"
      },
      "message": "agents: restore missing rule frontmatter and refine CI/rule guidance (#4387)\n\nSeveral agent rules lacked YAML trigger frontmatter, preventing agent\ndiscovery, while CI monitoring and merge workflows alerted on expected\nmerge-blocking label gates, woke parent conversations early during\nfailure analysis, and contended over monitor locks. Domain rules also\nomitted guidance on executable target forwarding, Windows `.exe` CLI\noutput matching, and bidirectional alias cross-references.\n\nAdd `model_decision` frontmatter to unindexed rules and document those\nStarlark, Windows, and documentation conventions. Update CI monitoring\nand merge skills to ignore expected `blocks-do-not-merge` failures when\nthe merge-blocking label is active, scope failure analyzer alerts to\nthe analyzer subagent, and release active CI monitor locks before\nlaunching the merge shepherd."
    },
    {
      "commit": "6fee02b2b1e989692af0109add5ff951f616b1b3",
      "tree": "1523e4bdcdfe5f4a5a8e8493b8953cd96f41540f",
      "parents": [
        "94858322db706c5044ab5b16f784b13a0b4a35a4"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Sat Oct 31 05:35:58 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 31 05:35:58 2026 +0000"
      },
      "message": "Prepare release v2.5.0 (#4389)\n\nWork towards #4388\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "94858322db706c5044ab5b16f784b13a0b4a35a4",
      "tree": "f8c6afad1998426938643d27fe45a14707b41237",
      "parents": [
        "e9734b5ff9173b65a6524b8fc02b2a0d8ffce8db"
      ],
      "author": {
        "name": "Tamir Duberstein",
        "email": "tamird@gmail.com",
        "time": "Sat Oct 31 00:42:41 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 31 00:42:41 2026 +0000"
      },
      "message": "fix(pypi): generate namespace package initializers without a shell (#4385)\n\nWheel namespace packages use an __init__.py file generated from a\nchecked-in template. Skylib\u0027s copy_file invokes cp through a shell on\nUnix, which fails on execution platforms that provide neither program.\n\nUse expand_template with no substitutions. This produces a regular\nfile with the same bytes from the same template, without spawning a\nprocess on the execution platform.\n\nThe namespace initializer generator was introduced in\nhttps://github.com/bazel-contrib/rules_python/commit/dce512024."
    },
    {
      "commit": "e9734b5ff9173b65a6524b8fc02b2a0d8ffce8db",
      "tree": "0f0aa85d032e48bb8c76cc31848846355d5fa305",
      "parents": [
        "6b85867813a69a3597a10967a16c7b80a8bc7c28"
      ],
      "author": {
        "name": "Xùdōng Yáng",
        "email": "wyverald@gmail.com",
        "time": "Fri Oct 30 19:11:15 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 19:11:15 2026 +0000"
      },
      "message": "fix: quote paths in stage1_bootstrap_template.sh (#4386)\n\nUnquoted path expansions in `stage1_bootstrap_template.sh` fail with\nword splitting when the executable symlink path, runfiles root\ndirectory, or `RULES_PYTHON_EXTRACT_ROOT` contains spaces (for example,\nin Bazel\u0027s `bazel_determinism_test`).\n\nQuote `$0`, `$stub_filename`, `$RUNFILES_DIR`, `$PYTHON_BINARY`,\n`$PYTHON_BINARY_ACTUAL`, `$RULES_PYTHON_EXTRACT_ROOT`, `$python_exe`,\nand `$venv_site_packages` when resolving runfiles and creating runtime\nvenvs, and extend the bootstrap runfiles and runtime venv tests to\nexercise paths with spaces."
    },
    {
      "commit": "6b85867813a69a3597a10967a16c7b80a8bc7c28",
      "tree": "f0958389a94c2c7a06326059431a26bf5a3279c8",
      "parents": [
        "674ce0745dea93e54865d9cfb846510b30475969"
      ],
      "author": {
        "name": "Tyler Yankee",
        "email": "tyler.yankee@kitware.com",
        "time": "Fri Oct 30 15:25:07 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 15:25:07 2026 +0000"
      },
      "message": "fix: tolerate absolute interpreter paths for lock update (#4384)\n\nSince #4029, the `lock` macro defaults the `directory` to the package\nname, and attempts to resolve the path to the Python interpreter via\nrelative path after `uv` changes into that directory. This is fine for\nhermetic Python, but it doesn\u0027t respect the case that `interpreter_path`\nis absolute.\n\nIf we have an absolute path to an interpreter, it doesn\u0027t need to\ninvolve `--directory`, so avoid the prefix altogether."
    },
    {
      "commit": "674ce0745dea93e54865d9cfb846510b30475969",
      "tree": "867ce1831a733b8724ab36d7e4a61f74e8d75b98",
      "parents": [
        "9699f18468276ce80fdb3c4e0125dd0c08fdbd65"
      ],
      "author": {
        "name": "Spencer Putt",
        "email": "sputt@alumni.iu.edu",
        "time": "Fri Oct 30 08:27:39 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 08:27:39 2026 +0000"
      },
      "message": "fix: don\u0027t materialize rules_python when reading the artifacts manifest (#4370)\n\nThe `config` extension reads `artifacts_manifest.json` with\n`mctx.read(Label(...))`, so with\n`--experimental_remote_repo_contents_cache` every consumer still\nmaterializes the whole `@rules_python` repo. This is the remaining gap\nafter #4294.\n\nFollowing #4294, the manifest becomes\n`python/private/artifacts_manifest.bzl`, whose `ARTIFACTS_MANIFEST_JSON`\nstring the extension loads. It stays empty in git, so source checkouts\nbuild the tools from source. The release generator now writes this\n`.bzl` file, and the archive script bundles it in place of the empty\none. `configure_tool_toolchains` no longer needs `module_ctx`, and tests\npass their manifest JSON directly.\n\n---------\n\nCo-authored-by: Spencer Putt \u003csputt@sputt-macbook-pro.local\u003e"
    },
    {
      "commit": "9699f18468276ce80fdb3c4e0125dd0c08fdbd65",
      "tree": "bd90d47b77b7fa4a9d49c577c9e3b50b94e256fb",
      "parents": [
        "d9909181be32b46f65e3a3ccca43b7dca6507224"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Oct 30 07:33:29 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 07:33:29 2026 +0000"
      },
      "message": "feat(uv): add @uv//:uv and //python/uv/bin:uv targets to run uv (#4371)\n\nUsers could not run the Bazel-configured `uv` binary directly because\n`//python/uv:current_toolchain` had restricted visibility and omitted\nthe underlying `uv` binary from its runfiles and executable symlink\nflag.\n\nMake `//python/uv:current_toolchain` public, mark its symlink executable\nwhile preserving any file extension (such as `.exe` on Windows),\ninclude the underlying `uv` binary in its runfiles, and expose the\n`$(UV)` Make variable alongside `$(UV_BIN)`. Expose convenient public\naliases at `@uv//:uv` and `//python/uv/bin:uv` so users can invoke `uv`\ndirectly via `bazel run`."
    },
    {
      "commit": "d9909181be32b46f65e3a3ccca43b7dca6507224",
      "tree": "7c9b0da6453adbdb5dcd3a1c1b4dcba10f370829",
      "parents": [
        "bfbcc014dd0be8763c467040eebd19baf926735b"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Fri Oct 30 05:34:13 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 05:34:13 2026 +0000"
      },
      "message": "build(deps-dev): Bump pylint from 2.17.7 to 4.0.9 in /examples/bzlmod (#4383)\n\nBumps [pylint](https://github.com/pylint-dev/pylint) from 2.17.7 to\n4.0.9\nin /examples/bzlmod and replaces `pylint-print` with\n`pylint-per-file-ignores`.\n\n`pylint-print 1.0.1` is incompatible with Pylint 4.0+ due to the removal\nof `IAstroidChecker` from `pylint.interfaces`. Replace it with\n`pylint-per-file-ignores` in `examples/bzlmod` to demonstrate plugin\nloading via `py_console_script_binary(deps \u003d [...])`, and update\n`entry_points` tests and documentation accordingly.\n\nFixes Dependabot alert 942:\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/942\n\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/releases\"\u003epylint\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.0.9\u003c/h2\u003e\n\u003ch2\u003eWhat\u0027s new in Pylint 4.0.9?\u003c/h2\u003e\n\u003cp\u003eRelease date: 2026-09-23\u003c/p\u003e\n\u003ch2\u003eSecurity Fixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSomeone without access to the configuration or linted code, but with\naccess\nto the cache directory (predictable \u003ccode\u003ePYLINT_HOME\u003c/code\u003e on a\nmulti-user host) can no\nlonger write a crafted pickle that will runs arbitrary code when pylint\naccess its\nstat cache. The result cache is now stored as JSON instead of pickle,\npreventing code-execution. The workaround is upgrading or not pointing\n\u003ccode\u003ePYLINT_HOME\u003c/code\u003e\nto an untrusted, shared, or group-writable directory. The default value,\n\u003ccode\u003e~/.cache/pylint\u003c/code\u003e,\nis writable only by the user running pylint. (CVE with the same\ninformation pending)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eFalse Positives Fixed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFixed a false positive for \u003ccode\u003eno-self-use\u003c/code\u003e on a method that\nonly uses\n\u003ccode\u003eself\u003c/code\u003e before a locally defined class (or other nested\nmethod), because\nthe checker\u0027s could-be-a-function tracking state was not restored after\nvisiting the nested method.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/3705\"\u003e#3705\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003enot-callable\u003c/code\u003e when calling\nfunctions constructed with\n\u003ccode\u003etypes.FunctionType\u003c/code\u003e or \u003ccode\u003etypes.LambdaType\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7500\"\u003e#7500\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eunnecessary-direct-lambda-call\u003c/code\u003e\nwhen a directly called\nlambda in a class body wraps a comprehension containing an assignment\nexpression.\nPEP 572 makes that a \u003ccode\u003eSyntaxError\u003c/code\u003e without the lambda\u0027s\nscope, so following the\nmessage produced code that would not compile.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9294\"\u003e#9294\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003eunnecessary-ellipsis\u003c/code\u003e when\nan ellipsis is the\nsole body statement of a method defined on a \u003ccode\u003eProtocol\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9319\"\u003e#9319\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003ebad-exception-cause\u003c/code\u003e when\nthe bases of the class\nbeing raised from cannot be inferred, such as an exception deriving from\na\nC extension class. :ref:\u003ccode\u003eraising-non-exception\u003c/code\u003e and\n:ref:\u003ccode\u003ecatching-non-exception\u003c/code\u003e already guard the same\n\u003ccode\u003einherit_from_std_ex\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/303703fe107fa812c42a66edfc88a5702a63f1f1\"\u003e\u003ccode\u003e303703f\u003c/code\u003e\u003c/a\u003e\nBump pylint to 4.0.9, update changelog (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11448\"\u003e#11448\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/b342384e6cb10986f3fa66093d99464b3ced4199\"\u003e\u003ccode\u003eb342384\u003c/code\u003e\u003c/a\u003e\nFix block-scoped disable leaking into sibling elif/else blocks (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11429\"\u003e#11429\u003c/a\u003e)\n(\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11445\"\u003e#11445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/58c87cffca9de2b3e89aa07b89686cbc90cfea2d\"\u003e\u003ccode\u003e58c87cf\u003c/code\u003e\u003c/a\u003e\nStore the results cache as JSON instead of pickle\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e3f4942a2ff51d28b69435587eee53ab44ebfb9c\"\u003e\u003ccode\u003ee3f4942\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix crash on failed attribute inference (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11443\"\u003e#11443\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/faf47f9f079c9461832a7bd7dcea61d44f6348b9\"\u003e\u003ccode\u003efaf47f9\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix false positive no-self-use when a\nmethod con...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/20c7bb9ef1468b38e61de43d2e3a7314f938e04f\"\u003e\u003ccode\u003e20c7bb9\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix a crash in method-hidden for methods\nnamed a...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/47e67578bef317ff0feb0211ba84ba3ba958645f\"\u003e\u003ccode\u003e47e6757\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix bad-exception-cause false positive when\nthe ...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/ae3ee5354062ca35c0d243f673a2bf3ee2e4f376\"\u003e\u003ccode\u003eae3ee53\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix not-callable false positive for\ntypes.Functi...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/3e444be6ef29e675f2f559960a60ee24a0372687\"\u003e\u003ccode\u003e3e444be\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix a crash in\nunnecessary-default-type-args for...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/8f2dd4fcaa85fa43b33da6b0fed4af3a22314984\"\u003e\u003ccode\u003e8f2dd4f\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix declare-non-slot false positives for\nClassVa...\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/compare/v2.17.7...v4.0.9\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003dpylint\u0026package-manager\u003duv\u0026previous-version\u003d2.17.7\u0026new-version\u003d4.0.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts\npage](https://github.com/bazel-contrib/rules_python/network/alerts).\n\n\u003c/details\u003e\n\n---------\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "bfbcc014dd0be8763c467040eebd19baf926735b",
      "tree": "9729f6721999fb9900837fc1962679c73bce7d90",
      "parents": [
        "702931a9354bd08d53174bb1b40621a036a9346b"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Oct 29 20:28:14 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 29 20:28:14 2026 -0700"
      },
      "message": "fix(toolchains): include libpython in python_repository attrs (#4382)\n\n`_python_repository_impl` omitted `libpython` from its returned\nreproducibility `attrs` dict, causing Bazel \u003c 8.3.0 and non-`sha256`\ninvocations to emit a spurious `DEBUG` warning about dropping\n`[\"libpython\"]`.\n\nInclude `libpython` in `attrs` so Bazel preserves the attribute\nwithout warning."
    },
    {
      "commit": "702931a9354bd08d53174bb1b40621a036a9346b",
      "tree": "a93916126dfaf0e80bd37ebc0ec97ea519a179a9",
      "parents": [
        "8e399d7493d0d2df2ec71b84b84715726e741522"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Fri Oct 30 01:07:18 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 30 01:07:18 2026 +0000"
      },
      "message": "build(deps): bump urllib3 in dev uv.lock files (#4381)\n\nBump urllib3 from 2.7.0 to 2.8.0 in dev/uv.lock and\nsphinxdocs/dev/uv.lock. These locks pinned vulnerable versions flagged\nby Dependabot.\n\nRelock dev/uv.lock and sphinxdocs/dev/uv.lock with\n`uv lock --upgrade-package urllib3`, leaving other pins intact.\n\nFixes Dependabot alerts 839, 840, 841, 897, 898, and 899:\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/839\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/840\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/841\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/897\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/898\nhttps://github.com/bazel-contrib/rules_python/security/dependabot/899"
    },
    {
      "commit": "8e399d7493d0d2df2ec71b84b84715726e741522",
      "tree": "dac56376fd31c0f661cc7906b27a7108b2f915ce",
      "parents": [
        "9b2cc3a64318021e24e89895e0b52c86d3a640e1"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Oct 29 12:42:49 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 29 12:42:49 2026 +0000"
      },
      "message": "fix(bzlmod): support Python versions not in MINOR_MAPPING (#4366)\n\nConfiguring a Python patch version newer than the built-in\n`MINOR_MAPPING` failed in the `python` and `pip` Bzlmod extensions.\nManifest files loaded via `add_runtime_manifest_files` omitted the\nrelease tag from default download URLs, `single_version_override` did\nnot require `sha256` and `urls` when introducing a new version, and\n`pip.parse` failed to match host interpreters when toolchain and pip\nversion granularities differed (such as `X.Y` vs. `X.Y.Z` or versions\ninferred from `pyproject.toml`).\n\nUpdate the `python` extension to include the release build version in\ndefault manifest URLs, require `sha256` and `urls` for new\nsingle-version overrides, and verify requested toolchains exist in\n`tool_versions`. Update `pip.parse` to resolve host interpreters across\nexact, full, and `major.minor` version names and key index URL settings\nby the resolved Python version.\n\nFixes #4358"
    },
    {
      "commit": "9b2cc3a64318021e24e89895e0b52c86d3a640e1",
      "tree": "07f7c5deb744d8c123f2bbb67be778b9e59f226e",
      "parents": [
        "6f58700dcc08db67c8208f7a074bd9733f1d1e53"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Thu Oct 29 09:09:59 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 29 09:09:59 2026 +0000"
      },
      "message": "chore(release): sync changelog for v2.4.6 backports (#4380)\n\nUpdates CHANGELOG.md and removes news files for backports:\n- #4369\n\nWork towards #4373\nRelease-Tracking-Issue: #4373\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "6f58700dcc08db67c8208f7a074bd9733f1d1e53",
      "tree": "c0d9fb8db41eb2f5442be1e262a29059380cbc53",
      "parents": [
        "632be0cfae49d97ceee1c5edd5b3dd72f6e0ce5e"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Thu Oct 29 03:21:47 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 29 03:21:47 2026 +0000"
      },
      "message": "feat(toolchains): update Python toolchains to latest patch releases (#4369)\n\nRecent Python patch releases address compromised eMudhra intermediate\nCA keys in the bundled CA bundle and provide the Python 3.15 GA and\npatch releases. Without these updates, default toolchains use older\npatch releases and pre-release 3.15 builds.\n\nAdd the `20261009` and `20261026` `python-build-standalone` runtime\nreleases, remove pre-release `3.15.0` entries, and update default\nminor version mappings to `3.10.22`, `3.11.18`, `3.12.16`, `3.13.18`,\n`3.14.10`, and `3.15.2`.\n\nFixes https://github.com/bazel-contrib/rules_python/issues/4358"
    },
    {
      "commit": "632be0cfae49d97ceee1c5edd5b3dd72f6e0ce5e",
      "tree": "1e406c486516527b733ac14ccd9ecccdfb32b389",
      "parents": [
        "05916c1776059ef0ab0edc1cdba84975d7f379e2"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Oct 29 03:19:40 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 29 03:19:40 2026 +0000"
      },
      "message": "build(deps-user): Bump the \"user-facing\" group with 1 update across multiple ecosystems (#4378)\n\nBumps the user-facing group with 2 updates in the /tools directory:\n[certifi](https://github.com/certifi/python-certifi) and\n[importlib-metadata](https://github.com/python/importlib_metadata).\nBumps the user-facing group with 2 updates in the /tools/publish\ndirectory: [certifi](https://github.com/certifi/python-certifi) and\n[importlib-metadata](https://github.com/python/importlib_metadata).\n\nUpdates `certifi` from 2026.10.19 to 2026.10.23\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/commit/b60466c9f2882d9cf088943c650b0faac06c080c\"\u003e\u003ccode\u003eb60466c\u003c/code\u003e\u003c/a\u003e\n2026.10.23 (\u003ca\nhref\u003d\"https://redirect.github.com/certifi/python-certifi/issues/445\"\u003e#445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/compare/2026.10.19...2026.10.23\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `importlib-metadata` from 9.0.1 to 10.1.0\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/blob/main/NEWS.rst\"\u003eimportlib-metadata\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch1\u003ev10.1.0\u003c/h1\u003e\n\u003ch2\u003eFeatures\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDetecting whether a distribution supplies metadata no longer reads\nor parses\nthat metadata where the metadata directory can be inspected instead, so\nretrieving a distribution by name, which prefers the valid candidates,\nis\nsubstantially faster.\u003c/li\u003e\n\u003cli\u003eReverted the preference for the greater metadata directory added in\nv9.1.0.\nThe ordering was lexicographic on the directory name and not on the\nparsed\nversion, so it only approximated a preference for the newer version.\nWhere a\npath supplies more than one metadata directory for a distribution,\ndiscovery\nonce again reports them in the order the path supplies\n\u003ccode\u003epython/cpython#100666\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eBugfixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eentry_points()\u003c/code\u003e now prefers distributions whose metadata\nis readable, so\nan empty metadata directory left behind by an unclean upgrade no longer\nshadows the valid one of the same name and suppresses its entry points.\nInvalid distributions are deferred to the end of the enumeration rather\nthan\ndropped. (\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/534\"\u003e#534\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eThe preference for valid distributions no longer propagates the\n\u003ccode\u003eMetadataNotFound\u003c/code\u003e of a distribution that a provider derived\nfrom\n\u003ccode\u003eimportlib.metadata\u003c/code\u003e, whose exception is a different class\nfrom this\npackage\u0027s and so escaped the preference rather than marking the\ndistribution\ninvalid.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1\u003ev10.0.0\u003c/h1\u003e\n\u003ch2\u003eFeatures\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eAdded \u003ccode\u003eIDistribution\u003c/code\u003e and \u003ccode\u003eIPackagePath\u003c/code\u003e\nprotocols so consumers can target a stable, shared interface across\n\u003ccode\u003eimportlib.metadata\u003c/code\u003e and \u003ccode\u003eimportlib_metadata\u003c/code\u003e. A\nprovider supplying its own \u003ccode\u003eDistribution\u003c/code\u003e subclass is warned\nabout only when the class omits members that interface requires, not\nmerely because it derives from \u003ccode\u003eimportlib.metadata\u003c/code\u003e.\n\u003ccode\u003eorigin\u003c/code\u003e is exempt from that expectation until support for\nPython 3.12 is dropped, as there is none to inherit before Python 3.13.\n(\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/486\"\u003e#486\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eDeprecations and Removals\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eWhen providers supply objects from \u003ccode\u003eimportlib.metadata\u003c/code\u003e,\nthey are now adapted to the classes from\n\u003ccode\u003eimportlib_metadata\u003c/code\u003e. (\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/486\"\u003e#486\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1\u003ev9.1.0\u003c/h1\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/d196fdbd3ebf90542b51f7215c230c17ef376cb0\"\u003e\u003ccode\u003ed196fdb\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/5d253aecaafb2fe88f2c0f6ff9d579fa95b24f09\"\u003e\u003ccode\u003e5d253ae\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/553\"\u003e#553\u003c/a\u003e\nfrom python/bugfix/534-entry-points-prefer-valid\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/0aa24f3392439c552a89fbd7fcc3cdc20d8f0105\"\u003e\u003ccode\u003e0aa24f3\u003c/code\u003e\u003c/a\u003e\nPrefer valid distributions when collecting entry points.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/e52be782b23218fff2dff7024654fae2d4410801\"\u003e\u003ccode\u003ee52be78\u003c/code\u003e\u003c/a\u003e\nDetect the presence of metadata without reading it.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/60bbaca797424d8234a703f0b076a12592079883\"\u003e\u003ccode\u003e60bbaca\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/552\"\u003e#552\u003c/a\u003e\nfrom python/debt/revert-prefer-greater-version\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/7e162d8a86815484cc26291e39052be5fbcf7514\"\u003e\u003ccode\u003e7e162d8\u003c/code\u003e\u003c/a\u003e\nRevert \u0026quot;Prefer the greater metadata directory when a path supplies\nseveral.\u0026quot;\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/3be14168f846b406b0f3a48bb1907fe70c5fb7c8\"\u003e\u003ccode\u003e3be1416\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/e3dad222d3ed33f6b68306eb92e537e2bfc83690\"\u003e\u003ccode\u003ee3dad22\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/505\"\u003e#505\u003c/a\u003e\nfrom python/bugfix/486-local-objects\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/301b791a4b4281dd5100eb26fa53466e75b28fe5\"\u003e\u003ccode\u003e301b791\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/4b7c45f3d1a5ad3fed28bf52db377770b754ef4f\"\u003e\u003ccode\u003e4b7c45f\u003c/code\u003e\u003c/a\u003e\nAvoid a dot in the news fragment id.\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/compare/v9.0.1...v10.1.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `certifi` from 2026.10.19 to 2026.10.23\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/commit/b60466c9f2882d9cf088943c650b0faac06c080c\"\u003e\u003ccode\u003eb60466c\u003c/code\u003e\u003c/a\u003e\n2026.10.23 (\u003ca\nhref\u003d\"https://redirect.github.com/certifi/python-certifi/issues/445\"\u003e#445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/compare/2026.10.19...2026.10.23\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\nUpdates `importlib-metadata` from 9.0.1 to 10.1.0\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/blob/main/NEWS.rst\"\u003eimportlib-metadata\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch1\u003ev10.1.0\u003c/h1\u003e\n\u003ch2\u003eFeatures\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDetecting whether a distribution supplies metadata no longer reads\nor parses\nthat metadata where the metadata directory can be inspected instead, so\nretrieving a distribution by name, which prefers the valid candidates,\nis\nsubstantially faster.\u003c/li\u003e\n\u003cli\u003eReverted the preference for the greater metadata directory added in\nv9.1.0.\nThe ordering was lexicographic on the directory name and not on the\nparsed\nversion, so it only approximated a preference for the newer version.\nWhere a\npath supplies more than one metadata directory for a distribution,\ndiscovery\nonce again reports them in the order the path supplies\n\u003ccode\u003epython/cpython#100666\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eBugfixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eentry_points()\u003c/code\u003e now prefers distributions whose metadata\nis readable, so\nan empty metadata directory left behind by an unclean upgrade no longer\nshadows the valid one of the same name and suppresses its entry points.\nInvalid distributions are deferred to the end of the enumeration rather\nthan\ndropped. (\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/534\"\u003e#534\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eThe preference for valid distributions no longer propagates the\n\u003ccode\u003eMetadataNotFound\u003c/code\u003e of a distribution that a provider derived\nfrom\n\u003ccode\u003eimportlib.metadata\u003c/code\u003e, whose exception is a different class\nfrom this\npackage\u0027s and so escaped the preference rather than marking the\ndistribution\ninvalid.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1\u003ev10.0.0\u003c/h1\u003e\n\u003ch2\u003eFeatures\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eAdded \u003ccode\u003eIDistribution\u003c/code\u003e and \u003ccode\u003eIPackagePath\u003c/code\u003e\nprotocols so consumers can target a stable, shared interface across\n\u003ccode\u003eimportlib.metadata\u003c/code\u003e and \u003ccode\u003eimportlib_metadata\u003c/code\u003e. A\nprovider supplying its own \u003ccode\u003eDistribution\u003c/code\u003e subclass is warned\nabout only when the class omits members that interface requires, not\nmerely because it derives from \u003ccode\u003eimportlib.metadata\u003c/code\u003e.\n\u003ccode\u003eorigin\u003c/code\u003e is exempt from that expectation until support for\nPython 3.12 is dropped, as there is none to inherit before Python 3.13.\n(\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/486\"\u003e#486\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eDeprecations and Removals\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eWhen providers supply objects from \u003ccode\u003eimportlib.metadata\u003c/code\u003e,\nthey are now adapted to the classes from\n\u003ccode\u003eimportlib_metadata\u003c/code\u003e. (\u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/486\"\u003e#486\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1\u003ev9.1.0\u003c/h1\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/d196fdbd3ebf90542b51f7215c230c17ef376cb0\"\u003e\u003ccode\u003ed196fdb\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/5d253aecaafb2fe88f2c0f6ff9d579fa95b24f09\"\u003e\u003ccode\u003e5d253ae\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/553\"\u003e#553\u003c/a\u003e\nfrom python/bugfix/534-entry-points-prefer-valid\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/0aa24f3392439c552a89fbd7fcc3cdc20d8f0105\"\u003e\u003ccode\u003e0aa24f3\u003c/code\u003e\u003c/a\u003e\nPrefer valid distributions when collecting entry points.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/e52be782b23218fff2dff7024654fae2d4410801\"\u003e\u003ccode\u003ee52be78\u003c/code\u003e\u003c/a\u003e\nDetect the presence of metadata without reading it.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/60bbaca797424d8234a703f0b076a12592079883\"\u003e\u003ccode\u003e60bbaca\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/552\"\u003e#552\u003c/a\u003e\nfrom python/debt/revert-prefer-greater-version\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/7e162d8a86815484cc26291e39052be5fbcf7514\"\u003e\u003ccode\u003e7e162d8\u003c/code\u003e\u003c/a\u003e\nRevert \u0026quot;Prefer the greater metadata directory when a path supplies\nseveral.\u0026quot;\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/3be14168f846b406b0f3a48bb1907fe70c5fb7c8\"\u003e\u003ccode\u003e3be1416\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/e3dad222d3ed33f6b68306eb92e537e2bfc83690\"\u003e\u003ccode\u003ee3dad22\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/python/importlib_metadata/issues/505\"\u003e#505\u003c/a\u003e\nfrom python/bugfix/486-local-objects\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/301b791a4b4281dd5100eb26fa53466e75b28fe5\"\u003e\u003ccode\u003e301b791\u003c/code\u003e\u003c/a\u003e\nFinalize\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/commit/4b7c45f3d1a5ad3fed28bf52db377770b754ef4f\"\u003e\u003ccode\u003e4b7c45f\u003c/code\u003e\u003c/a\u003e\nAvoid a dot in the news fragment id.\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/python/importlib_metadata/compare/v9.0.1...v10.1.0\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore \u003cdependency name\u003e major version` will close this\ngroup update PR and stop Dependabot creating any more for the specific\ndependency\u0027s major version (unless you unignore this specific\ndependency\u0027s major version or upgrade to it yourself)\n- `@dependabot ignore \u003cdependency name\u003e minor version` will close this\ngroup update PR and stop Dependabot creating any more for the specific\ndependency\u0027s minor version (unless you unignore this specific\ndependency\u0027s minor version or upgrade to it yourself)\n- `@dependabot ignore \u003cdependency name\u003e` will close this group update PR\nand stop Dependabot creating any more for the specific dependency\n(unless you unignore this specific dependency or upgrade to it yourself)\n- `@dependabot unignore \u003cdependency name\u003e` will remove all of the ignore\nconditions of the specified dependency\n- `@dependabot unignore \u003cdependency name\u003e \u003cignore condition\u003e` will\nremove the ignore condition of the specified dependency and ignore\nconditions\n\n\n\u003c/details\u003e\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "05916c1776059ef0ab0edc1cdba84975d7f379e2",
      "tree": "e8b7cb1162a191ec0c4bb76749414448af06733d",
      "parents": [
        "03961e106b810765c447f604cfddc79660a80ea4"
      ],
      "author": {
        "name": "Finn Ball",
        "email": "finn.ball@codificasolutions.com",
        "time": "Wed Oct 28 12:01:25 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 12:01:25 2026 +0000"
      },
      "message": "fix: preserve venv symlink setting in exec config (#4372)\n\nBazel 10 excludes target-scoped Starlark settings from exec\nconfigurations, so an explicit `venvs_use_declare_symlink\u003dno` can reset\nto `yes` for Python executables built as tools. Give the flag universal\nscope to preserve the selected value across exec transitions."
    },
    {
      "commit": "03961e106b810765c447f604cfddc79660a80ea4",
      "tree": "a3d23c8fd5197b8d49c408496d0aad0217891f06",
      "parents": [
        "2cf345fc1bcad3fe7d602876c374d9794c005e83"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed Oct 28 00:09:09 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 28 00:09:09 2026 +0000"
      },
      "message": "build(deps-dev): Bump pylint from 2.15.10 to 4.0.9 in /gazelle/examples/bzlmod_build_file_generation (#4368)\n\nBumps [pylint](https://github.com/pylint-dev/pylint) from 2.15.10 to\n4.0.9.\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/releases\"\u003epylint\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.0.9\u003c/h2\u003e\n\u003ch2\u003eWhat\u0027s new in Pylint 4.0.9?\u003c/h2\u003e\n\u003cp\u003eRelease date: 2026-09-23\u003c/p\u003e\n\u003ch2\u003eSecurity Fixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSomeone without access to the configuration or linted code, but with\naccess\nto the cache directory (predictable \u003ccode\u003ePYLINT_HOME\u003c/code\u003e on a\nmulti-user host) can no\nlonger write a crafted pickle that will runs arbitrary code when pylint\naccess its\nstat cache. The result cache is now stored as JSON instead of pickle,\npreventing code-execution. The workaround is upgrading or not pointing\n\u003ccode\u003ePYLINT_HOME\u003c/code\u003e\nto an untrusted, shared, or group-writable directory. The default value,\n\u003ccode\u003e~/.cache/pylint\u003c/code\u003e,\nis writable only by the user running pylint. (CVE with the same\ninformation pending)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eFalse Positives Fixed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFixed a false positive for \u003ccode\u003eno-self-use\u003c/code\u003e on a method that\nonly uses\n\u003ccode\u003eself\u003c/code\u003e before a locally defined class (or other nested\nmethod), because\nthe checker\u0027s could-be-a-function tracking state was not restored after\nvisiting the nested method.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/3705\"\u003e#3705\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003enot-callable\u003c/code\u003e when calling\nfunctions constructed with\n\u003ccode\u003etypes.FunctionType\u003c/code\u003e or \u003ccode\u003etypes.LambdaType\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/7500\"\u003e#7500\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for \u003ccode\u003eunnecessary-direct-lambda-call\u003c/code\u003e\nwhen a directly called\nlambda in a class body wraps a comprehension containing an assignment\nexpression.\nPEP 572 makes that a \u003ccode\u003eSyntaxError\u003c/code\u003e without the lambda\u0027s\nscope, so following the\nmessage produced code that would not compile.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9294\"\u003e#9294\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003eunnecessary-ellipsis\u003c/code\u003e when\nan ellipsis is the\nsole body statement of a method defined on a \u003ccode\u003eProtocol\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eCloses \u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/9319\"\u003e#9319\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFix a false positive for :ref:\u003ccode\u003ebad-exception-cause\u003c/code\u003e when\nthe bases of the class\nbeing raised from cannot be inferred, such as an exception deriving from\na\nC extension class. :ref:\u003ccode\u003eraising-non-exception\u003c/code\u003e and\n:ref:\u003ccode\u003ecatching-non-exception\u003c/code\u003e already guard the same\n\u003ccode\u003einherit_from_std_ex\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/303703fe107fa812c42a66edfc88a5702a63f1f1\"\u003e\u003ccode\u003e303703f\u003c/code\u003e\u003c/a\u003e\nBump pylint to 4.0.9, update changelog (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11448\"\u003e#11448\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/b342384e6cb10986f3fa66093d99464b3ced4199\"\u003e\u003ccode\u003eb342384\u003c/code\u003e\u003c/a\u003e\nFix block-scoped disable leaking into sibling elif/else blocks (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11429\"\u003e#11429\u003c/a\u003e)\n(\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11445\"\u003e#11445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/58c87cffca9de2b3e89aa07b89686cbc90cfea2d\"\u003e\u003ccode\u003e58c87cf\u003c/code\u003e\u003c/a\u003e\nStore the results cache as JSON instead of pickle\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/e3f4942a2ff51d28b69435587eee53ab44ebfb9c\"\u003e\u003ccode\u003ee3f4942\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix crash on failed attribute inference (\u003ca\nhref\u003d\"https://redirect.github.com/pylint-dev/pylint/issues/11443\"\u003e#11443\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/faf47f9f079c9461832a7bd7dcea61d44f6348b9\"\u003e\u003ccode\u003efaf47f9\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix false positive no-self-use when a\nmethod con...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/20c7bb9ef1468b38e61de43d2e3a7314f938e04f\"\u003e\u003ccode\u003e20c7bb9\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix a crash in method-hidden for methods\nnamed a...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/47e67578bef317ff0feb0211ba84ba3ba958645f\"\u003e\u003ccode\u003e47e6757\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix bad-exception-cause false positive when\nthe ...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/ae3ee5354062ca35c0d243f673a2bf3ee2e4f376\"\u003e\u003ccode\u003eae3ee53\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix not-callable false positive for\ntypes.Functi...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/3e444be6ef29e675f2f559960a60ee24a0372687\"\u003e\u003ccode\u003e3e444be\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix a crash in\nunnecessary-default-type-args for...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/commit/8f2dd4fcaa85fa43b33da6b0fed4af3a22314984\"\u003e\u003ccode\u003e8f2dd4f\u003c/code\u003e\u003c/a\u003e\n[Backport maintenance/4.0.x] Fix declare-non-slot false positives for\nClassVa...\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/pylint-dev/pylint/compare/v2.15.10...v4.0.9\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003dpylint\u0026package-manager\u003duv\u0026previous-version\u003d2.15.10\u0026new-version\u003d4.0.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts\npage](https://github.com/bazel-contrib/rules_python/network/alerts).\n\n\u003c/details\u003e\n\n---------\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Richard Levasseur \u003crichardlev@gmail.com\u003e"
    },
    {
      "commit": "2cf345fc1bcad3fe7d602876c374d9794c005e83",
      "tree": "438a12c566385d876571ac450efa2ae095061663",
      "parents": [
        "8ca9a778ab3b1765fbeb4e9bbb75d3173c34df79"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Oct 27 23:32:56 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 23:32:56 2026 +0000"
      },
      "message": "build(deps-dev): Bump certifi from 2026.10.19 to 2026.10.23 in /gazelle/examples/bzlmod_build_file_generation (#4367)\n\nBumps [certifi](https://github.com/certifi/python-certifi) from\n2026.10.19 to 2026.10.23.\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/commit/b60466c9f2882d9cf088943c650b0faac06c080c\"\u003e\u003ccode\u003eb60466c\u003c/code\u003e\u003c/a\u003e\n2026.10.23 (\u003ca\nhref\u003d\"https://redirect.github.com/certifi/python-certifi/issues/445\"\u003e#445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/compare/2026.10.19...2026.10.23\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003dcertifi\u0026package-manager\u003duv\u0026previous-version\u003d2026.10.19\u0026new-version\u003d2026.10.23)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts\npage](https://github.com/bazel-contrib/rules_python/network/alerts).\n\n\u003c/details\u003e\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "8ca9a778ab3b1765fbeb4e9bbb75d3173c34df79",
      "tree": "fc73d94ce3ec3edfdbb204a16b96835ebe7d035d",
      "parents": [
        "21d36f3fc072a0d0be49cdabcfc9d530141c025a"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Oct 27 18:22:02 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 18:22:02 2026 +0000"
      },
      "message": "refactor(examples): migrate remaining lockfiles to uv lock() (#4365)\n\nNow that the `uv` `lock()` macro supports `WORKSPACE` builds, remaining\nnon-dedicated `compile_pip_requirements` targets and `pip-compile`\nlockfiles can use `uv` instead.\n\nMigrate `tests/multiple_inputs` to `lock()` with `diff_test`, register\n`uv` toolchains in the example `WORKSPACE` and `MODULE.bazel` files, and\nregenerate the example `requirements*.txt` files with `uv`."
    },
    {
      "commit": "21d36f3fc072a0d0be49cdabcfc9d530141c025a",
      "tree": "250b2addedaf8709139db06f865740d701029b98",
      "parents": [
        "44eb677dce5ff532e11a5181afafc913fcd8f34c"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 23:39:42 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 23:39:42 2026 -0700"
      },
      "message": "agents: refine Starlark data serialization, docstring, and WORKSPACE rules (#4364)\n\nCapture review feedback from #4360 in the workspace agent rules so\nfuture Starlark and WORKSPACE implementations follow the same patterns:\n\n- Direct repository rules to serialize JSON-compatible data constants in\n  generated `.bzl` files with `json.encode_indent()` instead of custom\n  `render.*` helpers.\n- Keep `.bzl` API docstrings brief and place multi-scenario examples and\n  setup guides in narrative `docs/` pages linked via `{ref}` or `{obj}`.\n- Require `WORKSPACE` macros to match Bzlmod extension defaults, tag\n  schemas, and single-hub multi-version structure, splitting manifest\n  downloads into a manifest repo rule and a bound registration macro."
    },
    {
      "commit": "44eb677dce5ff532e11a5181afafc913fcd8f34c",
      "tree": "5e04ca29ec5662d846ae232d3a841f213a2318a0",
      "parents": [
        "6d04d7bddfd68f429984997446838e17726cc86b"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Oct 27 05:21:35 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 05:21:35 2026 +0000"
      },
      "message": "feat(uv): support WORKSPACE builds in the lock() macro (#4360)\n\nThis makes the uv `lock()` rule work in workspace mode. Since we\u0027ll\nbe supporting Bazel 8 for another year, and I\u0027d really like to get\nrid of the remaining requirements.txt and compile_pip_requirements\ncalls, I figured we should just implement workspace support for it.\n\nThis is a fairly low-effort conversion of the bzlmod APIs to\nworkspace mode. Fundamentally, the bzlmod API works by obtaining\none or more manifests, then using the manifest information to\ndefine repos with the uv binaries. Then the names of all those\nrepos are fed into the toolchain hub where the `toolchain()`\nregistrations are.\n\nThe workspace API more-or-less exposes that same API.\n\nThe `uv_toolchain_manifest()` function is the equivalent of the\nfirst half of the bzlmod phase. All it does is download the\nmanifests so they can be read by subsequent workspace macros\nand repos. Like the bzlmod API, a manifest per uv version can\nbe registered.\n\nThe `uv_register_toolchains()` function is the equivalent of the\nsecond half of the bzlmod phase. It takes what\u0027s in the manifest\nand defines repos pointing to a particular URL. Like the bzlmod\nAPI, it accepts args to customize processing. This function also\nkeeps track of all the created toolchain implementations and\ncreates the toolchain hub with all the `toolchain()` registrations.\n\nThe args to the functions mirror the bzlmod API, which is basically\na list of key-values. Hence the `uv_register_toolchains.configure`\narg accepts a list of dicts, where the keys are the same as the\nattributes of the `uv.configure` tag class. This makes for a\nsomewhat awkward API, but it matches the bzlmod API and makes it\neasier to integrate into the underlying code.\n\nTested on Bazel 7.x and 8.x in WORKSPACE mode, and on Bazel 7.x, 8.x\nand 9.x in bzlmod mode (Bazel 9 no longer evaluates WORKSPACE).\n\nWork towards #1975"
    },
    {
      "commit": "6d04d7bddfd68f429984997446838e17726cc86b",
      "tree": "d4b9f509ec19e79046a1ffc09a134837c0c8b041",
      "parents": [
        "6a1f3f09a3dc4e10dd9418a0a8395f7fed83ca2d"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 22:15:15 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 22:15:15 2026 -0700"
      },
      "message": "agents: avoid complex inline expressions and refine workflow guardrails (#4363)\n\nComplex inline expressions and dense boolean chains in workflow\ndefinitions and code obscure intent, complicate debugging, and increase\nthe risk of logic bugs or improper input sanitization.\n\nUpdate agent code style rules to disfavor dense inline expressions and\ndense one-liners in favor of explicit statements and intermediate\nsteps. Refine workflow security guardrails to recommend dedicated\nref-sanitization steps, simplify failure-reporting job condition\npredicates, and clarify the rationale for using `printf` over\n`echo`."
    },
    {
      "commit": "6a1f3f09a3dc4e10dd9418a0a8395f7fed83ca2d",
      "tree": "fbfabd9faecb8964cfd9d30974bf9a6930bf047a",
      "parents": [
        "7f2238d0b409df6437abed4a94cbe020c9c6217b"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Oct 27 04:37:55 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 04:37:55 2026 +0000"
      },
      "message": "build(deps-dev): Bump certifi from 2026.10.19 to 2026.10.23 in /dev (#4362)\n\nBumps [certifi](https://github.com/certifi/python-certifi) from\n2026.10.19 to 2026.10.23.\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/commit/b60466c9f2882d9cf088943c650b0faac06c080c\"\u003e\u003ccode\u003eb60466c\u003c/code\u003e\u003c/a\u003e\n2026.10.23 (\u003ca\nhref\u003d\"https://redirect.github.com/certifi/python-certifi/issues/445\"\u003e#445\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/certifi/python-certifi/compare/2026.10.19...2026.10.23\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003dcertifi\u0026package-manager\u003duv\u0026previous-version\u003d2026.10.19\u0026new-version\u003d2026.10.23)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts\npage](https://github.com/bazel-contrib/rules_python/network/alerts).\n\n\u003c/details\u003e\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "7f2238d0b409df6437abed4a94cbe020c9c6217b",
      "tree": "cf353b290fd968fc4f593b0dcfd7c7f05374ea7e",
      "parents": [
        "5c11b69c8ee0fdb85ea444fc91e815378a349ee3"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 21:01:51 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 21:01:51 2026 -0700"
      },
      "message": "workflows: harden GitHub Actions YAML against injection (#4361)\n\nInterpolating GitHub Actions expressions directly into shell `run:`\nblocks, `actions/github-script` scripts, and `.bazelrc` configs risks\ncommand, script, or flag injection when inputs or refs contain shell\nmetacharacters, newlines, or leading hyphens.\n\nPass workflow inputs and context values through step-scoped `env:`\nvariables, sanitize branch names written to `.bazelrc`, use\n`printf \u0027%s\\n\u0027` instead of `echo`, and guard CLI arguments with\n`--flag\u003dvalue` or `--` separators. Also require `parse_comment` to\nsucceed before posting failure reactions on issue comments."
    },
    {
      "commit": "5c11b69c8ee0fdb85ea444fc91e815378a349ee3",
      "tree": "e5741d9ca13dfc14e1d79c4b588ee6ec7ee6a9dd",
      "parents": [
        "54cfbd86dac342b8eb87d8be196b336583eae253"
      ],
      "author": {
        "name": "Frank Portman",
        "email": "frank1214@gmail.com",
        "time": "Tue Oct 27 00:25:02 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 00:25:02 2026 +0000"
      },
      "message": "feat: add PyInfo.direct_implicit_pyc_files and PyExecutableInfo.venv_runfiles (#4341)\n\n`PyInfo` had a direct counterpart for every pyc field except the\nimplicit pyc files, and `PyExecutableInfo` exposed the venv\u0027s\ninterpreter runfiles but not the application\u0027s. Tools that only see\nproviders, like a packager\u0027s aspect, need both to tell a target\u0027s own\nfiles apart from what it inherits.\n\nAlso pulls a few internals out so they can be reused, with no change in\nbehavior: `py_info_runfiles_files()` for the files a binary takes from a\ndependency\u0027s PyInfo, `get_runtime_files()` for the runtime\u0027s files, and\n`get_package_and_version()` taking the data files instead of the ctx.\n\nSplit out of #4254, which uses all of these."
    },
    {
      "commit": "54cfbd86dac342b8eb87d8be196b336583eae253",
      "tree": "f9822d7a8a3a4a1ed13015e713c25ed501ede864",
      "parents": [
        "298490532b27f51e3f5f288ac3ef6c83b813fb03"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Tue Oct 27 00:24:12 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 00:24:12 2026 +0000"
      },
      "message": "docs(uv): document uv.lock support in locking and download docs (#4354)\n\n`rules_python` supports `uv.lock` in addition to `requirements.txt`,\nleaving documentation that states only `requirements.txt` is supported\noutdated.\n\nUpdate the locking and download guides and `lock` rule docstrings to\ndocument both `uv.lock` generation via `uv lock` and `requirements.txt`\ngeneration via `uv pip compile`."
    },
    {
      "commit": "298490532b27f51e3f5f288ac3ef6c83b813fb03",
      "tree": "d114656e7d414557189a9e58c23d20294f621160",
      "parents": [
        "9e587e8e0416f0b81143b9f6ff94547db49b05f6"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 16:17:31 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 16:17:31 2026 -0700"
      },
      "message": "agents: add GitHub Actions workflow security review rules (#4359)\n\nGitHub Actions workflows and scripts can introduce command, flag, and\nenvironment injection vulnerabilities when handling untrusted inputs\nfrom pull requests, comments, and git refs. Without explicit review\ncriteria, code review audits may overlook these attack vectors.\n\nAdd security review rules and audit checks covering expression\ninterpolation in `run:` and `script:` blocks, untrusted git ref names,\nCLI option-flag injection, pre-mutation actor authorization,\nsingle-line `$GITHUB_OUTPUT` and `$GITHUB_ENV` writes, and untrusted\nstdout suppression."
    },
    {
      "commit": "9e587e8e0416f0b81143b9f6ff94547db49b05f6",
      "tree": "5bba066b98ab57ee73d26baaba18400fd9a7ceee",
      "parents": [
        "0ff1fe19372837339c22ccb629cc48b512fe1135"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 13:16:08 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 13:16:08 2026 -0700"
      },
      "message": "agents: make @rickeylev sole code owner of agent configs (#4356)\n\nCurrently, `.github/CODEOWNERS` assigns `@rickeylev` and `@aignas` as\nthe default owners (`*`), which automatically requests review from\n`@aignas` on pull requests that only modify agent configurations.\n\nAssign `@rickeylev` as the sole code owner for agent configuration\npaths in `.github/CODEOWNERS` to avoid unnecessary review requests."
    },
    {
      "commit": "0ff1fe19372837339c22ccb629cc48b512fe1135",
      "tree": "f4a9964acae60171bf4e0d2d34c183997a716e43",
      "parents": [
        "70e42bce5b60fbe0fdb1824e25e976418257cc70"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 09:21:11 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 09:21:11 2026 -0700"
      },
      "message": "agents: clarify automatic comment footer and surface AI disclosure in pr_info.md (#4355)\n\nWithout explicit rules distinguishing unreviewed comments from\nuser-approved comments or surfacing the AI disclosure comment in\n`pr_info.md`, subagents can post an automatic AI disclosure comment\nduring `create pr` that inaccurately claims user review and approval.\n\nDefine explicit footer strings for automatic versus user-approved\ncomments, require the automatic comment footer on unreviewed disclosure\ncomments, and include the AI disclosure comment in `pr_info.md` and the\nchat summary."
    },
    {
      "commit": "70e42bce5b60fbe0fdb1824e25e976418257cc70",
      "tree": "ec2bae4ae0099824db62a6b241556a74fa403490",
      "parents": [
        "c030f763029f92ac0e2d702da25970b388d97ea5"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Mon Oct 26 14:45:43 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 14:45:43 2026 +0000"
      },
      "message": "docs(uv): remove experimental notices from uv integration (#4353)\n\nThe `uv` integration is stable and no longer experimental.\n\nRemove experimental notices and qualifiers from the `uv` documentation,\nStarlark docstrings, and example comments.\n\nFixes #1975"
    },
    {
      "commit": "c030f763029f92ac0e2d702da25970b388d97ea5",
      "tree": "eddea552f56db456e1dc90f0814f94dddf74ea0c",
      "parents": [
        "12f9dcbec19c15cabbbb852575442ccee9d6e72d"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Oct 25 21:09:51 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 21:09:51 2026 -0700"
      },
      "message": "agents: add continuous Dependabot PR monitor to process-dependabot-prs (#4352)\n\nPreviously, `process-dependabot-prs` only evaluated open Dependabot PRs\nwhen manually invoked, requiring manual re-runs whenever new PRs opened\nor existing PRs were recreated after another merge.\n\nAdd `scripts/monitor_dependabot_prs.py` to poll GitHub in the background\nonce every 5 hours (or immediately on `SIGUSR1`) and wake the agent\nconversation via `agentapi send-message` only when new or updated open\nDependabot PRs appear, when an open PR becomes conflicting, or when a\npoll error occurs. Update\n`.agents/skills/process-dependabot-prs/SKILL.md` to launch the\nbackground daemon and trigger `SIGUSR1` after merging PRs."
    },
    {
      "commit": "12f9dcbec19c15cabbbb852575442ccee9d6e72d",
      "tree": "f1e5a6667bd041d82e3b0da22a67b4f7243df75b",
      "parents": [
        "8374a7dad11a415a4ae09ce06d9c1037872f47e8"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Oct 25 20:58:38 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 20:58:38 2026 -0700"
      },
      "message": "agents: rename buildkite-retry-job to retry-ci-job and refactor providers (#4351)\n\nThe `buildkite-retry-job` skill grew beyond Buildkite to handle GitHub\nActions workflow polling, job reruns, manual approval unblocking, and\nPR check routing inside a single procedural script with overloaded\npositional arguments and inconsistent error handling.\n\nRename the skill to `retry-ci-job` (`retry_ci_jobs.py`), replace\npositional target heuristics with explicit CLI flags (`--pr`, `--url`,\n`--buildkite-build`, `--buildkite-job-id`, `--github-job-id`), and\nencapsulate provider operations in `BuildkiteProvider`,\n`GitHubActionsProvider`, and `PrOrchestrator` with uniform failure\npropagation."
    },
    {
      "commit": "8374a7dad11a415a4ae09ce06d9c1037872f47e8",
      "tree": "c1662c0cf489bf03c57f79e4ef020a015afd44e6",
      "parents": [
        "229a8e0e6c330d9b3e888887843fa826f4cc4ff8"
      ],
      "author": {
        "name": "Richard Levasseur",
        "email": "richardlev@gmail.com",
        "time": "Sun Oct 25 20:57:47 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 20:57:47 2026 -0700"
      },
      "message": "docs: add GitHub Actions postsubmit CI status badge to README (#4350)\n\nSurface postsubmit GitHub Actions CI status alongside the existing\nBuildkite badge so maintainers and users can see at a glance whether\nmain passes GitHub Actions checks.\n\nAdd a workflow status badge for `.github/workflows/ci.yaml` filtered to\n`push` events on `main`."
    }
  ],
  "next": "229a8e0e6c330d9b3e888887843fa826f4cc4ff8"
}
