Skip to content

Commit a7b18ba

Browse files
feat: collect Python toolchain information via instrument hooks environment API
Update instrument-hooks submodule to pick up the new environment collection API and use it to report Python version and build info at runtime. Generated with AI Agent (Claude Code)
1 parent aa267f3 commit a7b18ba

6 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/pytest_codspeed/instruments/analysis.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, config: CodSpeedConfig, mode: MeasurementMode) -> None:
3333
try:
3434
self.instrument_hooks = InstrumentHooks()
3535
self.instrument_hooks.set_integration("pytest-codspeed", __semver_version__)
36+
self.instrument_hooks.collect_and_write_python_environment()
3637
except RuntimeError as e:
3738
if os.environ.get("CODSPEED_ENV") is not None:
3839
raise Exception(

src/pytest_codspeed/instruments/hooks/__init__.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import sys
5+
import sysconfig
56
import warnings
67
from typing import TYPE_CHECKING
78

@@ -92,3 +93,43 @@ def set_feature(self, feature: int, enabled: bool) -> None:
9293
enabled: Whether to enable or disable the feature
9394
"""
9495
self.lib.instrument_hooks_set_feature(feature, enabled)
96+
97+
def set_environment(self, section_name: str, key: str, value: str) -> None:
98+
"""Register a key-value pair under a named section for environment collection.
99+
100+
Args:
101+
section_name: The section name (e.g. "Python")
102+
key: The key (e.g. "version")
103+
value: The value (e.g. "3.13.12")
104+
"""
105+
ret = self.lib.instrument_hooks_set_environment(
106+
self.instance,
107+
section_name.encode("utf-8"),
108+
key.encode("utf-8"),
109+
value.encode("utf-8"),
110+
)
111+
if ret != 0:
112+
warnings.warn("Failed to set environment data", RuntimeWarning)
113+
114+
def write_environment(self, pid: int | None = None) -> None:
115+
"""Flush all registered environment sections to disk.
116+
117+
Writes to $CODSPEED_PROFILE_FOLDER/environment-<pid>.json.
118+
119+
Args:
120+
pid: Optional process ID (defaults to current process)
121+
"""
122+
if pid is None:
123+
pid = os.getpid()
124+
ret = self.lib.instrument_hooks_write_environment(self.instance, pid)
125+
if ret != 0:
126+
warnings.warn("Failed to write environment data", RuntimeWarning)
127+
128+
def collect_and_write_python_environment(self) -> None:
129+
"""Collect Python toolchain information and write it to disk."""
130+
131+
for key, value in sysconfig.get_config_vars().items():
132+
self.set_environment(
133+
"python", f"{key}", str(value) if value is not None else ""
134+
)
135+
self.write_environment()

src/pytest_codspeed/instruments/hooks/build.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
void callgrind_stop_instrumentation();
3737
3838
void instrument_hooks_set_feature(uint64_t feature, bool enabled);
39+
40+
uint8_t instrument_hooks_set_environment(InstrumentHooks *, const char *section_name,
41+
const char *key, const char *value);
42+
uint8_t instrument_hooks_write_environment(InstrumentHooks *, uint32_t pid);
3943
""")
4044

4145
ffibuilder.set_source(
@@ -47,6 +51,8 @@
4751
"src/pytest_codspeed/instruments/hooks/instrument-hooks/dist/core.c",
4852
],
4953
include_dirs=[str(includes_dir)],
54+
# IMPORTANT: Keep in sync with instrument-hooks/ci.yml (COMMON_CFLAGS)
55+
extra_compile_args=["-Wno-format-security"],
5056
)
5157

5258
if __name__ == "__main__":

src/pytest_codspeed/instruments/hooks/dist_instrument_hooks.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,13 @@ class lib:
3131
def callgrind_stop_instrumentation() -> int: ...
3232
@staticmethod
3333
def instrument_hooks_set_feature(feature: int, enabled: bool) -> None: ...
34+
@staticmethod
35+
def instrument_hooks_set_environment(
36+
hooks: InstrumentHooksPointer, section_name: bytes, key: bytes, value: bytes
37+
) -> int: ...
38+
@staticmethod
39+
def instrument_hooks_write_environment(
40+
hooks: InstrumentHooksPointer, pid: int
41+
) -> int: ...
3442

3543
LibType = type[lib]

src/pytest_codspeed/instruments/walltime.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def __init__(self, config: CodSpeedConfig, _mode: MeasurementMode) -> None:
163163
try:
164164
self.instrument_hooks = InstrumentHooks()
165165
self.instrument_hooks.set_integration("pytest-codspeed", __semver_version__)
166+
self.instrument_hooks.collect_and_write_python_environment()
166167
except RuntimeError as e:
167168
if os.environ.get("CODSPEED_ENV") is not None:
168169
warnings.warn(

0 commit comments

Comments
 (0)