1717from 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:
9394assert 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.
108126assert set_value is True
109127assert reset_value is False
@@ -124,7 +142,66 @@ def test_use_shell_on_class(try_restore_use_shell_state) -> None:
124142assert 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