Skip to content

Commit 75d62a0

Browse files
committed
chore: update bigfoot to >=0.4.1 and adopt with-bigfoot context manager syntax
- Pin bigfoot to >=0.4.1 (adds StateMachinePlugin, SocketPlugin, DatabasePlugin, PopenPlugin, SmtpPlugin, RedisPlugin, AsyncWebSocketPlugin, SyncWebSocketPlugin) - Replace bigfoot.sandbox() with bigfoot module context manager in all test files - Bump version to 0.8.2
1 parent 0a035de commit 75d62a0

7 files changed

Lines changed: 48 additions & 45 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.8.2] - 2026-03-05
11+
1012
### Changed
1113

14+
- Updated bigfoot dependency to >=0.4.1 and adopted `with bigfoot:` context manager syntax
1215
- Test suite now uses [bigfoot](https://github.com/axiomantic/bigfoot) for subprocess interception. `subprocess.run` and `shutil.which` mocks in `test_install_libclang.py`, `test_version_detect.py`, `test_libclang.py`, and `test_windows_detection.py` are replaced with `bigfoot.subprocess_mock`, which enforces strict FIFO ordering and fails fast on unexpected calls.
1316
- Integration test writer assertions extracted into shared helpers (`_check_ctypes_write`, `_check_cython_write`, etc.) in `test_real_headers.py`, eliminating repeated assertion logic across the five library test classes.
1417

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "headerkit"
7-
version = "0.8.1"
7+
version = "0.8.2"
88
description = "C/C++ header analysis toolkit with pluggable backends and writers for ctypes, Cython, CFFI, LuaJIT FFI, and more"
99
readme = "README.md"
1010
license = "MIT AND Apache-2.0 WITH LLVM-exception"
@@ -43,7 +43,7 @@ headerkit = "headerkit._cli:main"
4343

4444
[project.optional-dependencies]
4545
toml = []
46-
test = ["pytest", "pytest-timeout", "bigfoot>=0.3.0"]
46+
test = ["pytest", "pytest-timeout", "bigfoot>=0.4.1"]
4747
lint = ["ruff", "mypy"]
4848
docs = ["mkdocs>=1.6", "mkdocs-material>=9.5", "mkdocstrings[python]>=0.27", "mike>=2.1"]
4949
dev = ["headerkit[test,lint,docs,toml]"]

tests/test_backends/test_libclang.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ def test_clang_not_found_returns_empty(self):
739739
["clang", "-v", "-x", "c", "-E", null_file],
740740
raises=FileNotFoundError(),
741741
)
742-
with bigfoot.sandbox():
742+
with bigfoot:
743743
result = get_system_include_dirs()
744744
assert result == []
745745
bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file])
@@ -756,7 +756,7 @@ def test_clang_timeout_returns_empty(self):
756756
["clang", "-v", "-x", "c", "-E", null_file],
757757
raises=subprocess.TimeoutExpired(cmd="clang", timeout=10),
758758
)
759-
with bigfoot.sandbox():
759+
with bigfoot:
760760
result = get_system_include_dirs()
761761
assert result == []
762762
bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file])
@@ -780,7 +780,7 @@ def test_parses_include_search_paths(self):
780780
"End of search list.\n"
781781
),
782782
)
783-
with bigfoot.sandbox():
783+
with bigfoot:
784784
result = get_system_include_dirs()
785785
assert result == ["-isystem/usr/lib/clang/18/include", "-isystem/usr/include"]
786786
bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file])
@@ -803,7 +803,7 @@ def test_skips_framework_directories(self):
803803
"End of search list.\n"
804804
),
805805
)
806-
with bigfoot.sandbox():
806+
with bigfoot:
807807
result = get_system_include_dirs()
808808
assert result == ["-isystem/usr/include"]
809809
bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file])

tests/test_clang/test_version_detect.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def test_cir_clang_version_env_var_takes_precedence(self):
3838
bigfoot.subprocess_mock.install()
3939
with (
4040
patch.dict(os.environ, {"CIR_CLANG_VERSION": "20"}),
41-
bigfoot.sandbox(),
41+
bigfoot,
4242
):
4343
# Even though llvm-config would return 19, the env var should win.
4444
# No subprocess.run or shutil.which calls should be made at all.
@@ -76,7 +76,7 @@ def test_llvm_config_full_version(self):
7676
with (
7777
patch.dict(os.environ, {}, clear=False),
7878
_no_llvm_dir,
79-
bigfoot.sandbox(),
79+
bigfoot,
8080
):
8181
assert detect_llvm_version() == "18"
8282

