1717 from typing_extensions import assert_type
1818
1919import pytest
20+ from pytest import WarningsRecorder
2021
2122from git .cmd import Git
2223
@@ -93,17 +94,34 @@ def test_get_use_shell_on_class_default() -> None:
9394 assert not use_shell
9495
9596
96- def test_use_shell_on_class (try_restore_use_shell_state ) -> None :
97- """USE_SHELL can be written and re-read as a class attribute, always warning."""
98- with pytest .deprecated_call () as setting :
99- Git .USE_SHELL = True
100- with pytest .deprecated_call () as checking :
101- set_value = Git .USE_SHELL
102- with pytest .deprecated_call () as resetting :
103- Git .USE_SHELL = False
104- with pytest .deprecated_call () as rechecking :
105- reset_value = Git .USE_SHELL
97+ def test_get_use_shell_on_instance_default () -> None :
98+ """USE_SHELL can be read as an instance attribute, defaulting to False and warning.
99+
100+ This is the same as test_get_use_shell_on_class_default above, but for instances.
101+ The test is repeated, instead of using parametrization, for clearer static analysis.
102+ """
103+ instance = Git ()
106104
105+ with pytest .deprecated_call () as ctx :
106+ use_shell = instance .USE_SHELL
107+
108+ (message ,) = [str (entry .message ) for entry in ctx ] # Exactly one warning.
109+ assert message .startswith (_USE_SHELL_DEPRECATED_FRAGMENT )
110+
111+ assert_type (use_shell , bool )
112+
113+ # This comes after the static assertion, just in case it would affect the inference.
114+ assert not use_shell
115+
116+
117+ def _assert_use_shell_full_results (
118+ set_value : bool ,
119+ reset_value : bool ,
120+ setting : WarningsRecorder ,
121+ checking : WarningsRecorder ,
122+ resetting : WarningsRecorder ,
123+ rechecking : WarningsRecorder ,
124+ ) -> None :
107125 # The attribute should take on the values set to it.
108126 assert set_value is True
109127 assert reset_value is False
@@ -124,7 +142,66 @@ def test_use_shell_on_class(try_restore_use_shell_state) -> None:
124142 assert recheck_message .startswith (_USE_SHELL_DEPRECATED_FRAGMENT )
125143
126144
127- # FIXME: Test behavior on instances (where we can get but not set).
145+ def test_use_shell_set_and_get_on_class (try_restore_use_shell_state : None ) -> None :
146+ """USE_SHELL can be set and re-read as a class attribute, always warning."""
147+ with pytest .deprecated_call () as setting :
148+ Git .USE_SHELL = True
149+ with pytest .deprecated_call () as checking :
150+ set_value = Git .USE_SHELL
151+ with pytest .deprecated_call () as resetting :
152+ Git .USE_SHELL = False
153+ with pytest .deprecated_call () as rechecking :
154+ reset_value = Git .USE_SHELL
155+
156+ _assert_use_shell_full_results (
157+ set_value ,
158+ reset_value ,
159+ setting ,
160+ checking ,
161+ resetting ,
162+ rechecking ,
163+ )
164+
165+
166+ def test_use_shell_set_on_class_get_on_instance (try_restore_use_shell_state : None ) -> None :
167+ """USE_SHELL can be set on the class and read on an instance, always warning.
168+
169+ This is like test_use_shell_set_and_get_on_class but it performs reads on an
170+ instance. There is some redundancy here in assertions about warnings when the
171+ attribute is set, but it is a separate test so that any bugs where a read on the
172+ class (or an instance) is needed first before a read on an instance (or the class)
173+ are detected.
174+ """
175+ instance = Git ()
176+
177+ with pytest .deprecated_call () as setting :
178+ Git .USE_SHELL = True
179+ with pytest .deprecated_call () as checking :
180+ set_value = instance .USE_SHELL
181+ with pytest .deprecated_call () as resetting :
182+ Git .USE_SHELL = False
183+ with pytest .deprecated_call () as rechecking :
184+ reset_value = instance .USE_SHELL
185+
186+ _assert_use_shell_full_results (
187+ set_value ,
188+ reset_value ,
189+ setting ,
190+ checking ,
191+ resetting ,
192+ rechecking ,
193+ )
194+
195+
196+ @pytest .mark .parametrize ("value" , [False , True ])
197+ def test_use_shell_cannot_set_on_instance (
198+ value : bool ,
199+ try_restore_use_shell_state : None , # In case of a bug where it does set USE_SHELL.
200+ ) -> None :
201+ instance = Git ()
202+ with pytest .raises (AttributeError ):
203+ instance .USE_SHELL = value
204+
128205
129206# FIXME: Test behavior with multiprocessing (the attribute needs to pickle properly).
130207
0 commit comments