From 4b826022b1a09e7343aba411e3662ade506d21c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 21:14:44 +0000 Subject: [PATCH 01/10] =?UTF-8?q?=E2=AC=86=20Bump=20black=20from=2026.1.0?= =?UTF-8?q?=20to=2026.3.1=20(#15100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [black](https://github.com/psf/black) from 26.1.0 to 26.3.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/26.1.0...26.3.1) --- updated-dependencies: - dependency-name: black dependency-version: 26.3.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/uv.lock b/uv.lock index 2414d88ed5..e45d41cbf7 100644 --- a/uv.lock +++ b/uv.lock @@ -367,7 +367,7 @@ wheels = [ [[package]] name = "black" -version = "26.1.0" +version = "26.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -379,34 +379,34 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/88/560b11e521c522440af991d46848a2bde64b5f7202ec14e1f46f9509d328/black-26.1.0.tar.gz", hash = "sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58", size = 658785, upload-time = "2026-01-18T04:50:11.993Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/1b/523329e713f965ad0ea2b7a047eeb003007792a0353622ac7a8cb2ee6fef/black-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ca699710dece84e3ebf6e92ee15f5b8f72870ef984bf944a57a777a48357c168", size = 1849661, upload-time = "2026-01-18T04:59:12.425Z" }, - { url = "https://files.pythonhosted.org/packages/14/82/94c0640f7285fa71c2f32879f23e609dd2aa39ba2641f395487f24a578e7/black-26.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e8e75dabb6eb83d064b0db46392b25cabb6e784ea624219736e8985a6b3675d", size = 1689065, upload-time = "2026-01-18T04:59:13.993Z" }, - { url = "https://files.pythonhosted.org/packages/f0/78/474373cbd798f9291ed8f7107056e343fd39fef42de4a51c7fd0d360840c/black-26.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb07665d9a907a1a645ee41a0df8a25ffac8ad9c26cdb557b7b88eeeeec934e0", size = 1751502, upload-time = "2026-01-18T04:59:15.971Z" }, - { url = "https://files.pythonhosted.org/packages/29/89/59d0e350123f97bc32c27c4d79563432d7f3530dca2bff64d855c178af8b/black-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:7ed300200918147c963c87700ccf9966dceaefbbb7277450a8d646fc5646bf24", size = 1400102, upload-time = "2026-01-18T04:59:17.8Z" }, - { url = "https://files.pythonhosted.org/packages/e1/bc/5d866c7ae1c9d67d308f83af5462ca7046760158bbf142502bad8f22b3a1/black-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c5b7713daea9bf943f79f8c3b46f361cc5229e0e604dcef6a8bb6d1c37d9df89", size = 1207038, upload-time = "2026-01-18T04:59:19.543Z" }, - { url = "https://files.pythonhosted.org/packages/30/83/f05f22ff13756e1a8ce7891db517dbc06200796a16326258268f4658a745/black-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cee1487a9e4c640dc7467aaa543d6c0097c391dc8ac74eb313f2fbf9d7a7cb5", size = 1831956, upload-time = "2026-01-18T04:59:21.38Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/b2c570550e39bedc157715e43927360312d6dd677eed2cc149a802577491/black-26.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d62d14ca31c92adf561ebb2e5f2741bf8dea28aef6deb400d49cca011d186c68", size = 1672499, upload-time = "2026-01-18T04:59:23.257Z" }, - { url = "https://files.pythonhosted.org/packages/7a/d7/990d6a94dc9e169f61374b1c3d4f4dd3037e93c2cc12b6f3b12bc663aa7b/black-26.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb1dafbbaa3b1ee8b4550a84425aac8874e5f390200f5502cf3aee4a2acb2f14", size = 1735431, upload-time = "2026-01-18T04:59:24.729Z" }, - { url = "https://files.pythonhosted.org/packages/36/1c/cbd7bae7dd3cb315dfe6eeca802bb56662cc92b89af272e014d98c1f2286/black-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:101540cb2a77c680f4f80e628ae98bd2bd8812fb9d72ade4f8995c5ff019e82c", size = 1400468, upload-time = "2026-01-18T04:59:27.381Z" }, - { url = "https://files.pythonhosted.org/packages/59/b1/9fe6132bb2d0d1f7094613320b56297a108ae19ecf3041d9678aec381b37/black-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f3977a16e347f1b115662be07daa93137259c711e526402aa444d7a88fdc9d4", size = 1207332, upload-time = "2026-01-18T04:59:28.711Z" }, - { url = "https://files.pythonhosted.org/packages/f5/13/710298938a61f0f54cdb4d1c0baeb672c01ff0358712eddaf29f76d32a0b/black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f", size = 1878189, upload-time = "2026-01-18T04:59:30.682Z" }, - { url = "https://files.pythonhosted.org/packages/79/a6/5179beaa57e5dbd2ec9f1c64016214057b4265647c62125aa6aeffb05392/black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6", size = 1700178, upload-time = "2026-01-18T04:59:32.387Z" }, - { url = "https://files.pythonhosted.org/packages/8c/04/c96f79d7b93e8f09d9298b333ca0d31cd9b2ee6c46c274fd0f531de9dc61/black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a", size = 1777029, upload-time = "2026-01-18T04:59:33.767Z" }, - { url = "https://files.pythonhosted.org/packages/49/f9/71c161c4c7aa18bdda3776b66ac2dc07aed62053c7c0ff8bbda8c2624fe2/black-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791", size = 1406466, upload-time = "2026-01-18T04:59:35.177Z" }, - { url = "https://files.pythonhosted.org/packages/4a/8b/a7b0f974e473b159d0ac1b6bcefffeb6bec465898a516ee5cc989503cbc7/black-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954", size = 1216393, upload-time = "2026-01-18T04:59:37.18Z" }, - { url = "https://files.pythonhosted.org/packages/79/04/fa2f4784f7237279332aa735cdfd5ae2e7730db0072fb2041dadda9ae551/black-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ba1d768fbfb6930fc93b0ecc32a43d8861ded16f47a40f14afa9bb04ab93d304", size = 1877781, upload-time = "2026-01-18T04:59:39.054Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ad/5a131b01acc0e5336740a039628c0ab69d60cf09a2c87a4ec49f5826acda/black-26.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b807c240b64609cb0e80d2200a35b23c7df82259f80bef1b2c96eb422b4aac9", size = 1699670, upload-time = "2026-01-18T04:59:41.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/7c/b05f22964316a52ab6b4265bcd52c0ad2c30d7ca6bd3d0637e438fc32d6e/black-26.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1de0f7d01cc894066a1153b738145b194414cc6eeaad8ef4397ac9abacf40f6b", size = 1775212, upload-time = "2026-01-18T04:59:42.545Z" }, - { url = "https://files.pythonhosted.org/packages/a6/a3/e8d1526bea0446e040193185353920a9506eab60a7d8beb062029129c7d2/black-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:91a68ae46bf07868963671e4d05611b179c2313301bd756a89ad4e3b3db2325b", size = 1409953, upload-time = "2026-01-18T04:59:44.357Z" }, - { url = "https://files.pythonhosted.org/packages/c7/5a/d62ebf4d8f5e3a1daa54adaab94c107b57be1b1a2f115a0249b41931e188/black-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:be5e2fe860b9bd9edbf676d5b60a9282994c03fbbd40fe8f5e75d194f96064ca", size = 1217707, upload-time = "2026-01-18T04:59:45.719Z" }, - { url = "https://files.pythonhosted.org/packages/6a/83/be35a175aacfce4b05584ac415fd317dd6c24e93a0af2dcedce0f686f5d8/black-26.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9dc8c71656a79ca49b8d3e2ce8103210c9481c57798b48deeb3a8bb02db5f115", size = 1871864, upload-time = "2026-01-18T04:59:47.586Z" }, - { url = "https://files.pythonhosted.org/packages/a5/f5/d33696c099450b1274d925a42b7a030cd3ea1f56d72e5ca8bbed5f52759c/black-26.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b22b3810451abe359a964cc88121d57f7bce482b53a066de0f1584988ca36e79", size = 1701009, upload-time = "2026-01-18T04:59:49.443Z" }, - { url = "https://files.pythonhosted.org/packages/1b/87/670dd888c537acb53a863bc15abbd85b22b429237d9de1b77c0ed6b79c42/black-26.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53c62883b3f999f14e5d30b5a79bd437236658ad45b2f853906c7cbe79de00af", size = 1767806, upload-time = "2026-01-18T04:59:50.769Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9c/cd3deb79bfec5bcf30f9d2100ffeec63eecce826eb63e3961708b9431ff1/black-26.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:f016baaadc423dc960cdddf9acae679e71ee02c4c341f78f3179d7e4819c095f", size = 1433217, upload-time = "2026-01-18T04:59:52.218Z" }, - { url = "https://files.pythonhosted.org/packages/4e/29/f3be41a1cf502a283506f40f5d27203249d181f7a1a2abce1c6ce188035a/black-26.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:66912475200b67ef5a0ab665011964bf924745103f51977a78b4fb92a9fc1bf0", size = 1245773, upload-time = "2026-01-18T04:59:54.457Z" }, - { url = "https://files.pythonhosted.org/packages/e4/3d/51bdb3ecbfadfaf825ec0c75e1de6077422b4afa2091c6c9ba34fbfc0c2d/black-26.1.0-py3-none-any.whl", hash = "sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede", size = 204010, upload-time = "2026-01-18T04:50:09.978Z" }, + { url = "https://files.pythonhosted.org/packages/32/a8/11170031095655d36ebc6664fe0897866f6023892396900eec0e8fdc4299/black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2", size = 1866562, upload-time = "2026-03-12T03:39:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/9e7548d719c3248c6c2abfd555d11169457cbd584d98d179111338423790/black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b", size = 1703623, upload-time = "2026-03-12T03:40:00.347Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0a/8d17d1a9c06f88d3d030d0b1d4373c1551146e252afe4547ed601c0e697f/black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac", size = 1768388, upload-time = "2026-03-12T03:40:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/79/c1ee726e221c863cde5164f925bacf183dfdf0397d4e3f94889439b947b4/black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a", size = 1412969, upload-time = "2026-03-12T03:40:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/73/a5/15c01d613f5756f68ed8f6d4ec0a1e24b82b18889fa71affd3d1f7fad058/black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a", size = 1220345, upload-time = "2026-03-12T03:40:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, + { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/86e462cdd311a3c2a8ece708d22aba17d0b2a0d5348ca34b40cdcbea512e/black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983", size = 1420867, upload-time = "2026-03-12T03:40:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e5/22515a19cb7eaee3440325a6b0d95d2c0e88dd180cb011b12ae488e031d1/black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb", size = 1230124, upload-time = "2026-03-12T03:40:20.425Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/5728052a3c0450c53d9bb3945c4c46b91baa62b2cafab6801411b6271e45/black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54", size = 1895034, upload-time = "2026-03-12T03:40:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/7cae55fdfdfbe9d19e9a8d25d145018965fe2079fa908101c3733b0c55a0/black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f", size = 1718503, upload-time = "2026-03-12T03:40:23.666Z" }, + { url = "https://files.pythonhosted.org/packages/e1/87/af89ad449e8254fdbc74654e6467e3c9381b61472cc532ee350d28cfdafb/black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56", size = 1793557, upload-time = "2026-03-12T03:40:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/43/10/d6c06a791d8124b843bf325ab4ac7d2f5b98731dff84d6064eafd687ded1/black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839", size = 1422766, upload-time = "2026-03-12T03:40:27.14Z" }, + { url = "https://files.pythonhosted.org/packages/59/4f/40a582c015f2d841ac24fed6390bd68f0fc896069ff3a886317959c9daf8/black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2", size = 1232140, upload-time = "2026-03-12T03:40:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/e36e27c9cebc1311b7579210df6f1c86e50f2d7143ae4fcf8a5017dc8809/black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78", size = 1889234, upload-time = "2026-03-12T03:40:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7b/9871acf393f64a5fa33668c19350ca87177b181f44bb3d0c33b2d534f22c/black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568", size = 1720522, upload-time = "2026-03-12T03:40:32.346Z" }, + { url = "https://files.pythonhosted.org/packages/03/87/e766c7f2e90c07fb7586cc787c9ae6462b1eedab390191f2b7fc7f6170a9/black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f", size = 1787824, upload-time = "2026-03-12T03:40:33.636Z" }, + { url = "https://files.pythonhosted.org/packages/ac/94/2424338fb2d1875e9e83eed4c8e9c67f6905ec25afd826a911aea2b02535/black-26.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c", size = 1445855, upload-time = "2026-03-12T03:40:35.442Z" }, + { url = "https://files.pythonhosted.org/packages/86/43/0c3338bd928afb8ee7471f1a4eec3bdbe2245ccb4a646092a222e8669840/black-26.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1", size = 1258109, upload-time = "2026-03-12T03:40:36.832Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/52d98722666d6fc6c3dd4c76df339501d6efd40e0ff95e6186a7b7f0befd/black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b", size = 207542, upload-time = "2026-03-12T03:36:01.668Z" }, ] [[package]] From 04b279fe776ba03a27a0692bb0ca9ce0beb91f61 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 12 Mar 2026 21:15:19 +0000 Subject: [PATCH 02/10] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index f7b4c0891c..1e60539979 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Internal +* ⬆ Bump black from 26.1.0 to 26.3.1. PR [#15100](https://github.com/fastapi/fastapi/pull/15100) by [@dependabot[bot]](https://github.com/apps/dependabot). * 🔨 Update script to autofix permalinks to account for headers with Markdown links. PR [#15062](https://github.com/fastapi/fastapi/pull/15062) by [@tiangolo](https://github.com/tiangolo). * 📌 Pin Click for MkDocs live reload. PR [#15057](https://github.com/fastapi/fastapi/pull/15057) by [@tiangolo](https://github.com/tiangolo). * ⬆ Bump werkzeug from 3.1.5 to 3.1.6. PR [#14948](https://github.com/fastapi/fastapi/pull/14948) by [@dependabot[bot]](https://github.com/apps/dependabot). From a007932885b442e6462b8583b19cd34f3a19f562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:59:36 +0100 Subject: [PATCH 03/10] =?UTF-8?q?=E2=AC=86=20Bump=20pyjwt=20from=202.11.0?= =?UTF-8?q?=20to=202.12.0=20(#15110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.11.0 to 2.12.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.11.0...2.12.0) --- updated-dependencies: - dependency-name: pyjwt dependency-version: 2.12.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index e45d41cbf7..4261e433ad 100644 --- a/uv.lock +++ b/uv.lock @@ -4321,11 +4321,11 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.11.0" +version = "2.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/5a/b46fa56bf322901eee5b0454a34343cdbdae202cd421775a8ee4e42fd519/pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623", size = 98019, upload-time = "2026-01-30T19:59:55.694Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/10/e8192be5f38f3e8e7e046716de4cae33d56fd5ae08927a823bb916be36c1/pyjwt-2.12.0.tar.gz", hash = "sha256:2f62390b667cd8257de560b850bb5a883102a388829274147f1d724453f8fb02", size = 102511, upload-time = "2026-03-12T17:15:30.831Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469", size = 28224, upload-time = "2026-01-30T19:59:54.539Z" }, + { url = "https://files.pythonhosted.org/packages/15/70/70f895f404d363d291dcf62c12c85fdd47619ad9674ac0f53364d035925a/pyjwt-2.12.0-py3-none-any.whl", hash = "sha256:9bb459d1bdd0387967d287f5656bf7ec2b9a26645d1961628cda1764e087fd6e", size = 29700, upload-time = "2026-03-12T17:15:29.257Z" }, ] [package.optional-dependencies] From 9d9d51e054cb7c3f86a83ec56a11105502555fab Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Mar 2026 15:00:03 +0000 Subject: [PATCH 04/10] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 1e60539979..4dd6c85a5c 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Internal +* ⬆ Bump pyjwt from 2.11.0 to 2.12.0. PR [#15110](https://github.com/fastapi/fastapi/pull/15110) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump black from 26.1.0 to 26.3.1. PR [#15100](https://github.com/fastapi/fastapi/pull/15100) by [@dependabot[bot]](https://github.com/apps/dependabot). * 🔨 Update script to autofix permalinks to account for headers with Markdown links. PR [#15062](https://github.com/fastapi/fastapi/pull/15062) by [@tiangolo](https://github.com/tiangolo). * 📌 Pin Click for MkDocs live reload. PR [#15057](https://github.com/fastapi/fastapi/pull/15057) by [@tiangolo](https://github.com/tiangolo). From e4f19cd5c45b9c707cc19982b29696c9c10a5bc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:00:22 +0100 Subject: [PATCH 05/10] =?UTF-8?q?=E2=AC=86=20Bump=20cairosvg=20from=202.8.?= =?UTF-8?q?2=20to=202.9.0=20(#15108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [cairosvg](https://github.com/Kozea/CairoSVG) from 2.8.2 to 2.9.0. - [Release notes](https://github.com/Kozea/CairoSVG/releases) - [Changelog](https://github.com/Kozea/CairoSVG/blob/main/NEWS.rst) - [Commits](https://github.com/Kozea/CairoSVG/compare/2.8.2...2.9.0) --- updated-dependencies: - dependency-name: cairosvg dependency-version: 2.9.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/uv.lock b/uv.lock index 4261e433ad..2802a98a9d 100644 --- a/uv.lock +++ b/uv.lock @@ -469,7 +469,7 @@ wheels = [ [[package]] name = "cairosvg" -version = "2.8.2" +version = "2.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cairocffi" }, @@ -478,10 +478,7 @@ dependencies = [ { name = "pillow" }, { name = "tinycss2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/b9/5106168bd43d7cd8b7cc2a2ee465b385f14b63f4c092bb89eee2d48c8e67/cairosvg-2.8.2.tar.gz", hash = "sha256:07cbf4e86317b27a92318a4cac2a4bb37a5e9c1b8a27355d06874b22f85bef9f", size = 8398590, upload-time = "2025-05-15T06:56:32.653Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/48/816bd4aaae93dbf9e408c58598bc32f4a8c65f4b86ab560864cb3ee60adb/cairosvg-2.8.2-py3-none-any.whl", hash = "sha256:eab46dad4674f33267a671dce39b64be245911c901c70d65d2b7b0821e852bf5", size = 45773, upload-time = "2025-05-15T06:56:28.552Z" }, -] +sdist = { url = "https://files.pythonhosted.org/packages/38/07/e8412a13019b3f737972dea23a2c61ca42becafc16c9338f4ca7a0caa993/cairosvg-2.9.0.tar.gz", hash = "sha256:1debb00cd2da11350d8b6f5ceb739f1b539196d71d5cf5eb7363dbd1bfbc8dc5", size = 40877, upload-time = "2026-03-13T15:42:00.564Z" } [[package]] name = "certifi" From ae08a807a75a33e888e44c774b99f521c86d9cad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Mar 2026 15:01:19 +0000 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 4dd6c85a5c..bddea056ae 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Internal +* ⬆ Bump cairosvg from 2.8.2 to 2.9.0. PR [#15108](https://github.com/fastapi/fastapi/pull/15108) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyjwt from 2.11.0 to 2.12.0. PR [#15110](https://github.com/fastapi/fastapi/pull/15110) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump black from 26.1.0 to 26.3.1. PR [#15100](https://github.com/fastapi/fastapi/pull/15100) by [@dependabot[bot]](https://github.com/apps/dependabot). * 🔨 Update script to autofix permalinks to account for headers with Markdown links. PR [#15062](https://github.com/fastapi/fastapi/pull/15062) by [@tiangolo](https://github.com/tiangolo). From b4b76c811bca51d5a9fce5dc7683a8f7b3be638a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:01:34 +0100 Subject: [PATCH 07/10] =?UTF-8?q?=E2=AC=86=20Bump=20dorny/paths-filter=20f?= =?UTF-8?q?rom=203=20to=204=20(#15106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 3 to 4. - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](https://github.com/dorny/paths-filter/compare/v3...v4) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-docs.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index a0b507dd90..ea18fc0109 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v6 # For pull requests it's not necessary to checkout the code but for the main branch it is - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@v4 id: filter with: filters: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5b139f1d12..2e39633a0c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: steps: - uses: actions/checkout@v6 # For pull requests it's not necessary to checkout the code but for the main branch it is - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@v4 id: filter with: filters: | From 7e7c4d09ac3426ddd180247e8f582b84e7438852 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Mar 2026 15:02:03 +0000 Subject: [PATCH 08/10] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index bddea056ae..ba591530fe 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Internal +* ⬆ Bump dorny/paths-filter from 3 to 4. PR [#15106](https://github.com/fastapi/fastapi/pull/15106) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump cairosvg from 2.8.2 to 2.9.0. PR [#15108](https://github.com/fastapi/fastapi/pull/15108) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyjwt from 2.11.0 to 2.12.0. PR [#15110](https://github.com/fastapi/fastapi/pull/15110) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump black from 26.1.0 to 26.3.1. PR [#15100](https://github.com/fastapi/fastapi/pull/15100) by [@dependabot[bot]](https://github.com/apps/dependabot). From 98b269b51ef8ff9fe8b66d7bcd31f2d9770fc18f Mon Sep 17 00:00:00 2001 From: Sofie Van Landeghem Date: Sun, 15 Mar 2026 12:44:39 +0100 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=91=B7=20Add=20`ty`=20to=20precommi?= =?UTF-8?q?t=20(#15091)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- .pre-commit-config.yaml | 7 +++++++ fastapi/_compat/__init__.py | 2 +- fastapi/_compat/v2.py | 10 +++++----- fastapi/applications.py | 25 ++++++++++++------------- fastapi/cli.py | 2 +- fastapi/datastructures.py | 5 +++++ fastapi/dependencies/utils.py | 23 +++++++++++++---------- fastapi/encoders.py | 8 ++++---- fastapi/openapi/models.py | 2 +- fastapi/openapi/utils.py | 15 ++++++--------- fastapi/param_functions.py | 3 +-- fastapi/params.py | 15 +++++++-------- fastapi/routing.py | 14 +++++++++----- fastapi/security/api_key.py | 4 +++- fastapi/security/http.py | 6 +++--- pyproject.toml | 1 + uv.lock | 28 ++++++++++++++++++++++++++++ 17 files changed, 107 insertions(+), 63 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 64b84bfbd2..21c8bea6cd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,6 +37,13 @@ repos: language: unsupported pass_filenames: false + - id: local-ty + name: ty check + entry: uv run ty check fastapi + require_serial: true + language: unsupported + pass_filenames: false + - id: add-permalinks-pages language: unsupported name: add-permalinks-pages diff --git a/fastapi/_compat/__init__.py b/fastapi/_compat/__init__.py index 4581c38c88..40810eab7a 100644 --- a/fastapi/_compat/__init__.py +++ b/fastapi/_compat/__init__.py @@ -26,7 +26,7 @@ from .v2 import Undefined as Undefined from .v2 import Url as Url from .v2 import copy_field_info as copy_field_info from .v2 import create_body_model as create_body_model -from .v2 import evaluate_forwardref as evaluate_forwardref +from .v2 import evaluate_forwardref as evaluate_forwardref # ty: ignore[deprecated] from .v2 import get_cached_model_fields as get_cached_model_fields from .v2 import get_definitions as get_definitions from .v2 import get_flat_models_from_fields as get_flat_models_from_fields diff --git a/fastapi/_compat/v2.py b/fastapi/_compat/v2.py index 79fba93188..535af07849 100644 --- a/fastapi/_compat/v2.py +++ b/fastapi/_compat/v2.py @@ -22,10 +22,10 @@ from pydantic import BaseModel, ConfigDict, Field, TypeAdapter, create_model from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation from pydantic import ValidationError as ValidationError -from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined] +from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined] # ty: ignore[unused-ignore-comment] GetJsonSchemaHandler as GetJsonSchemaHandler, ) -from pydantic._internal._typing_extra import eval_type_lenient +from pydantic._internal._typing_extra import eval_type_lenient # ty: ignore[deprecated] from pydantic.fields import FieldInfo as FieldInfo from pydantic.json_schema import GenerateJsonSchema as _GenerateJsonSchema from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue @@ -38,7 +38,7 @@ from pydantic_core.core_schema import ( RequiredParam = PydanticUndefined Undefined = PydanticUndefined -evaluate_forwardref = eval_type_lenient +evaluate_forwardref = eval_type_lenient # ty: ignore[deprecated] class GenerateJsonSchema(_GenerateJsonSchema): @@ -148,7 +148,7 @@ class ModelField: Field(**field_dict["attributes"]), ) self._type_adapter: TypeAdapter[Any] = TypeAdapter( - Annotated[annotated_args], + Annotated[annotated_args], # ty: ignore[invalid-type-form] config=self.config, ) @@ -438,7 +438,7 @@ def get_flat_models_from_annotation( for arg in get_args(annotation): if lenient_issubclass(arg, (BaseModel, Enum)): if arg not in known_models: - known_models.add(arg) # type: ignore[arg-type] + known_models.add(arg) # type: ignore[arg-type] # ty: ignore[unused-ignore-comment] if lenient_issubclass(arg, BaseModel): get_flat_models_from_model(arg, known_models=known_models) else: diff --git a/fastapi/applications.py b/fastapi/applications.py index e7e816c2e9..4af1146b0d 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1,10 +1,6 @@ from collections.abc import Awaitable, Callable, Coroutine, Sequence from enum import Enum -from typing import ( - Annotated, - Any, - TypeVar, -) +from typing import Annotated, Any, TypeVar from annotated_doc import Doc from fastapi import routing @@ -1006,11 +1002,12 @@ class FastAPI(Starlette): self.exception_handlers.setdefault( RequestValidationError, request_validation_exception_handler ) + + # Starlette still has incorrect type specification for the handlers self.exception_handlers.setdefault( WebSocketRequestValidationError, - # Starlette still has incorrect type specification for the handlers - websocket_request_validation_exception_handler, # type: ignore - ) + websocket_request_validation_exception_handler, # type: ignore[arg-type] # ty: ignore[unused-ignore-comment] + ) # ty: ignore[no-matching-overload] self.user_middleware: list[Middleware] = ( [] if middleware is None else list(middleware) @@ -1032,11 +1029,13 @@ class FastAPI(Starlette): exception_handlers[key] = value middleware = ( - [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] + [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] # ty: ignore[invalid-argument-type] + self.user_middleware + [ Middleware( - ExceptionMiddleware, handlers=exception_handlers, debug=debug + ExceptionMiddleware, # ty: ignore[invalid-argument-type] + handlers=exception_handlers, + debug=debug, ), # Add FastAPI-specific AsyncExitStackMiddleware for closing files. # Before this was also used for closing dependencies with yield but @@ -1057,7 +1056,7 @@ class FastAPI(Starlette): # user middlewares, the same context is used. # This is currently not needed, only for closing files, but used to be # important when dependencies with yield were closed here. - Middleware(AsyncExitStackMiddleware), + Middleware(AsyncExitStackMiddleware), # ty: ignore[invalid-argument-type] ] ) @@ -4596,7 +4595,7 @@ class FastAPI(Starlette): Read more about it in the [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated). """ - return self.router.on_event(event_type) + return self.router.on_event(event_type) # ty: ignore[deprecated] def middleware( self, @@ -4639,7 +4638,7 @@ class FastAPI(Starlette): """ def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.add_middleware(BaseHTTPMiddleware, dispatch=func) + self.add_middleware(BaseHTTPMiddleware, dispatch=func) # ty: ignore[invalid-argument-type] return func return decorator diff --git a/fastapi/cli.py b/fastapi/cli.py index 8d3301e9da..fda271a53a 100644 --- a/fastapi/cli.py +++ b/fastapi/cli.py @@ -6,7 +6,7 @@ except ImportError: # pragma: no cover def main() -> None: - if not cli_main: # type: ignore[truthy-function] + if not cli_main: # type: ignore[truthy-function] # ty: ignore[unused-ignore-comment] message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n' print(message) raise RuntimeError(message) # noqa: B904 diff --git a/fastapi/datastructures.py b/fastapi/datastructures.py index 479e1a7c3b..1da784cf09 100644 --- a/fastapi/datastructures.py +++ b/fastapi/datastructures.py @@ -179,3 +179,8 @@ def Default(value: DefaultType) -> DefaultType: if the overridden default value was truthy. """ return DefaultPlaceholder(value) # type: ignore + + +# Sentinel for "parameter not provided" in Param/FieldInfo. +# Typed as None to satisfy ty +_Unset = Default(None) diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 8fcf1a5b3c..6b14dac8dc 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -33,7 +33,7 @@ from fastapi._compat import ( Undefined, copy_field_info, create_body_model, - evaluate_forwardref, + evaluate_forwardref, # ty: ignore[deprecated] field_annotation_is_scalar, field_annotation_is_scalar_sequence, field_annotation_is_sequence, @@ -100,12 +100,14 @@ def ensure_multipart_is_installed() -> None: except (ImportError, AssertionError): try: # __version__ is available in both multiparts, and can be mocked - from multipart import __version__ # type: ignore[no-redef,import-untyped] + from multipart import ( # type: ignore[no-redef,import-untyped] # ty: ignore[unused-ignore-comment] + __version__, + ) assert __version__ try: # parse_options_header is only available in the right multipart - from multipart.multipart import ( # type: ignore[import-untyped] + from multipart.multipart import ( # type: ignore[import-untyped] # ty: ignore[unused-ignore-comment] parse_options_header, ) @@ -243,7 +245,7 @@ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any: if isinstance(annotation, str): annotation = ForwardRef(annotation) - annotation = evaluate_forwardref(annotation, globalns, globalns) + annotation = evaluate_forwardref(annotation, globalns, globalns) # ty: ignore[deprecated] if annotation is type(None): return None return annotation @@ -320,8 +322,9 @@ def get_dependant( and param_details.depends.scope == "function" ): assert dependant.call + call_name = getattr(dependant.call, "__name__", "") raise DependencyScopeError( - f'The dependency "{dependant.call.__name__}" has a scope of ' + f'The dependency "{call_name}" has a scope of ' '"request", it cannot depend on dependencies with scope "function".' ) sub_own_oauth_scopes: list[str] = [] @@ -596,7 +599,7 @@ async def solve_dependencies( *, request: Request | WebSocket, dependant: Dependant, - body: dict[str, Any] | FormData | None = None, + body: dict[str, Any] | FormData | bytes | None = None, background_tasks: StarletteBackgroundTasks | None = None, response: Response | None = None, dependency_overrides_provider: Any | None = None, @@ -619,7 +622,7 @@ async def solve_dependencies( if response is None: response = Response() del response.headers["content-length"] - response.status_code = None # type: ignore + response.status_code = None # type: ignore # ty: ignore[unused-ignore-comment] if dependency_cache is None: dependency_cache = {} for sub_dependant in dependant.dependencies: @@ -826,7 +829,7 @@ def request_params_to_args( for key in received_params.keys(): if key not in processed_keys: - if hasattr(received_params, "getlist"): + if isinstance(received_params, (ImmutableMultiDict, Headers)): value = received_params.getlist(key) if isinstance(value, list) and (len(value) == 1): params_to_process[key] = value[0] @@ -947,7 +950,7 @@ async def _extract_form_body( async def request_body_to_args( body_fields: list[ModelField], - received_body: dict[str, Any] | FormData | None, + received_body: dict[str, Any] | FormData | bytes | None, embed_body_fields: bool, ) -> tuple[dict[str, Any], list[dict[str, Any]]]: values: dict[str, Any] = {} @@ -978,7 +981,7 @@ async def request_body_to_args( for field in body_fields: loc = ("body", get_validation_alias(field)) value: Any | None = None - if body_to_process is not None: + if body_to_process is not None and not isinstance(body_to_process, bytes): try: value = body_to_process.get(get_validation_alias(field)) # If the received body is a list, not a dict diff --git a/fastapi/encoders.py b/fastapi/encoders.py index e20255c110..84893dc808 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -22,7 +22,7 @@ from annotated_doc import Doc from fastapi.exceptions import PydanticV1NotSupportedError from fastapi.types import IncEx from pydantic import BaseModel -from pydantic.color import Color +from pydantic.color import Color # ty: ignore[deprecated] from pydantic.networks import AnyUrl, NameEmail from pydantic.types import SecretBytes, SecretStr from pydantic_core import PydanticUndefinedType @@ -67,7 +67,7 @@ def decimal_encoder(dec_value: Decimal) -> int | float: ENCODERS_BY_TYPE: dict[type[Any], Callable[[Any], Any]] = { bytes: lambda o: o.decode(), - Color: str, + Color: str, # ty: ignore[deprecated] datetime.date: isoformat, datetime.datetime: isoformat, datetime.time: isoformat, @@ -220,9 +220,9 @@ def jsonable_encoder( if isinstance(obj, encoder_type): return encoder_instance(obj) if include is not None and not isinstance(include, (set, dict)): - include = set(include) # type: ignore[assignment] + include = set(include) # type: ignore[assignment] # ty: ignore[unused-ignore-comment] if exclude is not None and not isinstance(exclude, (set, dict)): - exclude = set(exclude) # type: ignore[assignment] + exclude = set(exclude) # type: ignore[assignment] # ty: ignore[unused-ignore-comment] if isinstance(obj, BaseModel): obj_dict = obj.model_dump( mode="json", diff --git a/fastapi/openapi/models.py b/fastapi/openapi/models.py index d7950241fc..b9fad31a70 100644 --- a/fastapi/openapi/models.py +++ b/fastapi/openapi/models.py @@ -20,7 +20,7 @@ try: from pydantic import EmailStr except ImportError: # pragma: no cover - class EmailStr(str): # type: ignore + class EmailStr(str): # type: ignore # ty: ignore[unused-ignore-comment] @classmethod def __get_validators__(cls) -> Iterable[Callable[..., Any]]: yield cls.validate diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index 828442559b..8f1852b0cc 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -8,14 +8,13 @@ from typing import Any, Literal, cast from fastapi import routing from fastapi._compat import ( ModelField, - Undefined, get_definitions, get_flat_models_from_fields, get_model_name_map, get_schema_from_model_field, lenient_issubclass, ) -from fastapi.datastructures import DefaultPlaceholder +from fastapi.datastructures import DefaultPlaceholder, _Unset from fastapi.dependencies.models import Dependant from fastapi.dependencies.utils import ( _get_flat_fields_from_params, @@ -170,7 +169,7 @@ def _get_openapi_operation_parameters( example = getattr(field_info, "example", None) if openapi_examples: parameter["examples"] = jsonable_encoder(openapi_examples) - elif example != Undefined: + elif example is not _Unset: parameter["example"] = jsonable_encoder(example) if getattr(field_info, "deprecated", None): parameter["deprecated"] = True @@ -207,7 +206,7 @@ def get_openapi_operation_request_body( request_media_content["examples"] = jsonable_encoder( field_info.openapi_examples ) - elif field_info.example != Undefined: + elif field_info.example is not _Unset: request_media_content["example"] = jsonable_encoder(field_info.example) request_body_oai["content"] = {request_media_type: request_media_content} return request_body_oai @@ -245,10 +244,8 @@ def get_openapi_operation_metadata( operation["description"] = route.description operation_id = route.operation_id or route.unique_id if operation_id in operation_ids: - message = ( - f"Duplicate Operation ID {operation_id} for function " - + f"{route.endpoint.__name__}" - ) + endpoint_name = getattr(route.endpoint, "__name__", "") + message = f"Duplicate Operation ID {operation_id} for function {endpoint_name}" file_name = getattr(route.endpoint, "__globals__", {}).get("__file__") if file_name: message += f" at {file_name}" @@ -606,4 +603,4 @@ def get_openapi( output["tags"] = tags if external_docs: output["externalDocs"] = external_docs - return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore + return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore # ty: ignore[unused-ignore-comment] diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py index d3edde2682..1856178fcb 100644 --- a/fastapi/param_functions.py +++ b/fastapi/param_functions.py @@ -4,12 +4,11 @@ from typing import Annotated, Any, Literal from annotated_doc import Doc from fastapi import params from fastapi._compat import Undefined +from fastapi.datastructures import _Unset from fastapi.openapi.models import Example from pydantic import AliasChoices, AliasPath from typing_extensions import deprecated -_Unset: Any = Undefined - def Path( # noqa: N802 default: Annotated[ diff --git a/fastapi/params.py b/fastapi/params.py index 68f9870810..e8f2eb290d 100644 --- a/fastapi/params.py +++ b/fastapi/params.py @@ -13,8 +13,7 @@ from typing_extensions import deprecated from ._compat import ( Undefined, ) - -_Unset: Any = Undefined +from .datastructures import _Unset class ParamTypes(Enum): @@ -135,7 +134,7 @@ class Param(FieldInfo): # type: ignore[misc] return f"{self.__class__.__name__}({self.default})" -class Path(Param): # type: ignore[misc] +class Path(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment] in_ = ParamTypes.path def __init__( @@ -219,7 +218,7 @@ class Path(Param): # type: ignore[misc] ) -class Query(Param): # type: ignore[misc] +class Query(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment] in_ = ParamTypes.query def __init__( @@ -301,7 +300,7 @@ class Query(Param): # type: ignore[misc] ) -class Header(Param): # type: ignore[misc] +class Header(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment] in_ = ParamTypes.header def __init__( @@ -385,7 +384,7 @@ class Header(Param): # type: ignore[misc] ) -class Cookie(Param): # type: ignore[misc] +class Cookie(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment] in_ = ParamTypes.cookie def __init__( @@ -579,7 +578,7 @@ class Body(FieldInfo): # type: ignore[misc] return f"{self.__class__.__name__}({self.default})" -class Form(Body): # type: ignore[misc] +class Form(Body): # type: ignore[misc] # ty: ignore[unused-ignore-comment] def __init__( self, default: Any = Undefined, @@ -661,7 +660,7 @@ class Form(Body): # type: ignore[misc] ) -class File(Form): # type: ignore[misc] +class File(Form): # type: ignore[misc] # ty: ignore[unused-ignore-comment] def __init__( self, default: Any = Undefined, diff --git a/fastapi/routing.py b/fastapi/routing.py index e2c83aa7b3..36acb6b89d 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -26,6 +26,7 @@ from typing import ( Annotated, Any, TypeVar, + cast, ) import anyio @@ -75,6 +76,7 @@ from starlette import routing from starlette._exception_handler import wrap_app_handling_exceptions from starlette._utils import is_async_callable from starlette.concurrency import iterate_in_threadpool, run_in_threadpool +from starlette.datastructures import FormData from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.responses import JSONResponse, Response, StreamingResponse @@ -100,8 +102,10 @@ def request_response( and returns an ASGI application. """ f: Callable[[Request], Awaitable[Response]] = ( - func if is_async_callable(func) else functools.partial(run_in_threadpool, func) # type:ignore - ) + func # type: ignore[assignment] # ty: ignore[unused-ignore-comment] + if is_async_callable(func) + else functools.partial(run_in_threadpool, func) # type: ignore[call-arg] # ty: ignore[unused-ignore-comment] + ) # ty: ignore[invalid-assignment] async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive, send) @@ -453,7 +457,7 @@ def get_request_handler( solved_result = await solve_dependencies( request=request, dependant=dependant, - body=body, + body=cast(dict[str, Any] | FormData | bytes | None, body), dependency_overrides_provider=dependency_overrides_provider, async_exit_stack=async_exit_stack, embed_body_fields=embed_body_fields, @@ -635,7 +639,7 @@ def get_request_handler( else: def _sync_stream_jsonl() -> Iterator[bytes]: - for item in gen: + for item in gen: # ty: ignore[not-iterable] yield _serialize_item(item) jsonl_stream_content = _sync_stream_jsonl() @@ -908,7 +912,7 @@ class APIRoute(routing.Route): mode="serialization", ) else: - self.response_field = None # type: ignore + self.response_field = None # type: ignore # ty: ignore[unused-ignore-comment] if self.stream_item_type: stream_item_name = "StreamItem_" + self.unique_id self.stream_item_field: ModelField | None = create_model_field( diff --git a/fastapi/security/api_key.py b/fastapi/security/api_key.py index 89358a9136..83a4585a08 100644 --- a/fastapi/security/api_key.py +++ b/fastapi/security/api_key.py @@ -9,6 +9,8 @@ from starlette.status import HTTP_401_UNAUTHORIZED class APIKeyBase(SecurityBase): + model: APIKey + def __init__( self, location: APIKeyIn, @@ -20,7 +22,7 @@ class APIKeyBase(SecurityBase): self.auto_error = auto_error self.model: APIKey = APIKey( - **{"in": location}, + **{"in": location}, # ty: ignore[invalid-argument-type] name=name, description=description, ) diff --git a/fastapi/security/http.py b/fastapi/security/http.py index 05299323cb..228f2aa8ea 100644 --- a/fastapi/security/http.py +++ b/fastapi/security/http.py @@ -67,6 +67,8 @@ class HTTPAuthorizationCredentials(BaseModel): class HTTPBase(SecurityBase): + model: HTTPBaseModel + def __init__( self, *, @@ -75,9 +77,7 @@ class HTTPBase(SecurityBase): description: str | None = None, auto_error: bool = True, ): - self.model: HTTPBaseModel = HTTPBaseModel( - scheme=scheme, description=description - ) + self.model = HTTPBaseModel(scheme=scheme, description=description) self.scheme_name = scheme_name or self.__class__.__name__ self.auto_error = auto_error diff --git a/pyproject.toml b/pyproject.toml index da6bf9ead4..73d3929292 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -177,6 +177,7 @@ tests = [ "pyyaml >=5.3.1,<7.0.0", "sqlmodel >=0.0.31", "strawberry-graphql >=0.200.0,<1.0.0", + "ty>=0.0.9", "types-orjson >=3.6.2", "types-ujson >=5.10.0.20240515", "a2wsgi >=1.9.0,<=2.0.0", diff --git a/uv.lock b/uv.lock index 2802a98a9d..9a10d7bda6 100644 --- a/uv.lock +++ b/uv.lock @@ -1158,6 +1158,7 @@ dev = [ { name = "ruff" }, { name = "sqlmodel" }, { name = "strawberry-graphql" }, + { name = "ty" }, { name = "typer" }, { name = "types-orjson" }, { name = "types-ujson" }, @@ -1221,6 +1222,7 @@ tests = [ { name = "ruff" }, { name = "sqlmodel" }, { name = "strawberry-graphql" }, + { name = "ty" }, { name = "types-orjson" }, { name = "types-ujson" }, { name = "ujson" }, @@ -1309,6 +1311,7 @@ dev = [ { name = "ruff", specifier = ">=0.14.14" }, { name = "sqlmodel", specifier = ">=0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, + { name = "ty", specifier = ">=0.0.9" }, { name = "typer", specifier = ">=0.21.1" }, { name = "types-orjson", specifier = ">=3.6.2" }, { name = "types-ujson", specifier = ">=5.10.0.20240515" }, @@ -1372,6 +1375,7 @@ tests = [ { name = "ruff", specifier = ">=0.14.14" }, { name = "sqlmodel", specifier = ">=0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, + { name = "ty", specifier = ">=0.0.9" }, { name = "types-orjson", specifier = ">=3.6.2" }, { name = "types-ujson", specifier = ">=5.10.0.20240515" }, { name = "ujson", specifier = ">=5.8.0" }, @@ -5651,6 +5655,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/bf/945d527ff706233636c73880b22c7c953f3faeb9d6c7e2e85bfbfd0134a0/trio-0.32.0-py3-none-any.whl", hash = "sha256:4ab65984ef8370b79a76659ec87aa3a30c5c7c83ff250b4de88c29a8ab6123c5", size = 512030, upload-time = "2025-10-31T07:18:15.885Z" }, ] +[[package]] +name = "ty" +version = "0.0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/20/2ba8fd9493c89c41dfe9dbb73bc70a28b28028463bc0d2897ba8be36230a/ty-0.0.21.tar.gz", hash = "sha256:a4c2ba5d67d64df8fcdefd8b280ac1149d24a73dbda82fa953a0dff9d21400ed", size = 5297967, upload-time = "2026-03-06T01:57:13.809Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/70/edf38bb37517531681d1c37f5df64744e5ad02673c02eb48447eae4bea08/ty-0.0.21-py3-none-linux_armv6l.whl", hash = "sha256:7bdf2f572378de78e1f388d24691c89db51b7caf07cf90f2bfcc1d6b18b70a76", size = 10299222, upload-time = "2026-03-06T01:57:16.64Z" }, + { url = "https://files.pythonhosted.org/packages/72/62/0047b0bd19afeefbc7286f20a5f78a2aa39f92b4d89853f0d7185ab89edc/ty-0.0.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7e9613994610431ab8625025bd2880dbcb77c5c9fabdd21134cda12d840a529d", size = 10130513, upload-time = "2026-03-06T01:57:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/a2/20/0b93a9e91aaed23155780258cdfdb4726ef68b6985378ac069bc427291a0/ty-0.0.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:56d3b198b64dd0a19b2b66e257deaed2ecea568e722ae5352f3c6fb62027f89d", size = 9605425, upload-time = "2026-03-06T01:57:27.115Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fd/9945e2fa2996a1287b1e1d7ce050e97e1f420233b271e770934bfa0880a0/ty-0.0.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d23d2c34f7a77d974bb08f0860ef700addc8a683d81a0319f71c08f87506cfd0", size = 10108298, upload-time = "2026-03-06T01:57:35.429Z" }, + { url = "https://files.pythonhosted.org/packages/52/e7/4ec52fcb15f3200826c9f048472c062549a05b0d1ef0b51f32d527b513c4/ty-0.0.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56b01fd2519637a4ca88344f61c96225f540c98ff18bca321d4eaa7bb0f7aa2f", size = 10121556, upload-time = "2026-03-06T01:57:03.242Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c0/ad457be2a8abea0f25549598bd098554540ced66229488daa0d558dad3c8/ty-0.0.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de7e11c63c6afc40f3e9ba716374add171aee7fabc70b5146a510705c6d41b", size = 10603264, upload-time = "2026-03-06T01:56:52.134Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5b/2ecc7a2175243a4bcb72f5298ae41feabbb93b764bb0dc45722f3752c2c2/ty-0.0.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62f7f5b235c4f7876db305c36997aea07b7af29b1a068f373d0e2547e25f32ff", size = 11196428, upload-time = "2026-03-06T01:57:32.94Z" }, + { url = "https://files.pythonhosted.org/packages/37/f5/aff507d6a901f328ef96a298032b0c11aaaf950a146ed7dd3b5bf2cd3acf/ty-0.0.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee8399f7c453a425291e6688efe430cfae7ab0ac4ffd50eba9f872bf878b54f6", size = 10866355, upload-time = "2026-03-06T01:56:57.831Z" }, + { url = "https://files.pythonhosted.org/packages/be/30/822bbcb92d55b65989aa7ed06d9585f28ade9c9447369194ed4b0fb3b5b9/ty-0.0.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210e7568c9f886c4d01308d751949ee714ad7ad9d7d928d2ba90d329dd880367", size = 10738177, upload-time = "2026-03-06T01:57:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/57/cc/46e7991b6469e93ac2c7e533a028983e402485580150ac864c56352a3a82/ty-0.0.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:53508e345b11569f78b21ba8e2b4e61df38a9754947fb3cd9f2ef574367338fb", size = 10079158, upload-time = "2026-03-06T01:57:00.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/c2/0bbdadfbd008240f8f1a87dc877433cb3884436097926107ccf06e618199/ty-0.0.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:553e43571f4a35604c36cfd07d8b61a5eb7a714e3c67f8c4ff2cf674fefbaef9", size = 10150535, upload-time = "2026-03-06T01:57:08.815Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b5/2dbdb7b57b5362200ef0a39738ebd31331726328336def0143ac097ee59d/ty-0.0.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:666f6822e3b9200abfa7e95eb0ddd576460adb8d66b550c0ad2c70abc84a2048", size = 10319803, upload-time = "2026-03-06T01:57:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/72/84/70e52c0b7abc7c2086f9876ef454a73b161d3125315536d8d7e911c94ca4/ty-0.0.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0854d008347ce4a5fb351af132f660a390ab2a1163444d075251d43e6f74b9b", size = 10826239, upload-time = "2026-03-06T01:57:21.727Z" }, + { url = "https://files.pythonhosted.org/packages/a1/8a/1f72480fd013bbc6cd1929002abbbcde9a0b08ead6a15154de9d7f7fa37e/ty-0.0.21-py3-none-win32.whl", hash = "sha256:bef3ab4c7b966bcc276a8ac6c11b63ba222d21355b48d471ea782c4104eee4e0", size = 9693196, upload-time = "2026-03-06T01:57:24.126Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/1104808b875c26c640e536945753a78562d606bef4e241d9dbf3d92477f6/ty-0.0.21-py3-none-win_amd64.whl", hash = "sha256:a709d576e5bea84b745d43058d8b9cd4f27f74a0b24acb4b0cbb7d3d41e0d050", size = 10668660, upload-time = "2026-03-06T01:56:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b8/25e0adc404bbf986977657b25318991f93097b49f8aea640d93c0b0db68e/ty-0.0.21-py3-none-win_arm64.whl", hash = "sha256:f72047996598ac20553fb7e21ba5741e3c82dee4e9eadf10d954551a5fe09391", size = 10104161, upload-time = "2026-03-06T01:57:06.072Z" }, +] + [[package]] name = "typer" version = "0.24.1" From eb6851dd4bdb90dd94ed0a804972f0ef72d3dc39 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Mar 2026 11:45:11 +0000 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index ba591530fe..047090ff8f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Internal +* 👷 Add `ty` to precommit. PR [#15091](https://github.com/fastapi/fastapi/pull/15091) by [@svlandeg](https://github.com/svlandeg). * ⬆ Bump dorny/paths-filter from 3 to 4. PR [#15106](https://github.com/fastapi/fastapi/pull/15106) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump cairosvg from 2.8.2 to 2.9.0. PR [#15108](https://github.com/fastapi/fastapi/pull/15108) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyjwt from 2.11.0 to 2.12.0. PR [#15110](https://github.com/fastapi/fastapi/pull/15110) by [@dependabot[bot]](https://github.com/apps/dependabot).