@@ -102,7 +102,7 @@ def test_llvm_config_versioned_binary(self):
102102
with (
103103
patch.dict(os.environ, {}, clear=False),
104104
_no_llvm_dir,
105-
bigfoot.sandbox(),
105+
bigfoot,
106106
):
107107
assert detect_llvm_version() == "18"
108108

@@ -129,7 +129,7 @@ def test_llvm_config_not_found(self):
129129
patch.dict(os.environ, {}, clear=False),
130130
_no_llvm_dir,
131131
_linux_platform,
132-
bigfoot.sandbox(),
132+
bigfoot,
133133
):
134134
assert detect_llvm_version() == "19"
135135

@@ -163,7 +163,7 @@ def test_llvm_config_returns_non_zero_exit(self):
163163
patch.dict(os.environ, {}, clear=False),
164164
_no_llvm_dir,
165165
_linux_platform,
166-
bigfoot.sandbox(),
166+
bigfoot,
167167
):
168168
assert detect_llvm_version() == "21"
169169

@@ -202,7 +202,7 @@ def test_llvm_config_returns_garbage(self):
202202
patch.dict(os.environ, {}, clear=False),
203203
_no_llvm_dir,
204204
_linux_platform,
205-
bigfoot.sandbox(),
205+
bigfoot,
206206
):
207207
assert detect_llvm_version() == "20"
208208

@@ -240,7 +240,7 @@ def test_llvm_config_subprocess_timeout(self):
240240
patch.dict(os.environ, {}, clear=False),
241241
_no_llvm_dir,
242242
_linux_platform,
243-
bigfoot.sandbox(),
243+
bigfoot,
244244
):
245245
assert detect_llvm_version() == "19"
246246

@@ -273,7 +273,7 @@ def test_clang_major_define(self):
273273
patch.dict(os.environ, {}, clear=False),
274274
_no_llvm_dir,
275275
_linux_platform,
276-
bigfoot.sandbox(),
276+
bigfoot,
277277
):
278278
assert detect_llvm_version() == "20"
279279

@@ -302,7 +302,7 @@ def test_clang_versioned_binary(self):
302302
patch.dict(os.environ, {}, clear=False),
303303
_no_llvm_dir,
304304
_linux_platform,
305-
bigfoot.sandbox(),
305+
bigfoot,
306306
):
307307
assert detect_llvm_version() == "19"
308308

@@ -338,7 +338,7 @@ def test_apple_clang_version_detected(self):
338338
patch.dict(os.environ, {}, clear=False),
339339
_no_llvm_dir,
340340
_linux_platform,
341-
bigfoot.sandbox(),
341+
bigfoot,
342342
):
343343
assert detect_llvm_version() == "16"
344344

@@ -360,7 +360,7 @@ def test_clang_preprocessor_no_clang_major(self):
360360
patch.dict(os.environ, {}, clear=False),
361361
_no_llvm_dir,
362362
_linux_platform,
363-
bigfoot.sandbox(),
363+
bigfoot,
364364
):
365365
assert detect_llvm_version() is None
366366

@@ -381,7 +381,7 @@ def test_clang_subprocess_oserror(self):
381381
patch.dict(os.environ, {}, clear=False),
382382
_no_llvm_dir,
383383
_linux_platform,
384-
bigfoot.sandbox(),
384+
bigfoot,
385385
):
386386
assert detect_llvm_version() is None
387387

@@ -408,7 +408,7 @@ def test_pkg_config_clang_module(self):
408408
with (
409409
patch.dict(os.environ, {}, clear=False),
410410
_no_llvm_dir,
411-
bigfoot.sandbox(),
411+
bigfoot,
412412
):
413413
assert detect_llvm_version() == "18"
414414

@@ -435,7 +435,7 @@ def test_pkg_config_not_installed(self):
435435
patch.dict(os.environ, {}, clear=False),
436436
_no_llvm_dir,
437437
_linux_platform,
438-
bigfoot.sandbox(),
438+
bigfoot,
439439
):
440440
assert detect_llvm_version() == "20"
441441

