test_plugin.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. from __future__ import annotations
  2. import pathlib
  3. import subprocess
  4. import sys
  5. from typing import Callable
  6. import pytest
  7. @pytest.fixture
  8. def call_mypy(tmp_path: pathlib.Path) -> Callable[[str], tuple[int, str]]:
  9. cfg = """\
  10. [tool.mypy]
  11. plugins = ["tools.mypy_helpers.plugin"]
  12. """
  13. cfg_path = tmp_path.joinpath("mypy.toml")
  14. cfg_path.write_text(cfg)
  15. def _call_mypy(contents: str) -> tuple[int, str]:
  16. ret = subprocess.run(
  17. (
  18. *(sys.executable, "-m", "mypy"),
  19. *("--config", str(cfg_path)),
  20. *("-c", contents),
  21. ),
  22. capture_output=True,
  23. encoding="UTF-8",
  24. )
  25. return ret.returncode, ret.stdout
  26. return _call_mypy
  27. def test_invalid_get_connection_call(call_mypy):
  28. code = """
  29. from django.db.transaction import get_connection
  30. with get_connection() as cursor:
  31. cursor.execute("SELECT 1")
  32. """
  33. expected = """\
  34. <string>:4: error: Missing positional argument "using" in call to "get_connection" [call-arg]
  35. Found 1 error in 1 file (checked 1 source file)
  36. """
  37. ret, out = call_mypy(code)
  38. assert ret
  39. assert out == expected
  40. def test_ok_get_connection(call_mypy):
  41. code = """
  42. from django.db.transaction import get_connection
  43. with get_connection("default") as cursor:
  44. cursor.execute("SELECT 1")
  45. """
  46. ret, out = call_mypy(code)
  47. assert ret == 0
  48. def test_invalid_transaction_atomic(call_mypy):
  49. code = """
  50. from django.db import transaction
  51. with transaction.atomic():
  52. value = 10 / 2
  53. """
  54. expected = """\
  55. <string>:4: error: All overload variants of "atomic" require at least one argument [call-overload]
  56. <string>:4: note: Possible overload variants:
  57. <string>:4: note: def [_C] atomic(using: _C) -> _C
  58. <string>:4: note: def atomic(using: str, savepoint: bool = ..., durable: bool = ...) -> Atomic
  59. Found 1 error in 1 file (checked 1 source file)
  60. """
  61. ret, out = call_mypy(code)
  62. assert ret
  63. assert out == expected
  64. def test_ok_transaction_atomic(call_mypy):
  65. code = """
  66. from django.db import transaction
  67. with transaction.atomic("default"):
  68. value = 10 / 2
  69. """
  70. ret, _ = call_mypy(code)
  71. assert ret == 0
  72. def test_ok_transaction_on_commit(call_mypy):
  73. code = """
  74. from django.db import transaction
  75. def completed():
  76. pass
  77. transaction.on_commit(completed, "default")
  78. """
  79. ret, _ = call_mypy(code)
  80. assert ret == 0
  81. def test_invalid_transaction_on_commit(call_mypy):
  82. code = """
  83. from django.db import transaction
  84. def completed():
  85. pass
  86. transaction.on_commit(completed)
  87. """
  88. expected = """\
  89. <string>:7: error: Missing positional argument "using" in call to "on_commit" [call-arg]
  90. Found 1 error in 1 file (checked 1 source file)
  91. """
  92. ret, out = call_mypy(code)
  93. assert ret
  94. assert out == expected
  95. def test_invalid_transaction_set_rollback(call_mypy):
  96. code = """
  97. from django.db import transaction
  98. transaction.set_rollback(True)
  99. """
  100. expected = """\
  101. <string>:4: error: Missing positional argument "using" in call to "set_rollback" [call-arg]
  102. Found 1 error in 1 file (checked 1 source file)
  103. """
  104. ret, out = call_mypy(code)
  105. assert ret
  106. assert out == expected
  107. def test_ok_transaction_set_rollback(call_mypy):
  108. code = """
  109. from django.db import transaction
  110. transaction.set_rollback(True, "default")
  111. """
  112. ret, _ = call_mypy(code)
  113. assert ret == 0