diff --git a/python/packages/ag-ui/tests/ag_ui/test_helpers.py b/python/packages/ag-ui/tests/ag_ui/test_helpers.py index 7173f5c6b3..bfcea08afc 100644 --- a/python/packages/ag-ui/tests/ag_ui/test_helpers.py +++ b/python/packages/ag-ui/tests/ag_ui/test_helpers.py @@ -2,6 +2,8 @@ """Tests for orchestration helper functions.""" +from typing import Any + from agent_framework import Content, Message from agent_framework_ag_ui._orchestration._helpers import ( @@ -137,13 +139,13 @@ def test_creates_new_entry(self): def test_returns_existing_entry(self): """Returns existing entry when ID found.""" - existing_entry = { + existing_entry: dict[str, Any] = { "id": "call_123", "type": "function", "function": {"name": "get_weather", "arguments": '{"city": "NYC"}'}, } - tool_calls_by_id = {"call_123": existing_entry} - pending_tool_calls: list = [] + tool_calls_by_id: dict[str, dict[str, Any]] = {"call_123": existing_entry} + pending_tool_calls: list[dict[str, Any]] = [] entry = ensure_tool_call_entry("call_123", tool_calls_by_id, pending_tool_calls) diff --git a/python/packages/azurefunctions/tests/test_orchestration.py b/python/packages/azurefunctions/tests/test_orchestration.py index 385d66c387..ec387f60f1 100644 --- a/python/packages/azurefunctions/tests/test_orchestration.py +++ b/python/packages/azurefunctions/tests/test_orchestration.py @@ -90,7 +90,7 @@ def executor_with_uuid() -> tuple[Any, Mock, str]: executor = AzureFunctionsAgentExecutor(context) test_uuid_hex = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" - executor.generate_unique_id = Mock(return_value=test_uuid_hex) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + executor.generate_unique_id = Mock(return_value=test_uuid_hex) # type: ignore[method-assign] return executor, context, test_uuid_hex @@ -112,7 +112,7 @@ def executor_with_multiple_uuids() -> tuple[Any, Mock, list[str]]: "dddddddd-dddd-dddd-dddd-dddddddddddd", "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", ] - executor.generate_unique_id = Mock(side_effect=uuid_hexes) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + executor.generate_unique_id = Mock(side_effect=uuid_hexes) # type: ignore[method-assign] return executor, context, uuid_hexes diff --git a/python/packages/core/tests/core/test_embedding_client.py b/python/packages/core/tests/core/test_embedding_client.py index b2e6aead21..2de74b886a 100644 --- a/python/packages/core/tests/core/test_embedding_client.py +++ b/python/packages/core/tests/core/test_embedding_client.py @@ -24,9 +24,9 @@ async def get_embeddings( *, options: EmbeddingGenerationOptions | None = None, ) -> GeneratedEmbeddings[list[float]]: - return GeneratedEmbeddings( # ty: ignore[invalid-return-type] + return GeneratedEmbeddings( [Embedding(vector=[0.1, 0.2, 0.3], model="mock-model") for _ in values], - usage={"prompt_tokens": len(values), "total_tokens": len(values)}, # type: ignore[arg-type] # ty: ignore[invalid-argument-type, invalid-key] + usage={"prompt_tokens": len(values), "total_tokens": len(values)}, # type: ignore[arg-type] ) @@ -52,7 +52,7 @@ async def test_base_get_embeddings_usage() -> None: client = MockEmbeddingClient() result = await client.get_embeddings(["a", "b", "c"]) assert result.usage is not None - assert result.usage["prompt_tokens"] == 3 # type: ignore[typeddict-item] # ty: ignore[invalid-key] + assert result.usage["prompt_tokens"] == 3 # type: ignore[typeddict-item] def test_base_additional_properties_default() -> None: diff --git a/python/packages/core/tests/core/test_embedding_types.py b/python/packages/core/tests/core/test_embedding_types.py index 2e2a23f68d..c49ff9ca2a 100644 --- a/python/packages/core/tests/core/test_embedding_types.py +++ b/python/packages/core/tests/core/test_embedding_types.py @@ -102,7 +102,7 @@ def test_generated_construction_with_usage() -> None: usage=usage, # type: ignore[arg-type] # ty: ignore[invalid-argument-type] ) assert embeddings.usage == usage - assert embeddings.usage["prompt_tokens"] == 10 # type: ignore[index, typeddict-item] # pyrefly: ignore[unsupported-operation] # ty: ignore[invalid-key, not-subscriptable] + assert embeddings.usage["prompt_tokens"] == 10 # type: ignore[index, typeddict-item] # pyrefly: ignore[unsupported-operation] # ty: ignore[not-subscriptable] def test_generated_construction_with_additional_properties() -> None: diff --git a/python/packages/core/tests/core/test_mcp.py b/python/packages/core/tests/core/test_mcp.py index c9322101f7..ca45da484c 100644 --- a/python/packages/core/tests/core/test_mcp.py +++ b/python/packages/core/tests/core/test_mcp.py @@ -1833,8 +1833,8 @@ async def test_mcp_tool_message_handler_notification(): tool = MCPStdioTool(name="test_tool", command="python") # Mock the load_tools and load_prompts methods - tool.load_tools = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] - tool.load_prompts = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.load_tools = AsyncMock() # type: ignore[method-assign] + tool.load_prompts = AsyncMock() # type: ignore[method-assign] # Test tools list changed notification tools_notification = Mock(spec=types.ServerNotification) @@ -1845,10 +1845,10 @@ async def test_mcp_tool_message_handler_notification(): assert result is None # The reload is scheduled as a background task; let it run. await asyncio.sleep(0) - tool.load_tools.assert_called_once() # ty: ignore[unresolved-attribute] + tool.load_tools.assert_called_once() # Reset mock - tool.load_tools.reset_mock() # ty: ignore[unresolved-attribute] + tool.load_tools.reset_mock() # Test prompts list changed notification prompts_notification = Mock(spec=types.ServerNotification) @@ -1858,7 +1858,7 @@ async def test_mcp_tool_message_handler_notification(): result = await tool.message_handler(prompts_notification) # type: ignore[func-returns-value] assert result is None await asyncio.sleep(0) - tool.load_prompts.assert_called_once() # ty: ignore[unresolved-attribute] + tool.load_prompts.assert_called_once() # Test unhandled notification unknown_notification = Mock(spec=types.ServerNotification) @@ -1924,7 +1924,7 @@ async def slow_load_tools(): async def test_mcp_tool_message_handler_reload_failure_is_logged(caplog: pytest.LogCaptureFixture): """Background reload errors are logged, not raised into the receive loop.""" tool = MCPStdioTool(name="test_tool", command="python") - tool.load_tools = AsyncMock(side_effect=RuntimeError("connection lost")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.load_tools = AsyncMock(side_effect=RuntimeError("connection lost")) # type: ignore[method-assign] tools_notification = Mock(spec=types.ServerNotification) tools_notification.root = Mock() @@ -1936,7 +1936,7 @@ async def test_mcp_tool_message_handler_reload_failure_is_logged(caplog: pytest. pending = list(tool._pending_reload_tasks) if pending: await asyncio.wait_for(asyncio.gather(*pending, return_exceptions=True), timeout=1) - tool.load_tools.assert_called_once() # ty: ignore[unresolved-attribute] + tool.load_tools.assert_called_once() assert len(tool._pending_reload_tasks) == 0 # Verify the warning was actually logged with exception info. @@ -2627,7 +2627,7 @@ async def test_connect_sampling_capabilities_with_client(): mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session = AsyncMock() @@ -2657,7 +2657,7 @@ async def test_connect_no_sampling_capabilities_without_client(): mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session = AsyncMock() @@ -2686,7 +2686,7 @@ async def test_connect_session_creation_failure(): mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # Mock ClientSession to raise an exception with patch("mcp.client.session.ClientSession") as mock_session_class: @@ -2709,7 +2709,7 @@ async def test_connect_initialization_failure_http_no_command(): mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # Mock successful session creation but failed initialization mock_session = Mock() @@ -2732,28 +2732,28 @@ async def test_connect_cleanup_on_transport_failure(): tool = MCPStdioTool(name="test", command="test-command") # Mock _exit_stack.aclose to verify it's called - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # Mock get_mcp_client to raise an exception - tool.get_mcp_client = Mock(side_effect=RuntimeError("Transport failed")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(side_effect=RuntimeError("Transport failed")) # type: ignore[method-assign] with pytest.raises(ToolException): await tool.connect() # Verify cleanup was called - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_connect_cleanup_on_transport_failure_http_uses_generic_message(): """Test HTTP transport failures use the generic connection message when no command exists.""" tool = MCPStreamableHTTPTool(name="test", url="https://example.com/mcp") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] - tool.get_mcp_client = Mock(side_effect=RuntimeError("Transport failed")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] + tool.get_mcp_client = Mock(side_effect=RuntimeError("Transport failed")) # type: ignore[method-assign] with pytest.raises(ToolException, match="Failed to connect to MCP server: Transport failed"): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_connect_cleanup_on_initialization_failure(): @@ -2761,14 +2761,14 @@ async def test_connect_cleanup_on_initialization_failure(): tool = MCPStdioTool(name="test", command="test-command") # Mock _exit_stack.aclose to verify it's called - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # Mock successful transport creation mock_transport = (Mock(), Mock()) mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # Mock successful session creation but failed initialization mock_session = Mock() @@ -2782,31 +2782,31 @@ async def test_connect_cleanup_on_initialization_failure(): await tool.connect() # Verify cleanup was called - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_connect_cancelled_error_during_transport_creation_raises_tool_exception(): """Test that CancelledError from transport creation is wrapped in ToolException.""" tool = MCPStreamableHTTPTool(name="test", url="http://example.com") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] - tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("cancel scope")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] + tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("cancel scope")) # type: ignore[method-assign] with pytest.raises(ToolException, match="Failed to connect to MCP server"): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_connect_cancelled_error_during_transport_creation_stdio_raises_tool_exception(): """Test that CancelledError from transport creation uses the command-specific message for MCPStdioTool.""" tool = MCPStdioTool(name="test", command="my-server") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] - tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("cancel scope")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] + tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("cancel scope")) # type: ignore[method-assign] with pytest.raises(ToolException, match="Failed to start MCP server 'my-server'"): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_connect_cancelled_error_during_session_creation_raises_tool_exception(): @@ -2817,7 +2817,7 @@ async def test_connect_cancelled_error_during_session_creation_raises_tool_excep mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session_class.return_value.__aenter__ = AsyncMock(side_effect=asyncio.CancelledError("cancel scope")) @@ -2840,7 +2840,7 @@ async def test_connect_cancelled_error_during_initialize_raises_tool_exception() mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] mock_session = Mock() mock_session.initialize = AsyncMock(side_effect=asyncio.CancelledError("Cancelled via cancel scope")) @@ -2861,7 +2861,7 @@ async def test_connect_cancelled_error_during_initialize_stdio_raises_tool_excep mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] mock_session = Mock() mock_session.initialize = AsyncMock(side_effect=asyncio.CancelledError("Cancelled via cancel scope")) @@ -2878,30 +2878,30 @@ async def test_connect_cancelled_error_during_initialize_stdio_raises_tool_excep async def test_connect_genuine_cancellation_during_transport_creation_propagates(): """Test that genuine task cancellation (task.cancelling() > 0) propagates as CancelledError.""" tool = MCPStreamableHTTPTool(name="test", url="http://example.com") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] mock_cancelled_task = Mock() mock_cancelled_task.cancelling.return_value = 1 with patch("asyncio.current_task", return_value=mock_cancelled_task): - tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("task cancelled")) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(side_effect=asyncio.CancelledError("task cancelled")) # type: ignore[method-assign] with pytest.raises(asyncio.CancelledError): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() @pytest.mark.skipif(sys.version_info < (3, 11), reason="task.cancelling() requires Python >= 3.11") async def test_connect_genuine_cancellation_during_initialize_propagates(): """Test that genuine task cancellation during initialize() propagates as CancelledError.""" tool = MCPStreamableHTTPTool(name="test", url="http://example.com") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] mock_transport = (Mock(), Mock()) mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] mock_session = Mock() mock_session.initialize = AsyncMock(side_effect=asyncio.CancelledError("task cancelled")) @@ -2919,20 +2919,20 @@ async def test_connect_genuine_cancellation_during_initialize_propagates(): with pytest.raises(asyncio.CancelledError): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() @pytest.mark.skipif(sys.version_info < (3, 11), reason="task.cancelling() requires Python >= 3.11") async def test_connect_genuine_cancellation_during_session_creation_propagates(): """Test that genuine task cancellation during session creation propagates as CancelledError.""" tool = MCPStreamableHTTPTool(name="test", url="http://example.com") - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] mock_transport = (Mock(), Mock()) mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] mock_cancelled_task = Mock() mock_cancelled_task.cancelling.return_value = 1 @@ -2947,7 +2947,7 @@ async def test_connect_genuine_cancellation_during_session_creation_propagates() with pytest.raises(asyncio.CancelledError): await tool.connect() - tool._exit_stack.aclose.assert_called_once() # ty: ignore[unresolved-attribute] + tool._exit_stack.aclose.assert_called_once() async def test_aenter_cancelled_error_during_connect_is_catchable_as_exception(): @@ -2965,7 +2965,7 @@ async def test_aenter_cancelled_error_during_connect_is_catchable_as_exception() mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session_class.return_value.__aenter__ = AsyncMock(return_value=mock_session) @@ -3018,7 +3018,7 @@ async def test_connect_cancelled_error_during_session_creation_includes_exceptio mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session_class.return_value.__aenter__ = AsyncMock( @@ -3041,7 +3041,7 @@ async def test_connect_cancelled_error_during_session_creation_logs_with_exc_inf mock_context_manager = Mock() mock_context_manager.__aenter__ = AsyncMock(return_value=mock_transport) mock_context_manager.__aexit__ = AsyncMock(return_value=None) - tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool.get_mcp_client = Mock(return_value=mock_context_manager) # type: ignore[method-assign] with patch("mcp.client.session.ClientSession") as mock_session_class: mock_session_class.return_value.__aenter__ = AsyncMock(side_effect=asyncio.CancelledError("cancel scope")) @@ -3864,7 +3864,7 @@ async def test_mcp_tool_connection_properly_invalidated_after_closed_resource_er # Mock _exit_stack.aclose to track cleanup calls original_exit_stack = tool._exit_stack - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # Mock connect() to avoid trying to start actual process with patch.object(tool, "connect", new_callable=AsyncMock) as mock_connect: @@ -3963,7 +3963,7 @@ async def test_mcp_tool_get_prompt_reconnection_on_closed_resource_error(): # Mock _exit_stack.aclose to track cleanup calls original_exit_stack = tool._exit_stack - tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # ty: ignore[invalid-assignment] + tool._exit_stack.aclose = AsyncMock() # type: ignore[method-assign] # Mock connect() to avoid trying to start actual process with patch.object(tool, "connect", new_callable=AsyncMock) as mock_connect: @@ -5566,7 +5566,7 @@ def _send_request_dispatcher(*responses_by_method: tuple[str, Any]) -> Any: async def _dispatch(request: Any, _result_type: Any, *_args: Any, **_kw: Any) -> Any: method = getattr(request.root, "method", None) or getattr(request, "method", None) - queue = queues.get(method) # type: ignore[arg-type, call-overload] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-argument-type] + queue = queues.get(method) # type: ignore[arg-type, call-overload] # pyrefly: ignore[bad-argument-type] if not queue: raise AssertionError(f"No mocked send_request response for method '{method}'.") item = queue.pop(0) diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index 19c77585e4..ab5fd4dc22 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -572,35 +572,35 @@ def test_usage_details_addition(): input_token_count=5, output_token_count=10, total_token_count=15, - test1=10, # ty: ignore[invalid-key] - test2=20, # ty: ignore[invalid-key] + test1=10, + test2=20, ) usage2 = UsageDetails( # type: ignore[typeddict-unknown-key] input_token_count=3, output_token_count=6, total_token_count=9, - test1=10, # ty: ignore[invalid-key] - test3=30, # ty: ignore[invalid-key] + test1=10, + test3=30, ) combined_usage = add_usage_details(usage1, usage2) assert combined_usage["input_token_count"] == 8 assert combined_usage["output_token_count"] == 16 assert combined_usage["total_token_count"] == 24 - assert combined_usage["test1"] == 20 # type: ignore[typeddict-item] # ty: ignore[invalid-key] - assert combined_usage["test2"] == 20 # type: ignore[typeddict-item] # ty: ignore[invalid-key] - assert combined_usage["test3"] == 30 # type: ignore[typeddict-item] # ty: ignore[invalid-key] + assert combined_usage["test1"] == 20 # type: ignore[typeddict-item] + assert combined_usage["test2"] == 20 # type: ignore[typeddict-item] + assert combined_usage["test3"] == 30 # type: ignore[typeddict-item] def test_usage_details_fail(): # TypedDict doesn't validate types at runtime, so this test no longer applies # Creating UsageDetails with wrong types won't raise ValueError - usage = UsageDetails(input_token_count=5, output_token_count=10, total_token_count=15, wrong_type="42.923") # type: ignore[typeddict-item, typeddict-unknown-key] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-key] - assert usage["wrong_type"] == "42.923" # type: ignore[typeddict-item] # ty: ignore[invalid-key] + usage = cast(UsageDetails, {"input_token_count": 5, "output_token_count": 10, "total_token_count": 15, "wrong_type": "42.923"}) + assert usage["wrong_type"] == "42.923" # type: ignore[typeddict-item] def test_usage_details_additional_counts(): - usage = UsageDetails(input_token_count=5, output_token_count=10, total_token_count=15, **{"test": 1}) # type: ignore[call-arg, typeddict-unknown-key] # ty: ignore[invalid-key] + usage = UsageDetails(input_token_count=5, output_token_count=10, total_token_count=15, **{"test": 1}) # type: ignore[call-arg, typeddict-unknown-key] assert usage.get("test") == 1 @@ -616,8 +616,8 @@ def test_usage_details_add_with_none_and_type_errors(): def test_usage_details_add_skips_non_int(): - u1 = UsageDetails(input_token_count=10, other="test") # type: ignore[typeddict-item, typeddict-unknown-key] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-key] - u2 = UsageDetails(input_token_count=10, another="test") # type: ignore[typeddict-item, typeddict-unknown-key] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-key] + u1 = cast(UsageDetails, {"input_token_count": 10, "other": "test"}) + u2 = cast(UsageDetails, {"input_token_count": 10, "another": "test"}) u3 = add_usage_details(u1, u2) assert len(u3.keys()) == 1 assert "input_token_count" in u3 @@ -1758,9 +1758,9 @@ def test_comprehensive_to_dict_exclude_options(): assert "text" in text_dict_exclude # Test UsageDetails - it's a TypedDict now, not a class with to_dict - usage = UsageDetails(input_token_count=5, custom_count=10) # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] + usage = UsageDetails(input_token_count=5, custom_count=10) # type: ignore[typeddict-unknown-key] assert usage["input_token_count"] == 5 - assert usage["custom_count"] == 10 # type: ignore[typeddict-item] # ty: ignore[invalid-key] + assert usage["custom_count"] == 10 # type: ignore[typeddict-item] # Test UsageDetails exclude_none behavior isn't applicable to TypedDict # TypedDict doesn't have a to_dict method @@ -1769,8 +1769,8 @@ def test_comprehensive_to_dict_exclude_options(): def test_usage_details_iadd_edge_cases(): """Test UsageDetails addition with edge cases for better coverage.""" # Test with None values - u1 = UsageDetails(input_token_count=None, output_token_count=5, custom1=10) # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] - u2 = UsageDetails(input_token_count=3, output_token_count=None, custom2=20) # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] + u1 = UsageDetails(input_token_count=None, output_token_count=5, custom1=10) # type: ignore[typeddict-unknown-key] + u2 = UsageDetails(input_token_count=3, output_token_count=None, custom2=20) # type: ignore[typeddict-unknown-key] result = add_usage_details(u1, u2) assert result["input_token_count"] == 3 @@ -1779,8 +1779,8 @@ def test_usage_details_iadd_edge_cases(): assert result.get("custom2") == 20 # Test merging additional counts - u3 = UsageDetails(input_token_count=1, shared_count=5) # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] - u4 = UsageDetails(input_token_count=2, shared_count=15) # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] + u3 = UsageDetails(input_token_count=1, shared_count=5) # type: ignore[typeddict-unknown-key] + u4 = UsageDetails(input_token_count=2, shared_count=15) # type: ignore[typeddict-unknown-key] result2 = add_usage_details(u3, u4) assert result2["input_token_count"] == 3 @@ -2013,7 +2013,7 @@ def test_usage_content_serialization_with_details(): usage_content = Content(**usage_data) # type: ignore[arg-type] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-argument-type] assert isinstance(usage_content.usage_details, dict) assert usage_content.usage_details["input_token_count"] == 10 - assert usage_content.usage_details["custom_count"] == 5 # type: ignore[typeddict-item] # ty: ignore[invalid-argument-type, invalid-key] # Custom fields go directly in UsageDetails + assert usage_content.usage_details["custom_count"] == 5 # type: ignore[typeddict-item] # Custom fields go directly in UsageDetails # Test to_dict with UsageDetails object usage_dict = usage_content.to_dict() @@ -2692,6 +2692,7 @@ def test_text_content_with_annotations_serialization(): # Verify reconstruction assert len(reconstructed.annotations) == 2 # type: ignore[arg-type] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-argument-type] + assert reconstructed.annotations is not None # Annotation are TypedDicts (dicts at runtime) assert all(isinstance(ann, dict) for ann in reconstructed.annotations) # type: ignore[union-attr] # pyrefly: ignore[not-iterable] assert reconstructed.annotations[0]["title"] == "Citation 1" # type: ignore[index] # pyrefly: ignore[unsupported-operation] @@ -3039,19 +3040,20 @@ def test_content_add_usage_content_non_integer_values(): """Test adding usage content with non-integer values.""" usage1 = Content( type="usage", - usage_details={"model": "gpt-4", "count": 10}, # type: ignore[arg-type, typeddict-item] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-argument-type, invalid-key] + usage_details=cast(UsageDetails, {"model": "gpt-4", "count": 10}), ) usage2 = Content( type="usage", - usage_details={"model": "gpt-3.5", "count": 20}, # type: ignore[arg-type, typeddict-item] # pyrefly: ignore[bad-argument-type] # ty: ignore[invalid-argument-type, invalid-key] + usage_details=cast(UsageDetails, {"model": "gpt-3.5", "count": 20}), ) result = usage1 + usage2 # Non-integer "model" should take first non-None value - assert "model" not in result.usage_details # type: ignore[operator] # pyrefly: ignore[not-iterable] # ty: ignore[unsupported-operator] + assert result.usage_details is not None + assert "model" not in result.usage_details # type: ignore[operator] # pyrefly: ignore[not-iterable] # Integer "count" should be summed - assert result.usage_details["count"] == 30 # type: ignore[index, typeddict-item] # pyrefly: ignore[unsupported-operation] # ty: ignore[invalid-key, not-subscriptable] + assert result.usage_details["count"] == 30 # type: ignore[index, typeddict-item] # pyrefly: ignore[unsupported-operation] # endregion diff --git a/python/packages/durabletask/tests/test_durable_agent_state.py b/python/packages/durabletask/tests/test_durable_agent_state.py index 62f0522779..d3a36c9a7e 100644 --- a/python/packages/durabletask/tests/test_durable_agent_state.py +++ b/python/packages/durabletask/tests/test_durable_agent_state.py @@ -344,8 +344,8 @@ def test_usage_from_usage_details_with_extension_fields(self) -> None: "total_token_count": 300, } # Add provider-specific fields (UsageDetails is a TypedDict but allows extra keys) - usage_details["prompt_tokens"] = 100 # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] - usage_details["completion_tokens"] = 200 # type: ignore[typeddict-unknown-key] # ty: ignore[invalid-key] + usage_details["prompt_tokens"] = 100 # type: ignore[typeddict-unknown-key] + usage_details["completion_tokens"] = 200 # type: ignore[typeddict-unknown-key] usage = DurableAgentStateUsage.from_usage(usage_details) diff --git a/python/packages/foundry_hosting/tests/test_toolbox.py b/python/packages/foundry_hosting/tests/test_toolbox.py index c9a1391ad3..b378a627fc 100644 --- a/python/packages/foundry_hosting/tests/test_toolbox.py +++ b/python/packages/foundry_hosting/tests/test_toolbox.py @@ -145,14 +145,14 @@ async def test_close_closes_owned_http_client() -> None: ) client = toolbox._httpx_client # pyright: ignore[reportPrivateUsage] assert client is not None - client.aclose = AsyncMock() # ty: ignore # zuban: ignore + client.aclose = AsyncMock() # zuban: ignore await toolbox.close() - client.aclose.assert_awaited_once() # ty: ignore + client.aclose.assert_awaited_once() # Idempotent: a second close does not re-close the client. await toolbox.close() - client.aclose.assert_awaited_once() # ty: ignore + client.aclose.assert_awaited_once() def test_as_skills_provider_returns_provider() -> None: diff --git a/python/packages/ollama/tests/test_ollama_chat_client.py b/python/packages/ollama/tests/test_ollama_chat_client.py index 130102da27..f50a5803ea 100644 --- a/python/packages/ollama/tests/test_ollama_chat_client.py +++ b/python/packages/ollama/tests/test_ollama_chat_client.py @@ -518,7 +518,7 @@ async def test_cmc_with_invalid_data_content_media_type( ) ollama_client = OllamaChatClient() - ollama_client.client.chat = AsyncMock(return_value=mock_streaming_chat_completion_response) # type: ignore[method-assign] # ty: ignore[invalid-assignment] + ollama_client.client.chat = AsyncMock(return_value=mock_streaming_chat_completion_response) # type: ignore[method-assign] await ollama_client.get_response(messages=chat_history) diff --git a/python/pyproject.toml b/python/pyproject.toml index aa204d33d2..c9803b1eb7 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -40,7 +40,7 @@ dev = [ "mypy==1.20.0", "pyright==1.1.410", "pyrefly==1.0.0", - "ty==0.0.46", + "ty==0.0.55", "zuban==0.8.2", "mcp[ws]==1.27.2", "opentelemetry-sdk==1.40.0",