diff --git a/tests/xargs_with_blocked_sysconf_test.py b/tests/xargs_with_blocked_sysconf_test.py index 982fa34e..8348cd34 100644 --- a/tests/xargs_with_blocked_sysconf_test.py +++ b/tests/xargs_with_blocked_sysconf_test.py @@ -1,3 +1,4 @@ +"""Tests for pre_commit.xargs when os.sysconf is blocked in a sandbox environment.""" from __future__ import annotations import subprocess @@ -6,27 +7,19 @@ import textwrap # flake8: noqa: E501 - -# TODO -# import module without throwing exception -# create object without throwing exception -# -- explicit _length -# -- implicit _length +# Error message when os.sysconf is blocked in the test subprocess +BLOCKED_SYSCONF_ERROR = 'blocked' -def test_import_module_without_throwing_exception_as_subprocess() -> None: - """Import pre_commit.xargs in a subprocess even when os.sysconf is blocked. +def _create_import_test_script() -> str: + """Create a Python script that tests importing pre_commit.xargs with blocked os.sysconf. - This test runs in a fresh subprocess where we can control os.sysconf - BEFORE any imports happen, avoiding the conftest.py chicken/egg problem. - - With the current buggy implementation, this subprocess will crash - (returncode != 0) because os.sysconf('SC_ARG_MAX') is called at import - time and raises OSError. - - After the fix, the subprocess should succeed (returncode == 0). + This script must run in a subprocess (not in the main pytest process) because: + 1. We need to patch os.sysconf BEFORE any imports happen + 2. conftest.py already imports pre_commit.xargs in the main process + 3. A subprocess gives us a clean import state to test against """ - script = textwrap.dedent(""" + return textwrap.dedent(f""" import importlib import os from unittest import mock @@ -36,7 +29,7 @@ def test_import_module_without_throwing_exception_as_subprocess() -> None: os.name = 'posix' # Block os.sysconf so that any SC_ARG_MAX lookup fails with OSError. - with mock.patch.object(os, 'sysconf', side_effect=OSError('blocked')): + with mock.patch.object(os, 'sysconf', side_effect=OSError('{BLOCKED_SYSCONF_ERROR}')): # This should NOT raise with the fixed implementation. importlib.import_module('pre_commit.xargs') @@ -44,6 +37,21 @@ def test_import_module_without_throwing_exception_as_subprocess() -> None: main() """) + +def test_import_module_without_throwing_exception_as_subprocess() -> None: + """Test that pre_commit.xargs can be imported when os.sysconf is blocked. + + This test uses a subprocess to avoid the conftest.py chicken/egg problem: + - Phase 1 (this function): Sets up and runs a subprocess with blocked os.sysconf + - Phase 2 (subprocess script): Attempts to import pre_commit.xargs in that environment + + With the current buggy implementation, the subprocess crashes because os.sysconf + is called at import time. After the fix, the subprocess should succeed. + """ + # Create the test script that will run in a subprocess + script = _create_import_test_script() + + # Run the script in a fresh subprocess where we control os.sysconf proc = subprocess.run( [sys.executable, '-c', script], capture_output=True, @@ -51,6 +59,7 @@ def test_import_module_without_throwing_exception_as_subprocess() -> None: cwd='/Users/michael/repos/pre-commit', ) + # Assert the subprocess succeeded (import worked without exception) # Test-first: This test FAILS with current buggy behavior (subprocess crashes). # After fix, subprocess should succeed (returncode == 0). assert proc.returncode == 0, (