René's URL Explorer Experiment


Title: Run SSE and Unicode transport tests in process instead of over sockets by maxisbey · Pull Request #2765 · modelcontextprotocol/python-sdk · GitHub

Open Graph Title: Run SSE and Unicode transport tests in process instead of over sockets by maxisbey · Pull Request #2765 · modelcontextprotocol/python-sdk

X Title: Run SSE and Unicode transport tests in process instead of over sockets by maxisbey · Pull Request #2765 · modelcontextprotocol/python-sdk

Description: Second installment of the in-process test migration that started in #2764: tests/shared/test_sse.py and tests/client/test_http_unicode.py still used the bind-then-close port pick + uvicorn subprocess + readiness-poll harness, which races under pytest-xdist when two workers grab the same ephemeral port. test_sse_session_cleanup_on_disconnect has flaked exactly this way under parallel load. Motivation and Context Same mechanism and fix as #2764. The two files now drive the same Starlette apps in process through StreamingASGITransport (via the sanctioned tests.interaction.transports re-export): tests/shared/test_sse.py: sse_client connects through an httpx_client_factory backed by the bridge — the same pattern the interaction suite's SSE leg uses — and the basic/mounted/request-context servers become plain app factories sharing one make_app(server) builder. DNS-rebinding protection is disabled in the in-process apps (it guards against a network attack that can't exist here; the protection behaviour itself is pinned by tests/server/test_sse_security.py). tests/client/test_http_unicode.py: the Unicode echo server runs in process and streamable_http_client speaks to it through the bridge with follow_redirects=True, matching the SDK's own client factory (Starlette's Mount 307-redirects the bare /mcp path; the subprocess version silently relied on redirect-following too). Assertions are unchanged, with two deliberate exceptions now that the server handlers run as traced in-process code: test_sse_client_timeout is deleted. It was @pytest.mark.skip from the day it was introduced ("highlights a possible bug in SSE read timeout exception handling") and carried pragma: no cover, so no executing coverage is lost. Its premise — a real socket read timeout firing mid-stream — cannot occur for an in-process app, so it could never be unskipped here. The slow:// resource branch and the sse_read_timeout=0.5 fixture plumbing existed only for it. Note for the record: the suspicion it encoded (an expired sse_read_timeout may not surface an error to the in-flight request — the ReadTimeout path in src/mcp/client/sse.py is still pragma: lax no cover) is not tracked anywhere; nearest existing issue is #1811, which is the same failure family with a different trigger. Happy to file a dedicated issue so deleting the test doesn't delete the suspicion. Handlers no test ever invoked are gone or restructured. The main SSE server's tools handlers had no callers; the context server's unknown-tool fallthrough and defensive if ctx.request: arms were dead. They're removed or replaced with dispatch asserts (assert params.name in (...)), since unreachable branches now fail branch coverage instead of hiding in an untraced subprocess. The migrated test_sse.py also gets the same prose pass the security files got in #2764: behaviour-sentence docstrings, full annotations, and the line-counter loop in the raw-connection test replaced by two anext() assertions, which retires the file's last pragma: no branch. tests/shared/test_streamable_http.py is the remaining subprocess-based file and will be its own (final) migration, along with pruning the then-unused wait_for_server helper. How Has This Been Tested? ./scripts/test green: 1526 passed, 100% line+branch coverage, strict-no-cover clean (the suite's skip count drops from 2 to 1 with the dead test removed) The two files stress-tested heavily: ~100 runs including pytest-xdist at -n 2/4/8/16, sustained CPU load (loadavg >100), GC-canary runs for ResourceWarning leaks under filterwarnings=error, and failure-injection runs to verify clean teardown on assertion failure — zero failures The post-disconnect 404 regression test (#1227) is now deterministic by construction: the bridge's drain-on-close means the server-side session teardown provably completes before the follow-up POST (the old socket version actually raced uvicorn's disconnect processing) Breaking Changes None — test-only. Types of changes Bug fix (non-breaking change which fixes an issue) Checklist I have read the MCP Documentation My code follows the repository's style guidelines New and existing tests pass locally I have added appropriate error handling I have added or updated documentation as needed Additional context Several migrated tests now overlap with tests/interaction/transports/test_sse.py coverage (basic connection, session-created callback, disconnect cleanup, happy/error round trips). Deduplicating is deliberately out of scope here — this PR keeps the harness swap auditable — but it's inventoried for a follow-up. AI Disclaimer

Open Graph Description: Second installment of the in-process test migration that started in #2764: tests/shared/test_sse.py and tests/client/test_http_unicode.py still used the bind-then-close port pick + uvicorn subproce...

