Skip to content

Commit af723d5

Browse files
committed
Make test_use_shell_on_class more robust
1 parent 7ab27c5 commit af723d5

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

test/deprecation/test_cmd_git.py

+37-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import contextlib
1010
import sys
1111
from typing import Generator
12+
import warnings
1213

1314
if sys.version_info >= (3, 11):
1415
from typing import assert_type
@@ -26,9 +27,16 @@
2627
"""Beginning text of USE_SHELL deprecation warnings when USE_SHELL is set True."""
2728

2829

30+
@contextlib.contextmanager
31+
def _suppress_deprecation_warning() -> Generator[None, None, None]:
32+
with warnings.catch_warnings():
33+
warnings.filterwarnings("ignore", category=DeprecationWarning)
34+
yield
35+
36+
2937
@pytest.fixture
30-
def reset_backing_attribute() -> Generator[None, None, None]:
31-
"""Fixture to reset the private ``_USE_SHELL`` attribute.
38+
def try_restore_use_shell_state() -> Generator[None, None, None]:
39+
"""Fixture to attempt to restore state associated with the ``USE_SHELL`` attribute.
3240
3341
This is used to decrease the likelihood of state changes leaking out and affecting
3442
other tests. But the goal is not to assert that ``_USE_SHELL`` is used, nor anything
@@ -38,18 +46,27 @@ def reset_backing_attribute() -> Generator[None, None, None]:
3846
restores attributes that it has previously been used to change, create, or remove.
3947
"""
4048
no_value = object()
49+
4150
try:
42-
old_value = Git._USE_SHELL
51+
old_backing_value = Git._USE_SHELL
4352
except AttributeError:
44-
old_value = no_value
53+
old_backing_value = no_value
54+
try:
55+
with _suppress_deprecation_warning():
56+
old_public_value = Git.USE_SHELL
4557

46-
yield
58+
# This doesn't have its own try-finally because pytest catches exceptions raised
59+
# during the yield. (The outer try-finally catches exceptions in this fixture.)
60+
yield
4761

48-
if old_value is no_value:
49-
with contextlib.suppress(AttributeError):
50-
del Git._USE_SHELL
51-
else:
52-
Git._USE_SHELL = old_value
62+
with _suppress_deprecation_warning():
63+
Git.USE_SHELL = old_public_value
64+
finally:
65+
if old_backing_value is no_value:
66+
with contextlib.suppress(AttributeError):
67+
del Git._USE_SHELL
68+
else:
69+
Git._USE_SHELL = old_backing_value
5370

5471

5572
def test_cannot_access_undefined_on_git_class() -> None:
@@ -76,23 +93,26 @@ def test_get_use_shell_on_class_default() -> None:
7693
assert not use_shell
7794

7895

79-
# FIXME: More robustly check that each operation really issues exactly one deprecation
80-
# warning, even if this requires relying more on reset_backing_attribute doing its job.
81-
def test_use_shell_on_class(reset_backing_attribute) -> None:
96+
def test_use_shell_on_class(try_restore_use_shell_state) -> None:
8297
"""USE_SHELL can be written and re-read as a class attribute, always warning."""
83-
# We assert in a "safe" order, using reset_backing_attribute only as a backstop.
84-
with pytest.deprecated_call() as ctx:
98+
with pytest.deprecated_call() as setting:
8599
Git.USE_SHELL = True
100+
with pytest.deprecated_call() as checking:
86101
set_value = Git.USE_SHELL
102+
with pytest.deprecated_call() as resetting:
87103
Git.USE_SHELL = False
104+
with pytest.deprecated_call() as rechecking:
88105
reset_value = Git.USE_SHELL
89106

90107
# The attribute should take on the values set to it.
91108
assert set_value is True
92109
assert reset_value is False
93110

94-
messages = [str(entry.message) for entry in ctx]
95-
set_message, check_message, reset_message, recheck_message = messages
111+
# Each access should warn exactly once.
112+
(set_message,) = [str(entry.message) for entry in setting]
113+
(check_message,) = [str(entry.message) for entry in checking]
114+
(reset_message,) = [str(entry.message) for entry in resetting]
115+
(recheck_message,) = [str(entry.message) for entry in rechecking]
96116

97117
# Setting it to True should produce the special warning for that.
98118
assert _USE_SHELL_DEPRECATED_FRAGMENT in set_message

0 commit comments

Comments
 (0)