def restore_use_shell_state() -> Generator[None, None, None]:
    """Fixture to attempt to restore state associated with the USE_SHELL attribute.

    This is used to decrease the likelihood of state changes leaking out and affecting
    other tests. But the goal is not to assert implementation details of USE_SHELL.

    This covers two of the common implementation strategies, for convenience in testing
    both. USE_SHELL could be implemented in the metaclass:

    * With a separate _USE_SHELL backing attribute. If using a property or other
      descriptor, this is the natural way to do it, but custom __getattribute__ and
      __setattr__ logic, if it does more than adding warnings, may also use that.
    * Like a simple attribute, using USE_SHELL itself, stored as usual in the class
      dictionary, with custom __getattribute__/__setattr__ logic only to warn.

    This tries to save private state, tries to save the public attribute value, yields
    to the test case, tries to restore the public attribute value, then tries to restore
    private state. The idea is that if the getting or setting logic is wrong in the code
    under test, the state will still most likely be reset successfully.
    """
    no_value = object()

    # Try to save the original private state.
    try:
        old_private_value = Git._USE_SHELL  # type: ignore[attr-defined]
    except AttributeError:
        separate_backing_attribute = False
        try:
            old_private_value = type.__getattribute__(Git, "USE_SHELL")
        except AttributeError:
            old_private_value = no_value
            _logger.error("Cannot retrieve old private _USE_SHELL or USE_SHELL value")
    else:
        separate_backing_attribute = True

    try:
        # Try to save the original public value. Rather than attempt to restore a state
        # where the attribute is not set, if we cannot do this we allow AttributeError
        # to propagate out of the fixture, erroring the test case before its code runs.
        with suppress_deprecation_warning():
            old_public_value = Git.USE_SHELL

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

        # Try to restore the original public value.
        with suppress_deprecation_warning():
            Git.USE_SHELL = old_public_value
    finally:
        # Try to restore the original private state.
        if separate_backing_attribute:
            Git._USE_SHELL = old_private_value  # type: ignore[attr-defined]
        elif old_private_value is not no_value:
            type.__setattr__(Git, "USE_SHELL", old_private_value)
Fixture to attempt to restore state associated with the USE_SHELL attribute.

    This is used to decrease the likelihood of state changes leaking out and affecting
    other tests. But the goal is not to assert implementation details of USE_SHELL.

    This covers two of the common implementation strategies, for convenience in testing
    both. USE_SHELL could be implemented in the metaclass:

    * With a separate _USE_SHELL backing attribute. If using a property or other
      descriptor, this is the natural way to do it, but custom __getattribute__ and
      __setattr__ logic, if it does more than adding warnings, may also use that.
    * Like a simple attribute, using USE_SHELL itself, stored as usual in the class
      dictionary, with custom __getattribute__/__setattr__ logic only to warn.

    This tries to save private state, tries to save the public attribute value, yields
    to the test case, tries to restore the public attribute value, then tries to restore
    private state. The idea is that if the getting or setting logic is wrong in the code
    under test, the state will still most likely be reset successfully.
    
test/deprecation/test_cmd_git.py