Skip to content

Commit 821486f

Browse files
fix: use TYPE_CHECKING for BaseExceptionGroup type safety
ROOT CAUSE: Pyright strict mode couldn't resolve BaseExceptionGroup type from try/except import blocks, causing 68 type errors across all files using the pattern. CHANGES: - Use typing.TYPE_CHECKING to import BaseExceptionGroup from builtins at type-checking time (Pyright knows this type exists) - Keep runtime try/except for Python 3.10 compatibility - Apply to all 16 files using BaseExceptionGroup IMPACT: - All 68 Pyright type errors resolved - Tests still pass (runtime behavior unchanged) - Type checker now understands BaseExceptionGroup type FILES MODIFIED: - src/mcp/shared/exceptions.py - src/mcp/client/_memory.py - src/mcp/client/session_group.py - src/mcp/client/sse.py - src/mcp/client/stdio.py - src/mcp/client/streamable_http.py - src/mcp/client/websocket.py - src/mcp/server/sse.py - src/mcp/server/stdio.py - src/mcp/server/streamable_http.py - src/mcp/server/streamable_http_manager.py - src/mcp/server/websocket.py - src/mcp/server/experimental/task_result_handler.py - src/mcp/server/experimental/task_support.py - src/mcp/server/lowlevel/server.py - tests/shared/test_exceptions.py
1 parent 07edfb1 commit 821486f

File tree

16 files changed

+139
-80
lines changed

16 files changed

+139
-80
lines changed

src/mcp/client/_memory.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
from __future__ import annotations
44

5-
try:
6-
from builtins import BaseExceptionGroup
7-
except ImportError:
8-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
95
from collections.abc import AsyncIterator
106
from contextlib import AbstractAsyncContextManager, asynccontextmanager
117
from types import TracebackType
12-
from typing import Any
8+
from typing import TYPE_CHECKING, Any
9+
10+
if TYPE_CHECKING:
11+
from builtins import BaseExceptionGroup
12+
else:
13+
try:
14+
from builtins import BaseExceptionGroup
15+
except ImportError:
16+
from exceptiongroup import BaseExceptionGroup
1317

1418
import anyio
1519

src/mcp/client/session_group.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88

99
import contextlib
1010
import logging
11-
12-
try:
13-
from builtins import BaseExceptionGroup
14-
except ImportError:
15-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
1611
from collections.abc import Callable
1712
from dataclasses import dataclass
1813
from types import TracebackType
19-
from typing import Any, TypeAlias
14+
from typing import TYPE_CHECKING, Any, TypeAlias
15+
16+
if TYPE_CHECKING:
17+
from builtins import BaseExceptionGroup
18+
else:
19+
try:
20+
from builtins import BaseExceptionGroup
21+
except ImportError:
22+
from exceptiongroup import BaseExceptionGroup
2023

2124
import anyio
2225
import httpx

src/mcp/client/sse.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import logging
2-
3-
try:
4-
from builtins import BaseExceptionGroup
5-
except ImportError:
6-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
72
from collections.abc import Callable
83
from contextlib import asynccontextmanager
9-
from typing import Any
4+
from typing import TYPE_CHECKING, Any
105
from urllib.parse import parse_qs, urljoin, urlparse
116

7+
if TYPE_CHECKING:
8+
from builtins import BaseExceptionGroup
9+
else:
10+
try:
11+
from builtins import BaseExceptionGroup
12+
except ImportError:
13+
from exceptiongroup import BaseExceptionGroup
14+
1215
import anyio
1316
import httpx
1417
from anyio.abc import TaskStatus

src/mcp/client/stdio.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import logging
22
import os
33
import sys
4-
5-
try:
6-
from builtins import BaseExceptionGroup
7-
except ImportError:
8-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
94
from contextlib import asynccontextmanager
105
from pathlib import Path
11-
from typing import Literal, TextIO
6+
from typing import TYPE_CHECKING, Literal, TextIO
7+
8+
if TYPE_CHECKING:
9+
from builtins import BaseExceptionGroup
10+
else:
11+
try:
12+
from builtins import BaseExceptionGroup
13+
except ImportError:
14+
from exceptiongroup import BaseExceptionGroup
1215

