Skip to content

Commit

Permalink
feat: ensure we can evaluate same queryset twice without false positives
Browse files Browse the repository at this point in the history
  • Loading branch information
taobojlen committed Jul 2, 2024
1 parent 1b10952 commit 5e8ea3a
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 4 deletions.
4 changes: 2 additions & 2 deletions hooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh

make format-check
make typecheck
make format-check || exit 1
make typecheck || exit 1

2 changes: 1 addition & 1 deletion hooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

make test
make test || exit 1
3 changes: 2 additions & 1 deletion src/queryspy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from .errors import NPlusOneError, QuerySpyError
from .listeners import queryspy_context, setup, teardown
from .listeners import queryspy_context, queryspy_ignore, setup, teardown

__all__ = [
"QuerySpyError",
"NPlusOneError",
"setup",
"teardown",
"queryspy_context",
"queryspy_ignore",
]
9 changes: 9 additions & 0 deletions src/queryspy/listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ def queryspy_context():
finally:
n_plus_one_listener.reset()
_is_in_context.reset(token)


@contextmanager
def queryspy_ignore():
token = _is_in_context.set(False)
try:
yield
finally:
_is_in_context.reset(token)
13 changes: 13 additions & 0 deletions tests/test_nplusones.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import re

import pytest
from django.db import connection
from django.test.utils import CaptureQueriesContext
from djangoproject.social.models import Post, Profile, User
from queryspy import NPlusOneError, queryspy_context

Expand Down Expand Up @@ -39,6 +41,17 @@ def test_detects_nplusone_in_reverse_many_to_one():
_ = list(user.posts.all())


def test_no_false_positive_when_calling_reverse_many_to_one_twice():
user = UserFactory.create()
PostFactory.create(author=user)

with queryspy_context(), CaptureQueriesContext(connection) as ctx:
queryset = user.posts.all()
list(queryset) # evaluate queryset once
list(queryset) # evalute again (cached)
assert len(ctx.captured_queries) == 1


@queryspy_context()
def test_detects_nplusone_in_forward_one_to_one():
[user_1, user_2] = UserFactory.create_batch(2)
Expand Down

0 comments on commit 5e8ea3a

Please sign in to comment.