Skip to content

fix(typing): add missing type annotations for assertNumQueries and non_debugging_runtest - #1294

Open
atiqur-rahman-pro wants to merge 1 commit into
pytest-dev:mainfrom
atiqur-rahman-pro:fix/type-annotations-asserts-plugin
Open

fix(typing): add missing type annotations for assertNumQueries and non_debugging_runtest#1294
atiqur-rahman-pro wants to merge 1 commit into
pytest-dev:mainfrom
atiqur-rahman-pro:fix/type-annotations-asserts-plugin

Conversation

@atiqur-rahman-pro

Copy link
Copy Markdown

…n_debugging_runtest

This PR fixes missing type annotations identified during strict type checking:

  • pytest_django/asserts.py: Added missing parameter (func: Callable[..., Any] | None = ...) and return type (-> AbstractContextManager[None] | None) annotations to the assertNumQueries overload implementation.
  • pytest_django/plugin.py: Added explicit type annotation (self: TestCaseFunction) for non_debugging_runtest parameter and removed unnecessary noqa: ANN001.

All mypy strict checks pass cleanly.

@kingbuzzman

Copy link
Copy Markdown
Member

While the change looks good on the surface, can you provide an example where it was failing? (real world use case?)

@atiqur-rahman-pro

atiqur-rahman-pro commented Aug 3, 2026

Copy link
Copy Markdown
Author

Hi @kingbuzzman,

Thanks for reviewing! The primary use case occurs when running Mypy in strict mode (mypy --strict / --disallow-untyped-defs) on downstream user codebases or type-checked pytest plugins.

Real-world Example

Consider a Django project configured with strict = true in pyproject.toml or mypy.ini:

# tests/test_queries.py
import pytest
from pytest_django.asserts import assertNumQueries
from myapp.models import User

def test_user_query_count() -> None:
    # 1. Context manager usage with strict typing
    with assertNumQueries(2):
        User.objects.filter(is_active=True).count()

    # 2. Callable invocation usage
    assertNumQueries(1, lambda: User.objects.get(id=1)) 

Mypy Error Output:

error: Function is missing a type annotation for parameter "func"  [no-untyped-def]
error: Function is missing a return type annotation  [no-untyped-def]

@bluetech bluetech left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for trying to improve this.

Regarding the assertNumQueries, if we want to be completely accurate we need to do something like django-stubs: https://github.com/typeddjango/django-stubs/blob/61a3af749523e9645861057588fe67230ac6b6dd/django-stubs/test/testcases.pyi#L176-L181. But that's somewhat complex, so I punted it. But AbstractContextManager[Any] would side-step the main complexity and still be an improvement.

The non_debugging_runtest looks good.

Comment thread pytest_django/asserts.py
def assertNumQueries(
num: int,
func=...,
func: Callable[..., Any] | None = ...,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an @overload rather than a param with default.

Comment thread pytest_django/asserts.py
using: str = ...,
**kwargs: Any,
): ...
) -> AbstractContextManager[None] | None: ...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context manager is not exactly None, it actually returns itself. So Any would be better for now.

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.

3 participants