Skip to main content
Glama
pydantic

mcp-run-python

Official
by pydantic
test_exceptions.py3.41 kB
"""Tests for exception classes.""" from collections.abc import Callable from typing import Any import pytest from pydantic import ValidationError from pydantic_core import ErrorDetails from pydantic_ai import ModelRetry from pydantic_ai.exceptions import ( AgentRunError, ApprovalRequired, CallDeferred, IncompleteToolCall, ModelAPIError, ModelHTTPError, ToolRetryError, UnexpectedModelBehavior, UsageLimitExceeded, UserError, ) from pydantic_ai.messages import RetryPromptPart @pytest.mark.parametrize( 'exc_factory', [ lambda: ModelRetry('test'), lambda: CallDeferred(), lambda: ApprovalRequired(), lambda: UserError('test'), lambda: AgentRunError('test'), lambda: UnexpectedModelBehavior('test'), lambda: UsageLimitExceeded('test'), lambda: ModelAPIError('model', 'test message'), lambda: ModelHTTPError(500, 'model'), lambda: IncompleteToolCall('test'), lambda: ToolRetryError(RetryPromptPart(content='test', tool_name='test')), ], ids=[ 'ModelRetry', 'CallDeferred', 'ApprovalRequired', 'UserError', 'AgentRunError', 'UnexpectedModelBehavior', 'UsageLimitExceeded', 'ModelAPIError', 'ModelHTTPError', 'IncompleteToolCall', 'ToolRetryError', ], ) def test_exceptions_hashable(exc_factory: Callable[[], Any]): """Test that all exception classes are hashable and usable as keys.""" exc = exc_factory() # Does not raise TypeError _ = hash(exc) # Can be used in sets and dicts s = {exc} d = {exc: 'value'} assert exc in s assert d[exc] == 'value' def test_tool_retry_error_str_with_string_content(): """Test that ToolRetryError uses string content as message automatically.""" part = RetryPromptPart(content='error from tool', tool_name='my_tool') error = ToolRetryError(part) assert str(error) == 'error from tool' def test_tool_retry_error_str_with_error_details(): """Test that ToolRetryError formats ErrorDetails automatically.""" validation_error = ValidationError.from_exception_data( 'Test', [{'type': 'string_type', 'loc': ('name',), 'input': 123}] ) part = RetryPromptPart(content=validation_error.errors(include_url=False), tool_name='my_tool') error = ToolRetryError(part) assert str(error) == ( "1 validation error for 'my_tool'\nname\n Input should be a valid string [type=string_type, input_value=123]" ) def test_tool_retry_error_str_with_value_error_type(): """Test that ToolRetryError handles value_error type without ctx.error. When ErrorDetails are serialized, the exception object in ctx is stripped. This test ensures we handle error types that normally require ctx.error. """ # Simulate serialized ErrorDetails where ctx.error has been stripped error_details: list[ErrorDetails] = [ { 'type': 'value_error', 'loc': ('field',), 'msg': 'Value error, must not be foo', 'input': 'foo', } ] part = RetryPromptPart(content=error_details, tool_name='my_tool') error = ToolRetryError(part) assert str(error) == ( "1 validation error for 'my_tool'\nfield\n Value error, must not be foo [type=value_error, input_value='foo']" )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pydantic/pydantic-ai'

If you have feedback or need assistance with the MCP directory API, please join our Discord server