|
1 | 1 | """Tests for static and dynamic characteristics of Git class and instance attributes. |
2 | 2 |
|
3 | | -Currently this all relates to the deprecated :class:`Git.USE_SHELL` class attribute, |
| 3 | +Currently this all relates to the deprecated :attr:`Git.USE_SHELL` class attribute, |
4 | 4 | which can also be accessed through instances. Some tests directly verify its behavior, |
5 | 5 | including deprecation warnings, while others verify that other aspects of attribute |
6 | 6 | access are not inadvertently broken by mechanisms introduced to issue the warnings. |
| 7 | +
|
| 8 | +A note on multiprocessing: Because USE_SHELL has no instance state, this module does not |
| 9 | +include tests of pickling and multiprocessing. |
| 10 | +
|
| 11 | +- Just as with a simple class attribute, when a class attribute with custom logic is |
| 12 | + later set to a new value, it may have either its initial value or the new value when |
| 13 | + accessed from a worker process, depending on the process start method. With "fork", |
| 14 | + changes are preserved. With "spawn" or "forkserver", re-importing the modules causes |
| 15 | + initial values to be set. Then the value in the parent at the time it dispatches the |
| 16 | + task is only set in the children if the parent has the task set it, or if it is set as |
| 17 | + a side effect of importing needed modules, or of unpickling objects passed to the |
| 18 | + child (for example, if it is set in a top-level statement of the module that defines |
| 19 | + the function submitted for the child worker process to call). |
| 20 | +
|
| 21 | +- When an attribute gains new logic provided by a property or custom descriptor, and the |
| 22 | + attribute involves instance-level state, incomplete or corrupted pickling can break |
| 23 | + multiprocessing. (For example, if an instance attribute is reimplemented using a |
| 24 | + descriptor that stores data in a global WeakKeyDictionary, pickled instances should be |
| 25 | + tested to ensure they are still working correctly.) But nothing like that applies |
| 26 | + here, because instance state is not involved. Although the situation is inherently |
| 27 | + complex as described above, it is independent of the attribute implementation. |
| 28 | +
|
| 29 | +- That USE_SHELL cannot be set on instances, and that when retrieved on instances it |
| 30 | + always gives the same value as on the class, is covered in the tests here. |
7 | 31 | """ |
8 | 32 |
|
9 | | -fromconcurrent.futuresimportProcessPoolExecutor |
10 | 33 | importcontextlib |
11 | 34 | importsys |
12 | 35 | fromtypingimportGenerator |
@@ -204,23 +227,6 @@ def test_use_shell_cannot_set_on_instance( |
204 | 227 | instance.USE_SHELL=value |
205 | 228 |
|
206 | 229 |
|
207 | | -def_get_value_in_current_process()->bool: |
208 | | -returnGit.USE_SHELL |
209 | | - |
210 | | - |
211 | | -@pytest.mark.filterwarnings("ignore::DeprecationWarning") |
212 | | -@pytest.mark.parametrize("value", [False,True]) |
213 | | -deftest_use_shell_preserved_in_multiprocessing( |
214 | | -value:bool, |
215 | | -restore_use_shell_state:None, |
216 | | -)->None: |
217 | | -"""The USE_SHELL class attribute pickles accurately for multiprocessing.""" |
218 | | -Git.USE_SHELL=value |
219 | | -withProcessPoolExecutor(max_workers=1)asexecutor: |
220 | | -marshaled_value=executor.submit(_get_value_in_current_process).result() |
221 | | -assertmarshaled_valueisvalue |
222 | | - |
223 | | - |
224 | 230 | _EXPECTED_DIR_SUBSET= { |
225 | 231 | "cat_file_all", |
226 | 232 | "cat_file_header", |
|