def test_view_setattr_machinery(attr, subset_func, subset_func2):
    # Tests that setting attributes on a view doesn't mess anything up too bad
    adata = gen_adata((10, 10))
    view = adata[subset_func(adata.obs_names), subset_func2(adata.var_names)]

    actual = view.copy()
    setattr(view, attr, getattr(actual, attr))
    assert_equal(actual, view, exact=True)
def reset_signal_handler(cls, signal_handler):
        """Class state:

        - Overwrites `cls._signal_handler`.
        OS state:
        - Overwrites signal handlers for SIGINT, SIGQUIT, and SIGTERM.

        NB: This method calls signal.signal(), which will crash if not called from the main thread!

        :returns: The :class:`SignalHandler` that was previously registered, or None if this is
                  the first time this method was called.
        """
        assert isinstance(signal_handler, SignalHandler)
        # NB: Modify process-global state!
        for signum, handler in signal_handler.signal_handler_mapping.items():
            signal.signal(signum, handler)
            # Retry any system calls interrupted by any of the signals we just installed handlers for
            # (instead of having them raise EINTR). siginterrupt(3) says this is the default behavior on
            # Linux and OSX.
            signal.siginterrupt(signum, False)

        previous_signal_handler = cls._signal_handler
        # NB: Mutate the class variables!
        cls._signal_handler = signal_handler
        return previous_signal_handler