refactor: move inline imports to module level (#1893)
This commit is contained in:
parent
c06362126b
commit
5d80f4efc8
9 changed files with 58 additions and 122 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import urllib.parse
|
||||
import warnings
|
||||
|
||||
import jwt
|
||||
import pytest
|
||||
|
|
@ -60,8 +61,6 @@ def rfc7523_oauth_provider(client_metadata: OAuthClientMetadata, mock_storage: M
|
|||
"""Mock callback handler."""
|
||||
return "test_auth_code", "test_state"
|
||||
|
||||
import warnings
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
return RFC7523OAuthClientProvider(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Tests for refactored OAuth client authentication implementation.
|
|||
import base64
|
||||
import time
|
||||
from unittest import mock
|
||||
from urllib.parse import unquote
|
||||
from urllib.parse import parse_qs, quote, unquote, urlparse
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
|
@ -27,6 +27,8 @@ from mcp.client.auth.utils import (
|
|||
is_valid_client_metadata_url,
|
||||
should_use_client_metadata_url,
|
||||
)
|
||||
from mcp.server.auth.routes import build_metadata
|
||||
from mcp.server.auth.settings import ClientRegistrationOptions, RevocationOptions
|
||||
from mcp.shared.auth import (
|
||||
OAuthClientInformationFull,
|
||||
OAuthClientMetadata,
|
||||
|
|
@ -758,8 +760,6 @@ class TestProtectedResourceMetadata:
|
|||
content = request.content.decode()
|
||||
assert "resource=" in content
|
||||
# Check URL-encoded resource parameter
|
||||
from urllib.parse import quote
|
||||
|
||||
expected_resource = quote(oauth_provider.context.get_resource_url(), safe="")
|
||||
assert f"resource={expected_resource}" in content
|
||||
|
||||
|
|
@ -1226,8 +1226,6 @@ class TestAuthFlow:
|
|||
"%3A", ":"
|
||||
).replace("+", " ")
|
||||
# Extract state from redirect URL
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
parsed = urlparse(url)
|
||||
params = parse_qs(parsed.query)
|
||||
captured_state = params.get("state", [None])[0]
|
||||
|
|
@ -1336,9 +1334,6 @@ def test_build_metadata(
|
|||
registration_endpoint: str,
|
||||
revocation_endpoint: str,
|
||||
):
|
||||
from mcp.server.auth.routes import build_metadata
|
||||
from mcp.server.auth.settings import ClientRegistrationOptions, RevocationOptions
|
||||
|
||||
metadata = build_metadata(
|
||||
issuer_url=AnyHttpUrl(issuer_url),
|
||||
service_documentation_url=AnyHttpUrl(service_documentation_url),
|
||||
|
|
|
|||
|
|
@ -7,12 +7,20 @@ Verifies that Unicode text is correctly transmitted and received in both directi
|
|||
|
||||
import multiprocessing
|
||||
import socket
|
||||
from collections.abc import Generator
|
||||
from collections.abc import AsyncGenerator, Generator
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Mount
|
||||
|
||||
import mcp.types as types
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.client.streamable_http import streamable_http_client
|
||||
from mcp.server import Server
|
||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||
from mcp.types import TextContent, Tool
|
||||
from tests.test_helpers import wait_for_server
|
||||
|
||||
# Test constants with various Unicode characters
|
||||
|
|
@ -37,19 +45,7 @@ UNICODE_TEST_STRINGS = {
|
|||
|
||||
def run_unicode_server(port: int) -> None: # pragma: no cover
|
||||
"""Run the Unicode test server in a separate process."""
|
||||
# Import inside the function since this runs in a separate process
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import Any
|
||||
|
||||
import uvicorn
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Mount
|
||||
|
||||
import mcp.types as types
|
||||
from mcp.server import Server
|
||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||
from mcp.types import TextContent, Tool
|
||||
|
||||
# Need to recreate the server setup in this process
|
||||
server = Server(name="unicode_test_server")
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import pytest
|
|||
from pydantic import FileUrl
|
||||
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.server.fastmcp.server import Context
|
||||
from mcp.server.session import ServerSession
|
||||
from mcp.shared.context import RequestContext
|
||||
|
|
@ -13,8 +14,6 @@ from mcp.types import ListRootsResult, Root, TextContent
|
|||
|
||||
@pytest.mark.anyio
|
||||
async def test_list_roots_callback():
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
server = FastMCP("test")
|
||||
|
||||
callback_return = ListRootsResult(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Any, Literal
|
|||
import pytest
|
||||
|
||||
import mcp.types as types
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.shared.memory import (
|
||||
create_connected_server_and_client_session as create_session,
|
||||
)
|
||||
|
|
@ -23,8 +24,6 @@ class LoggingCollector:
|
|||
|
||||
@pytest.mark.anyio
|
||||
async def test_logging_callback():
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
server = FastMCP("test")
|
||||
logging_collector = LoggingCollector()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import inspect
|
||||
import logging
|
||||
from contextlib import contextmanager
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
import jsonschema
|
||||
import pytest
|
||||
|
||||
from mcp.server.lowlevel import Server
|
||||
|
|
@ -19,15 +21,11 @@ def bypass_server_output_validation():
|
|||
This simulates a malicious or non-compliant server that doesn't validate
|
||||
its outputs, allowing us to test client-side validation.
|
||||
"""
|
||||
import jsonschema
|
||||
|
||||
# Save the original validate function
|
||||
original_validate = jsonschema.validate
|
||||
|
||||
# Create a mock that tracks which module is calling it
|
||||
def selective_mock(instance: Any = None, schema: Any = None, *args: Any, **kwargs: Any) -> None:
|
||||
import inspect
|
||||
|
||||
# Check the call stack to see where this is being called from
|
||||
for frame_info in inspect.stack():
|
||||
# If called from the server module, skip validation
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.shared.context import RequestContext
|
||||
from mcp.shared.memory import (
|
||||
create_connected_server_and_client_session as create_session,
|
||||
|
|
@ -17,8 +18,6 @@ from mcp.types import (
|
|||
|
||||
@pytest.mark.anyio
|
||||
async def test_sampling_callback():
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
server = FastMCP("test")
|
||||
|
||||
callback_return = CreateMessageResult(
|
||||
|
|
@ -63,8 +62,6 @@ async def test_sampling_callback():
|
|||
@pytest.mark.anyio
|
||||
async def test_create_message_backwards_compat_single_content():
|
||||
"""Test backwards compatibility: create_message without tools returns single content."""
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
server = FastMCP("test")
|
||||
|
||||
# Callback returns single content (text)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import contextlib
|
||||
from unittest import mock
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
import mcp
|
||||
|
|
@ -356,8 +357,6 @@ class TestClientSessionGroup:
|
|||
assert isinstance(server_params_instance, StreamableHttpParameters)
|
||||
# Verify streamable_http_client was called with url, httpx_client, and terminate_on_close
|
||||
# The http_client is created by the real create_mcp_http_client
|
||||
import httpx
|
||||
|
||||
call_args = mock_specific_client_func.call_args
|
||||
assert call_args.kwargs["url"] == server_params_instance.url
|
||||
assert call_args.kwargs["terminate_on_close"] == server_params_instance.terminate_on_close
|
||||
|
|
|
|||
|
|
@ -10,7 +10,12 @@ import anyio
|
|||
import pytest
|
||||
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.client.stdio import StdioServerParameters, _create_platform_compatible_process, stdio_client
|
||||
from mcp.client.stdio import (
|
||||
StdioServerParameters,
|
||||
_create_platform_compatible_process,
|
||||
_terminate_process_tree,
|
||||
stdio_client,
|
||||
)
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.shared.message import SessionMessage
|
||||
from mcp.types import CONNECTION_CLOSED, JSONRPCMessage, JSONRPCRequest, JSONRPCResponse
|
||||
|
|
@ -312,8 +317,6 @@ class TestChildProcessCleanup:
|
|||
|
||||
# Terminate using our function
|
||||
print("Terminating process and children...")
|
||||
from mcp.client.stdio import _terminate_process_tree
|
||||
|
||||
await _terminate_process_tree(proc)
|
||||
|
||||
# Verify processes stopped
|
||||
|
|
@ -413,8 +416,6 @@ class TestChildProcessCleanup:
|
|||
assert new_size > initial_size, f"{name} process should be writing"
|
||||
|
||||
# Terminate the whole tree
|
||||
from mcp.client.stdio import _terminate_process_tree
|
||||
|
||||
await _terminate_process_tree(proc)
|
||||
|
||||
# Verify all stopped
|
||||
|
|
@ -494,8 +495,6 @@ class TestChildProcessCleanup:
|
|||
assert size2 > size1, "Child should be writing"
|
||||
|
||||
# Terminate - this will kill the process group even if parent exits first
|
||||
from mcp.client.stdio import _terminate_process_tree
|
||||
|
||||
await _terminate_process_tree(proc)
|
||||
|
||||
# Verify child stopped
|
||||
|
|
|
|||
Loading…
Reference in a new issue