def run_in_subprocess(test_func, *args):
    """Run a function in a subprocess.

    This ensures that sys.modules changes in subprocesses won't impact the parent process.

    Args:
        test_func: The function to be run in a subprocess.
        *args: Positional args to pass to the function.
    """

    assert callable(test_func), (
        "run_in_subprocess expects a function. Did you call the function instead of passing "
        "it to this method?"
    )

    # Use spawn to ensure subprocesses are isolated.
    # See https://github.com/quantumlib/Cirq/issues/6373
    ctx = multiprocessing.get_context('spawn')

    queue = ctx.Queue()

    p = ctx.Process(
        target=_trace_unhandled_exceptions, args=args, kwargs={'queue': queue, 'func': test_func}
    )
    p.start()
    p.join()
    result = queue.get()
    if result:  # pragma: no cover
        ex_type, msg, ex_trace = result
        if ex_type == "Skipped":
            warnings.warn(f"Skipping: {ex_type}: {msg}\n{ex_trace}")
            pytest.skip(f'{ex_type}: {msg}\n{ex_trace}')
        else:
            pytest.fail(f'{ex_type}: {msg}\n{ex_trace}')
Run a function in a subprocess.

    This ensures that sys.modules changes in subprocesses won't impact the parent process.

    Args:
        test_func: The function to be run in a subprocess.
        *args: Positional args to pass to the function.
    
cirq-core/cirq/_compat_test.py