X Description: Second installment of the in-process test migration that started in #2764: tests/shared/test_sse.py and tests/client/test_http_unicode.py still used the bind-then-close port pick + uvicorn subproce...

Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/2765

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:bde0fd8e-ccae-64be-4c24-058b13bd3176
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-id9982:210405:178C9E7:1E7FB43:6A5C58D1
html-safe-nonced0fb4ee17d2605b97eebc646c1cef29edddfc94e5cca34b33b78e795c960e502
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5OTgyOjIxMDQwNToxNzhDOUU3OjFFN0ZCNDM6NkE1QzU4RDEiLCJ2aXNpdG9yX2lkIjoiMjgwNzczNDE3MDYyMTI3ODI1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=
visitor-hmac84d7d5e5acf663d2b56d157cc0e1e17f0de9d9d1f85603f130a199618a5d990c
hovercard-subject-tagpull_request:3790967877
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/2765/files
twitter:imagehttps://avatars.githubusercontent.com/u/224885523?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/224885523?s=400&v=4
og:image:altSecond installment of the in-process test migration that started in #2764: tests/shared/test_sse.py and tests/client/test_http_unicode.py still used the bind-then-close port pick + uvicorn subproce...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git
octolytics-dimension-user_id182288589
octolytics-dimension-user_loginmodelcontextprotocol
octolytics-dimension-repository_id862584018
octolytics-dimension-repository_nwomodelcontextprotocol/python-sdk
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id862584018
octolytics-dimension-repository_network_root_nwomodelcontextprotocol/python-sdk
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release9c975978430e9ad293956f2bbdaf153b1bd84a99
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol%2Fpython-sdk%2Fpull%2F2765%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fmodelcontextprotocol%2Fpython-sdk%2Fpull%2F2765%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=modelcontextprotocol%2Fpython-sdk
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Reloadhttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
modelcontextprotocol https://github.com/modelcontextprotocol
python-sdkhttps://github.com/modelcontextprotocol/python-sdk
Notifications https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Fork 3.7k https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Star 23.7k https://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk
Code https://github.com/modelcontextprotocol/python-sdk
Issues 259 https://github.com/modelcontextprotocol/python-sdk/issues
Pull requests 307 https://github.com/modelcontextprotocol/python-sdk/pulls
Actions https://github.com/modelcontextprotocol/python-sdk/actions
Projects https://github.com/modelcontextprotocol/python-sdk/projects
Models https://github.com/modelcontextprotocol/python-sdk/models
Security and quality 6 https://github.com/modelcontextprotocol/python-sdk/security
Insights https://github.com/modelcontextprotocol/python-sdk/pulse
Code https://github.com/modelcontextprotocol/python-sdk
Issues https://github.com/modelcontextprotocol/python-sdk/issues
Pull requests https://github.com/modelcontextprotocol/python-sdk/pulls
Actions https://github.com/modelcontextprotocol/python-sdk/actions
Projects https://github.com/modelcontextprotocol/python-sdk/projects
Models https://github.com/modelcontextprotocol/python-sdk/models
Security and quality https://github.com/modelcontextprotocol/python-sdk/security
Insights https://github.com/modelcontextprotocol/python-sdk/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fmodelcontextprotocol%2Fpython-sdk%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fmodelcontextprotocol%2Fpython-sdk%2Fissues%2Fnew%2Fchoose
maxisbeyhttps://github.com/maxisbey
mainhttps://github.com/modelcontextprotocol/python-sdk/tree/main
maxisbey/deflake-sse-and-unicode-testshttps://github.com/modelcontextprotocol/python-sdk/tree/maxisbey/deflake-sse-and-unicode-tests
Conversation 0 https://github.com/modelcontextprotocol/python-sdk/pull/2765
Commits 1 https://github.com/modelcontextprotocol/python-sdk/pull/2765/commits
Checks 33 https://github.com/modelcontextprotocol/python-sdk/pull/2765/checks
Files changed https://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Run SSE and Unicode transport tests in process instead of over sockets https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#top
Show all changes 1 commit https://github.com/modelcontextprotocol/python-sdk/pull/2765/files
a77ebf3 Run SSE and Unicode transport tests in process instead of over sockets maxisbey Jun 2, 2026 https://github.com/modelcontextprotocol/python-sdk/pull/2765/commits/a77ebf37d9f4d4a30700f21a6c056a6a32486dd6
Clear filters https://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
test_http_unicode.py https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-1abfe619fb6ecef0087c7e77c14530625aee85ec1dc1db958de2f341769c21c9
test_sse.py https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-a2934f5f6ec610dff6774352c41b8c697b539614667643d69fd67f6fc6d7765e
tests/client/test_http_unicode.pyhttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-1abfe619fb6ecef0087c7e77c14530625aee85ec1dc1db958de2f341769c21c9
View file https://github.com/modelcontextprotocol/python-sdk/blob/a77ebf37d9f4d4a30700f21a6c056a6a32486dd6/tests/client/test_http_unicode.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/modelcontextprotocol/python-sdk/pull/2765/{{ revealButtonHref }}
https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-1abfe619fb6ecef0087c7e77c14530625aee85ec1dc1db958de2f341769c21c9
https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-1abfe619fb6ecef0087c7e77c14530625aee85ec1dc1db958de2f341769c21c9
https://github.com/modelcontextprotocol/python-sdk/pull/2765/files#diff-1abfe619fb6ecef0087c7e77c14530625aee85ec1dc1db958de2f341769c21c9
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
Please reload this pagehttps://github.com/modelcontextprotocol/python-sdk/pull/2765/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.