)]}'
{
  "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",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "fe0b80225280f6bcfb5bdf4746606c51eeb5b70d",
      "old_mode": 33188,
      "old_path": "dev/uv.lock",
      "new_id": "5b4db329d2b55b1da95271dce28fa552872dbec3",
      "new_mode": 33188,
      "new_path": "dev/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "be2e21a8c431e1780ac352309acce8e780dc9016",
      "old_mode": 33188,
      "old_path": "examples/build_file_generation/uv.lock",
      "new_id": "4ea2b113dade3ff8dd6dff9efae189f096f7ac37",
      "new_mode": 33188,
      "new_path": "examples/build_file_generation/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "d20f8756e01c8c99356286b2e4777c254b1ee54c",
      "old_mode": 33188,
      "old_path": "examples/bzlmod/pyproject.toml",
      "new_id": "0db7ddb4f493f28b4465a58b01f0cab13c933ce9",
      "new_mode": 33188,
      "new_path": "examples/bzlmod/pyproject.toml"
    },
    {
      "type": "modify",
      "old_id": "9788ae523efcfe1da1bd37b3846381ea38572936",
      "old_mode": 33188,
      "old_path": "examples/bzlmod/uv.lock",
      "new_id": "f3a51e9158c3ad4161f69dd7b824104f531167c5",
      "new_mode": 33188,
      "new_path": "examples/bzlmod/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "1a5870c343a6846ab7ac2d8cc7e428ead83b6aea",
      "old_mode": 33188,
      "old_path": "examples/pip_parse/pyproject.toml",
      "new_id": "6cc23bb899c7e7c13f6f8662bd2059de894e4af8",
      "new_mode": 33188,
      "new_path": "examples/pip_parse/pyproject.toml"
    },
    {
      "type": "modify",
      "old_id": "0bcfccf85737cd69796afc61e73db1c0fc751469",
      "old_mode": 33188,
      "old_path": "examples/pip_parse/uv.lock",
      "new_id": "86ea3f71f9cff4cbc99cb6260e87cc0ac3be507d",
      "new_mode": 33188,
      "new_path": "examples/pip_parse/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "3bc80ac8e695716ce86551178a305d9a9b4d7351",
      "old_mode": 33188,
      "old_path": "gazelle/examples/bzlmod_build_file_generation/pyproject.toml",
      "new_id": "abad80741d825ec7b7fac81af5fd9adbe8262677",
      "new_mode": 33188,
      "new_path": "gazelle/examples/bzlmod_build_file_generation/pyproject.toml"
    },
    {
      "type": "modify",
      "old_id": "8da72840b659d480541399eddc9258ec9c7d495b",
      "old_mode": 33188,
      "old_path": "gazelle/examples/bzlmod_build_file_generation/uv.lock",
      "new_id": "3c735dbefc4baace45552cfb264804dbb1f7bf0b",
      "new_mode": 33188,
      "new_path": "gazelle/examples/bzlmod_build_file_generation/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "d8dcf2d44e8a20baf41d1879e06288b03fb56d67",
      "old_mode": 33188,
      "old_path": "tests/integration/bzlmod_lockfile/requirements_lock.txt",
      "new_id": "114601068a4754babc88d9c72bbe277a7be8cce6",
      "new_mode": 33188,
      "new_path": "tests/integration/bzlmod_lockfile/requirements_lock.txt"
    },
    {
      "type": "modify",
      "old_id": "c69f3631b27631da0c55bf99ea6eb3c3125cab88",
      "old_mode": 33188,
      "old_path": "tests/integration/unified_pypi/requirements_b.txt",
      "new_id": "762c3688e1ee4c3d55392379f7684faa86ab809d",
      "new_mode": 33188,
      "new_path": "tests/integration/unified_pypi/requirements_b.txt"
    },
    {
      "type": "modify",
      "old_id": "ab5f031951d73895d7e7f7a902f7935ccf7597fe",
      "old_mode": 33188,
      "old_path": "tests/integration/unified_pypi/requirements_b_without_six.txt",
      "new_id": "788f12f818ff245d18483ed9d08df9815800626f",
      "new_mode": 33188,
      "new_path": "tests/integration/unified_pypi/requirements_b_without_six.txt"
    },
    {
      "type": "modify",
      "old_id": "f62a0a42eb43ca7fe460be8946675358db85ead0",
      "old_mode": 33188,
      "old_path": "tests/multi_pypi/alpha/pyproject.toml",
      "new_id": "13b7cdefc0531b5648c82bc91fcc6245e2aed8f5",
      "new_mode": 33188,
      "new_path": "tests/multi_pypi/alpha/pyproject.toml"
    },
    {
      "type": "modify",
      "old_id": "fc2f1f03bca890344058e3be1de0491e141bc8eb",
      "old_mode": 33188,
      "old_path": "tests/multi_pypi/alpha/uv.lock",
      "new_id": "2b1abdcf5d3e45eced16919ad4b87eb350ee8353",
      "new_mode": 33188,
      "new_path": "tests/multi_pypi/alpha/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "753b52e8498aafabcc54f3bda16d1cac9f192fa2",
      "old_mode": 33188,
      "old_path": "tests/multi_pypi/beta/pyproject.toml",
      "new_id": "4dfa60f784a6bf91d10afd544b0f34e586ab60c4",
      "new_mode": 33188,
      "new_path": "tests/multi_pypi/beta/pyproject.toml"
    },
    {
      "type": "modify",
      "old_id": "6ff80a5af3a9b4dcad9641e520795d7a9e1e32d4",
      "old_mode": 33188,
      "old_path": "tests/multi_pypi/beta/uv.lock",
      "new_id": "a84e1656e6853072e299ec7091b697a365cc484c",
      "new_mode": 33188,
      "new_path": "tests/multi_pypi/beta/uv.lock"
    },
    {
      "type": "modify",
      "old_id": "602dc8ad0ac79466911b0447eb3375641af45602",
      "old_mode": 33188,
      "old_path": "tests/multiple_inputs/multiple_inputs.txt",
      "new_id": "fc3b2810867b99c82e0fe1f5f335fa3ee4f02cf7",
      "new_mode": 33188,
      "new_path": "tests/multiple_inputs/multiple_inputs.txt"
    },
    {
      "type": "modify",
      "old_id": "f6326123dad1b45f105620979072772c1efb2563",
      "old_mode": 33188,
      "old_path": "tests/multiple_inputs/multiple_pyproject_toml.txt",
      "new_id": "d56b55d03c9bc4071ad654f166d14f7b6814013e",
      "new_mode": 33188,
      "new_path": "tests/multiple_inputs/multiple_pyproject_toml.txt"
    },
    {
      "type": "modify",
      "old_id": "567df9e161d738ea39bddc31b7b0c7ea2b241bc6",
      "old_mode": 33188,
      "old_path": "tests/multiple_inputs/multiple_requirements_in.txt",
      "new_id": "9743a8176c16f9001e15ccfe338d406dd17bb3b3",
      "new_mode": 33188,
      "new_path": "tests/multiple_inputs/multiple_requirements_in.txt"
    },
    {
      "type": "modify",
      "old_id": "36d880ef204c7ee2bdc96f307ef8c667000820a8",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/pyproject_toml/requirements.txt",
      "new_id": "18f38fe96b11d6de348cd94fbb14ce342054c31a",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/pyproject_toml/requirements.txt"
    },
    {
      "type": "modify",
      "old_id": "34c3ebe3de5f8a2cc9ea43807ef0ca5dcaec22f6",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/testdata/build_constraints.txt",
      "new_id": "07d65af646f10c8d04d251fd1f31d071a7e246bb",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/build_constraints.txt"
    },
    {
      "type": "modify",
      "old_id": "34c3ebe3de5f8a2cc9ea43807ef0ca5dcaec22f6",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/testdata/build_constraints2.txt",
      "new_id": "07d65af646f10c8d04d251fd1f31d071a7e246bb",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/build_constraints2.txt"
    },
    {
      "type": "modify",
      "old_id": "8fe01fc406d06c0e94e9d580a200739a7b9254a3",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/testdata/constraints.txt",
      "new_id": "883e00a01597fa83f82a33aedd4cd777558163a8",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/constraints.txt"
    },
    {
      "type": "modify",
      "old_id": "18ade2c5b96d17b1ab810a4e8ee8ef4efb9bd1c4",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/testdata/constraints2.txt",
      "new_id": "03e03c7ae570069362fe9fe58cbd3e6f1dbfae8d",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/constraints2.txt"
    },
    {
      "type": "modify",
      "old_id": "fd33583df8c52e57410cfde47cf0735ba64b63f8",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/testdata/requirements.txt",
      "new_id": "38494c5aa4d9895ac07d45e6eeffd1e3aa908777",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/requirements.txt"
    },
    {
      "type": "modify",
      "old_id": "bbd6b25713865a45c6efa02b333e318faf11d138",
      "old_mode": 33261,
      "old_path": "tests/uv/lock/testdata/requirements_directory.txt",
      "new_id": "2a4b64d69af09074a17dacc15f24a53488db6c83",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/testdata/requirements_directory.txt"
    },
    {
      "type": "modify",
      "old_id": "531c7ad6297323d94b636bae0dbe0228601fe87a",
      "old_mode": 33188,
      "old_path": "tests/uv/lock/workspaces/requirements.txt",
      "new_id": "08f8b4f24820ad819310b34b9fbf16378a579fe6",
      "new_mode": 33188,
      "new_path": "tests/uv/lock/workspaces/requirements.txt"
    }
  ]
}
