From 66dc695071d8a040db72d5546eb848a58b41152e Mon Sep 17 00:00:00 2001 From: rijenkii Date: Tue, 10 Feb 2026 17:52:24 +0700 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20Replace=20`dict`=20by=20`Mappin?= =?UTF-8?q?g`=20on=20`HTTPException.headers`=20(#12997)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- fastapi/exceptions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py index 62b4674de..9924d0e2b 100644 --- a/fastapi/exceptions.py +++ b/fastapi/exceptions.py @@ -1,4 +1,4 @@ -from collections.abc import Sequence +from collections.abc import Mapping, Sequence from typing import Annotated, Any, Optional, TypedDict, Union from annotated_doc import Doc @@ -68,7 +68,7 @@ class HTTPException(StarletteHTTPException): ), ] = None, headers: Annotated[ - Optional[dict[str, str]], + Optional[Mapping[str, str]], Doc( """ Any headers to send to the client in the response. From 363aced75a26a5247855ea41b2bee53481be4d52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 10 Feb 2026 10:52:51 +0000 Subject: [PATCH 2/4] =?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 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 71dc7bb74..fff7ccc33 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Features + +* ✨ Replace `dict` by `Mapping` on `HTTPException.headers`. PR [#12997](https://github.com/fastapi/fastapi/pull/12997) by [@rijenkii](https://github.com/rijenkii). + ### Internal * 🔧 Configure `test` workflow to run tests with `inline-snapshot=review`. PR [#14876](https://github.com/fastapi/fastapi/pull/14876) by [@YuriiMotov](https://github.com/YuriiMotov). From df950111fe97c8040e49f4600d6f563456bbdba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20S=C3=A1nchez=20Castro?= <72013291+JavierSanchezCastro@users.noreply.github.com> Date: Tue, 10 Feb 2026 11:58:40 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20Show=20a=20clear=20error=20on?= =?UTF-8?q?=20attempt=20to=20include=20router=20into=20itself=20(#14258)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Javier Sánchez Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- fastapi/routing.py | 4 ++++ tests/test_router_circular_import.py | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/test_router_circular_import.py diff --git a/fastapi/routing.py b/fastapi/routing.py index 16a89ef3e..ed873fda8 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -1393,6 +1393,10 @@ class APIRouter(routing.Router): app.include_router(internal_router) ``` """ + assert self is not router, ( + "Cannot include the same APIRouter instance into itself. " + "Did you mean to include a different router?" + ) if prefix: assert prefix.startswith("/"), "A path prefix must start with '/'" assert not prefix.endswith("/"), ( diff --git a/tests/test_router_circular_import.py b/tests/test_router_circular_import.py new file mode 100644 index 000000000..492a26d00 --- /dev/null +++ b/tests/test_router_circular_import.py @@ -0,0 +1,12 @@ +import pytest +from fastapi import APIRouter + + +def test_router_circular_import(): + router = APIRouter() + + with pytest.raises( + AssertionError, + match="Cannot include the same APIRouter instance into itself. Did you mean to include a different router?", + ): + router.include_router(router) From 8bdb0d22423fdfbc4e12eee1baa339ffa960471d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 10 Feb 2026 10:59:10 +0000 Subject: [PATCH 4/4] =?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 fff7ccc33..495bf83b4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### Features +* ✨ Show a clear error on attempt to include router into itself. PR [#14258](https://github.com/fastapi/fastapi/pull/14258) by [@JavierSanchezCastro](https://github.com/JavierSanchezCastro). * ✨ Replace `dict` by `Mapping` on `HTTPException.headers`. PR [#12997](https://github.com/fastapi/fastapi/pull/12997) by [@rijenkii](https://github.com/rijenkii). ### Internal