Skip to content

Add SpyType protocol to expose spy attributes for type checking#572

Open
BlocksecPHD wants to merge 2 commits intopytest-dev:mainfrom
BlocksecPHD:fix-spy-type-annotations
Open

Add SpyType protocol to expose spy attributes for type checking#572
BlocksecPHD wants to merge 2 commits intopytest-dev:mainfrom
BlocksecPHD:fix-spy-type-annotations

Conversation

@BlocksecPHD
Copy link
Copy Markdown

Summary

The Spy type definition previously didn't include the extra attributes (spy_return, spy_return_list, spy_return_iter, spy_exception) that are added at runtime by the spy() method. This broke autocomplete and type checking for users.

This PR introduces a new SpyType protocol that:

  • Defines the spy-specific attributes with proper type annotations
  • Includes common mock assertion methods for full mock interface
  • Uses runtime_checkable decorator for isinstance support
  • Is exported from pytest_mock module for easy import

The spy() method now returns SpyType instead of MockType, enabling proper type inference and autocomplete in IDEs.

Changes

  1. Added SpyType protocol in src/pytest_mock/plugin.py with:

    • spy_return: Any
    • spy_return_list: list[Any]
    • spy_return_iter: Optional[Iterator[Any]]
    • spy_exception: Optional[BaseException]
    • Mock assertion methods (assert_called, assert_called_once, etc.)
    • Mock properties (call_count, call_args, call_args_list, called)
  2. Updated spy() method to return SpyType

  3. Exported SpyType from src/pytest_mock/__init__.py

  4. Added comprehensive tests in tests/test_spy_type_annotations.py

Example Usage

Before (required type: ignore comments):

spy = mocker.spy(Foo, "bar")
result = spy.spy_return  # type: ignore[attr-defined]

After (type checker recognizes attributes):

from pytest_mock import SpyType

spy: SpyType = mocker.spy(Foo, "bar")
result = spy.spy_return  # No type: ignore needed!

Testing

All existing spy tests pass. New test file verifies:

  • SpyType is properly exported
  • All spy attributes are defined with correct types
  • spy() method returns SpyType
  • Mock methods are available on SpyType

Fixes #547

Funan Zhou and others added 2 commits April 10, 2026 06:13
The Spy type definition previously didn't include the extra attributes
(spy_return, spy_return_list, spy_return_iter, spy_exception) that are
added at runtime by the spy() method. This broke autocomplete and type
checking for users.

This change introduces a new SpyType protocol that:
- Defines the spy-specific attributes with proper type annotations
- Includes common mock assertion methods for full mock interface
- Uses runtime_checkable decorator for isinstance support
- Is exported from pytest_mock module for easy import

The spy() method now returns SpyType instead of MockType, enabling
proper type inference and autocomplete in IDEs.

Fixes pytest-dev#547
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spy type is missing extra attributes

1 participant