@@ -475,7 +475,7 @@ def test_pkg_config_module_not_found(self):
475475
patch.dict(os.environ, {}, clear=False),
476476
_no_llvm_dir,
477477
_linux_platform,
478-
bigfoot.sandbox(),
478+
bigfoot,
479479
):
480480
assert detect_llvm_version() == "19"
481481

@@ -561,7 +561,7 @@ def test_brew_llvm_prefix(self):
561561
patch("headerkit._clang._version.sys.platform", "darwin"),
562562
patch("headerkit._clang._version.os.path.isfile", return_value=True),
563563
_no_llvm_dir,
564-
bigfoot.sandbox(),
564+
bigfoot,
565565
):
566566
assert detect_llvm_version() == "20"
567567

@@ -623,7 +623,7 @@ def test_registry_called_after_clang_preprocessor(self):
623623
patch.dict("sys.modules", {"winreg": mock_winreg}),
624624
patch("headerkit._clang._version.os.path.isdir", return_value=True),
625625
patch("headerkit._clang._version.os.path.isfile", return_value=True),
626-
bigfoot.sandbox(),
626+
bigfoot,
627627
):
628628
assert detect_llvm_version() == "18"
629629

@@ -668,7 +668,7 @@ def isfile_side_effect(path):
668668
patch.dict("sys.modules", {"winreg": mock_winreg}),
669669
patch("headerkit._clang._version.os.path.isdir", return_value=False),
670670
patch("headerkit._clang._version.os.path.isfile", side_effect=isfile_side_effect),
671-
bigfoot.sandbox(),
671+
bigfoot,
672672
):
673673
assert detect_llvm_version() == "20"
674674

@@ -686,6 +686,6 @@ def test_all_methods_fail_returns_none(self):
686686
_no_llvm_dir,
687687
patch("headerkit._clang._version._try_windows_registry", return_value=None),
688688
patch("headerkit._clang._version._try_windows_program_files", return_value=None),
689-
bigfoot.sandbox(),
689+
bigfoot,
690690
):
691691
assert detect_llvm_version() is None

tests/test_clang/test_windows_detection.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def test_finds_version_from_registry(self, mock_winreg_constants):
4545
patch.dict(sys.modules, {"winreg": mock_winreg}),
4646
patch("headerkit._clang._version.os.path.isdir", return_value=True),
4747
patch("headerkit._clang._version.os.path.isfile", return_value=True),
48-
bigfoot.sandbox(),
48+
bigfoot,
4949
):
5050
result = _try_windows_registry()
5151
assert result == "18"
@@ -112,7 +112,7 @@ def test_clang_exe_returns_no_version(self, mock_winreg_constants):
112112
patch.dict(sys.modules, {"winreg": mock_winreg}),
113113
patch("headerkit._clang._version.os.path.isdir", return_value=True),
114114
patch("headerkit._clang._version.os.path.isfile", return_value=True),
115-
bigfoot.sandbox(),
115+
bigfoot,
116116
):
117117
result = _try_windows_registry()
118118
assert result is None
@@ -141,7 +141,7 @@ def test_subprocess_timeout(self, mock_winreg_constants):
141141
patch.dict(sys.modules, {"winreg": mock_winreg}),
142142
patch("headerkit._clang._version.os.path.isdir", return_value=True),
143143
patch("headerkit._clang._version.os.path.isfile", return_value=True),
144-
bigfoot.sandbox(),
144+
bigfoot,
145145
):
146146
result = _try_windows_registry()
147147
assert result is None
@@ -178,7 +178,7 @@ def test_finds_version_from_programfiles(self):
178178
},
179179
),
180180
patch("headerkit._clang._version.os.path.isfile", return_value=True),
181-
bigfoot.sandbox(),
181+
bigfoot,
182182
):
183183
result = _try_windows_program_files()
184184
assert result == "20"
@@ -208,7 +208,7 @@ def isfile_side_effect(path):
208208
},
209209
),
210210
patch("headerkit._clang._version.os.path.isfile", side_effect=isfile_side_effect),
211-
bigfoot.sandbox(),
211+
bigfoot,
212212
):
213213
result = _try_windows_program_files()
214214
assert result == "19"
@@ -271,7 +271,7 @@ def test_subprocess_error_continues_to_next_candidate(self):
271271
},
272272
),
273273
patch("headerkit._clang._version.os.path.isfile", return_value=True),
274-
bigfoot.sandbox(),
274+
bigfoot,
275275
):
276276
result = _try_windows_program_files()
277277
assert result == "21"

