Repository: numpy/numpy
File: numpy/testing/_private/utils.py (Python)

Code before:
                for arg in all_args:
                    futures.append(tpe.submit(*arg))
            except RuntimeError as e:
                import pytest
                pytest.skip(f"Spawning {max_workers} threads failed with "
                            f"error {e!r} (likely due to resource limits on the "
                            "system running the tests)")
            finally:
                if len(futures) < max_workers and pass_barrier:
                    barrier.abort()
            for f in futures:
                f.result()


def requires_deep_recursion(func):
    """Decorator to skip test if deep recursion is not supported."""
    import pytest

    @wraps(func)
    def wrapper(*args, **kwargs):
        if IS_PYSTON:
            pytest.skip("Pyston disables recursion checking")
        if IS_WASM:
            pytest.skip("WASM has limited stack size")
        cflags = sysconfig.get_config_var('CFLAGS') or ''
        config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
        address_sanitizer = (
            '-fsanitize=address' in cflags or
            '--with-address-sanitizer' in config_args
        )
        thread_sanitizer = (
            '-fsanitize=thread' in cflags or
            '--with-thread-sanitizer' in config_args
        )
        if address_sanitizer or thread_sanitizer:
            pytest.skip("AddressSanitizer and ThreadSanitizer do not support "
                        "deep recursion")
        return func(*args, **kwargs)
    return wrapper


Review comment (bug):
To avoid a segfault on the `i686-cp312` test job: https://github.com/numpy/numpy/actions/runs/21183357907/job/60931865175?pr=30683

I suspect that the different pytest version is leading to a slightly different Python stack structure. I could try to understand more deeply too, but I don't think it's worth spending a bunch of time on an issue that only happens on 32 bit Python in a stress-test that we know causes issues in some situations.

Code after:
                for arg in all_args:
                    futures.append(tpe.submit(*arg))
            except RuntimeError as e:
                import pytest
                pytest.skip(f"Spawning {max_workers} threads failed with "
                            f"error {e!r} (likely due to resource limits on the "
                            "system running the tests)")
            finally:
                if len(futures) < max_workers and pass_barrier:
                    barrier.abort()
            for f in futures:
                f.result()


def requires_deep_recursion(func):
    """Decorator to skip test if deep recursion is not supported."""
    import pytest

    @wraps(func)
    def wrapper(*args, **kwargs):
        if IS_PYSTON:
            pytest.skip("Pyston disables recursion checking")
        if IS_WASM:
            pytest.skip("WASM has limited stack size")
        if not IS_64BIT:
            pytest.skip("32 bit Python has limited stack size")
        cflags = sysconfig.get_config_var('CFLAGS') or ''
        config_args = sysconfig.get_config_var('CONFIG_ARGS') or ''
        address_sanitizer = (
            '-fsanitize=address' in cflags or
            '--with-address-sanitizer' in config_args
        )
        thread_sanitizer = (
            '-fsanitize=thread' in cflags or
            '--with-thread-sanitizer' in config_args
        )
        if address_sanitizer or thread_sanitizer:
            pytest.skip("AddressSanitizer and ThreadSanitizer do not support "
                        "deep recursion")
        return func(*args, **kwargs)
    return wrapper