1316
import anyio
1417
import anyio.lowlevel

src/mcp/client/streamable_http.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44

55
import contextlib
66
import logging
7-
8-
try:
9-
from builtins import BaseExceptionGroup
10-
except ImportError:
11-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
127
from collections.abc import AsyncGenerator, Awaitable, Callable
138
from contextlib import asynccontextmanager
149
from dataclasses import dataclass
10+
from typing import TYPE_CHECKING
11+
12+
if TYPE_CHECKING:
13+
from builtins import BaseExceptionGroup
14+
else:
15+
try:
16+
from builtins import BaseExceptionGroup
17+
except ImportError:
18+
from exceptiongroup import BaseExceptionGroup
1519

1620
import anyio
1721
import httpx

src/mcp/client/websocket.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import json
2-
3-
try:
4-
from builtins import BaseExceptionGroup
5-
except ImportError:
6-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
72
from collections.abc import AsyncGenerator
83
from contextlib import asynccontextmanager
4+
from typing import TYPE_CHECKING
5+
6+
if TYPE_CHECKING:
7+
from builtins import BaseExceptionGroup
8+
else:
9+
try:
10+
from builtins import BaseExceptionGroup
11+
except ImportError:
12+
from exceptiongroup import BaseExceptionGroup
913

1014
import anyio
1115
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream

src/mcp/server/experimental/task_result_handler.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
"""
1111

1212
import logging
13+
from typing import TYPE_CHECKING, Any
1314

14-
try:
15+
if TYPE_CHECKING:
1516
from builtins import BaseExceptionGroup
16-
except ImportError:
17-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
18-
from typing import Any
17+
else:
18+
try:
19+
from builtins import BaseExceptionGroup
20+
except ImportError:
21+
from exceptiongroup import BaseExceptionGroup
1922

2023
import anyio
2124

src/mcp/server/experimental/task_support.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
infrastructure needed for task-augmented requests: store, queue, and handler.
55
"""
66

7-
try:
8-
from builtins import BaseExceptionGroup
9-
except ImportError:
10-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
117
from collections.abc import AsyncIterator
128
from contextlib import asynccontextmanager
139
from dataclasses import dataclass, field
10+
from typing import TYPE_CHECKING
11+
12+
if TYPE_CHECKING:
13+
from builtins import BaseExceptionGroup
14+
else:
15+
try:
16+
from builtins import BaseExceptionGroup
17+
except ImportError:
18+
from exceptiongroup import BaseExceptionGroup
1419

1520
import anyio
1621
from anyio.abc import TaskGroup

src/mcp/server/lowlevel/server.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,18 @@ async def main():
3939
import contextvars
4040
import logging
4141
import warnings
42-
43-
try:
44-
from builtins import BaseExceptionGroup
45-
except ImportError:
46-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
4742
from collections.abc import AsyncIterator, Awaitable, Callable
4843
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager
4944
from importlib.metadata import version as importlib_version
50-
from typing import Any, Generic
45+
from typing import TYPE_CHECKING, Any, Generic
46+
47+
if TYPE_CHECKING:
48+
from builtins import BaseExceptionGroup
49+
else:
50+
try:
51+
from builtins import BaseExceptionGroup
52+
except ImportError:
53+
from exceptiongroup import BaseExceptionGroup
5154

5255
import anyio
5356
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream

src/mcp/server/sse.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,19 @@ async def handle_sse(request):
3737
"""
3838

3939
import logging
40-
41-
try:
42-
from builtins import BaseExceptionGroup
43-
except ImportError:
44-
from exceptiongroup import BaseExceptionGroup # type: ignore[import-not-found]
4540
from contextlib import asynccontextmanager
46-
from typing import Any
41+
from typing import TYPE_CHECKING, Any
4742
from urllib.parse import quote
4843
from uuid import UUID, uuid4
4944

45+
if TYPE_CHECKING:
46+
from builtins import BaseExceptionGroup
47+
else:
48+
try:
49+
from builtins import BaseExceptionGroup
50+
except ImportError:
51+
from exceptiongroup import BaseExceptionGroup
52+
5053
import anyio
5154
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
5255
from pydantic import ValidationError

0 commit comments

Comments
 (0)