tests/test_install_libclang.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_install_linux_dnf(self) -> None:
2424
bigfoot.subprocess_mock.mock_which("dnf", returns="/usr/bin/dnf")
2525
bigfoot.subprocess_mock.mock_run(["dnf", "install", "-y", "clang-devel"], returncode=0)
2626

27-
with bigfoot.sandbox():
27+
with bigfoot:
2828
result = install_linux()
2929

3030
assert result is True
@@ -43,7 +43,7 @@ def test_install_linux_apt(self) -> None:
4343
bigfoot.subprocess_mock.mock_run(["apt-get", "update", "-qq"], returncode=0)
4444
bigfoot.subprocess_mock.mock_run(["apt-get", "install", "-y", "libclang-dev"], returncode=0)
4545

46-
with bigfoot.sandbox():
46+
with bigfoot:
4747
result = install_linux()
4848

4949
assert result is True
@@ -65,7 +65,7 @@ def test_install_linux_apk(self) -> None:
6565
bigfoot.subprocess_mock.mock_which("apk", returns="/sbin/apk")
6666
bigfoot.subprocess_mock.mock_run(["apk", "add", "clang-dev"], returncode=0)
6767

68-
with bigfoot.sandbox():
68+
with bigfoot:
6969
result = install_linux()
7070

7171
assert result is True
@@ -84,7 +84,7 @@ def test_install_linux_no_package_manager(self) -> None:
8484
# sandbox entry. Without this, subprocess.run would not be intercepted.
8585
bigfoot.subprocess_mock.install() # no mocks; any call raises UnmockedInteractionError
8686

87-
with bigfoot.sandbox():
87+
with bigfoot:
8888
result = install_linux()
8989

9090
assert result is False
@@ -99,7 +99,7 @@ def test_install_linux_dnf_fails_falls_through_to_apt(self) -> None:
9999
bigfoot.subprocess_mock.mock_run(["apt-get", "update", "-qq"], returncode=0)
100100
bigfoot.subprocess_mock.mock_run(["apt-get", "install", "-y", "libclang-dev"], returncode=0)
101101

102-
with bigfoot.sandbox():
102+
with bigfoot:
103103
result = install_linux()
104104

105105
assert result is True
@@ -131,7 +131,7 @@ def test_install_macos_success(self) -> None:
131131
bigfoot.subprocess_mock.mock_which("brew", returns="/opt/homebrew/bin/brew")
132132
bigfoot.subprocess_mock.mock_run(["brew", "install", "llvm"], returncode=0)
133133

134-
with bigfoot.sandbox():
134+
with bigfoot:
135135
result = install_macos()
136136

137137
assert result is True
@@ -148,7 +148,7 @@ def test_install_macos_no_brew(self) -> None:
148148
"""When brew is unavailable, install_macos returns False."""
149149
bigfoot.subprocess_mock.install() # no mocks; any call raises UnmockedInteractionError
150150

151-
with bigfoot.sandbox():
151+
with bigfoot:
152152
result = install_macos()
153153

154154
assert result is False
@@ -165,7 +165,7 @@ def test_install_windows_x64(self) -> None:
165165

166166
with (
167167
patch.dict("os.environ", {"PROCESSOR_ARCHITECTURE": "AMD64"}, clear=False),
168-
bigfoot.sandbox(),
168+
bigfoot,
169169
):
170170
result = install_windows(DEFAULT_LLVM_VERSION)
171171

@@ -185,7 +185,7 @@ def test_install_windows_x64_no_choco(self) -> None:
185185

186186
with (
187187
patch.dict("os.environ", {"PROCESSOR_ARCHITECTURE": "AMD64"}, clear=False),
188-
bigfoot.sandbox(),
188+
bigfoot,
189189
):
190190
result = install_windows(DEFAULT_LLVM_VERSION)
191191

@@ -219,7 +219,7 @@ def test_install_windows_arm64(self) -> None:
219219
with (
220220
patch.dict("os.environ", {"PROCESSOR_ARCHITECTURE": "ARM64"}, clear=False),
221221
patch("headerkit.install_libclang.os.remove") as mock_remove,
222-
bigfoot.sandbox(),
222+
bigfoot,
223223
):
224224
result = install_windows(version)
225225

0 commit comments

Comments
 (0)