From 9236cf1a183418f4f4d03d5f3cc85c7310665f6b Mon Sep 17 00:00:00 2001 From: Alex Lubbock Date: Sun, 26 Apr 2026 13:17:55 +0100 Subject: [PATCH] fix(resource-usage): forward pre/post_run_triggers via super() for correct MRO chaining --- CHANGELOG.md | 8 ++++++++ microbench/mixins/system.py | 6 ++++++ tests/test_mixins.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f596a5e..a566de5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,14 @@ All notable changes to microbench are documented here. overrides the default entirely; the Python API is unaffected. The hash algorithm name is now stored under `mb.file_hash_algorithm`. +### Bug fixes + +- **`MBResourceUsage` — `pre_run_triggers`/`post_run_triggers` now forward + via `super()`**: composing `MBResourceUsage` with another mixin that also + implements `pre_run_triggers` or `post_run_triggers` previously caused the + second mixin's hooks to be silently skipped. Both methods now propagate + correctly through the MRO. + ### Documentation - Fix documentation on writing custom mixins to note that they must be diff --git a/microbench/mixins/system.py b/microbench/mixins/system.py index 3971745..5896525 100644 --- a/microbench/mixins/system.py +++ b/microbench/mixins/system.py @@ -445,6 +445,9 @@ def pre_run_triggers(self, bm_data): self._rusage_iter_before = _rusage_to_dict( _resource.getrusage(_resource.RUSAGE_SELF), include_maxrss=False ) + parent = super() + if hasattr(parent, 'pre_run_triggers'): + parent.pre_run_triggers(bm_data) def post_run_triggers(self, bm_data): if _resource is not None and not hasattr(self, '_subprocess_command'): @@ -454,6 +457,9 @@ def post_run_triggers(self, bm_data): self._rusage_iter_entries.append( _rusage_delta(self._rusage_iter_before, after) ) + parent = super() + if hasattr(parent, 'post_run_triggers'): + parent.post_run_triggers(bm_data) def capturepost_resource_usage(self, bm_data): """Write the resource_usage list to bm_data after all iterations.""" diff --git a/tests/test_mixins.py b/tests/test_mixins.py index 8567046..77d29a1 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -1009,3 +1009,38 @@ def noop(): _sys_mod._resource = original assert 'resource_usage' not in bench.get_results()[0] + + +@pytest.mark.skipif( + sys.platform == 'win32', reason='resource module not available on Windows' +) +def test_resource_usage_run_trigger_chain(): + """pre/post_run_triggers forward via super() so composed mixins all fire.""" + calls = [] + + class _TrackerMixin: + def pre_run_triggers(self, bm_data): + calls.append('pre') + parent = super() + if hasattr(parent, 'pre_run_triggers'): + parent.pre_run_triggers(bm_data) + + def post_run_triggers(self, bm_data): + calls.append('post') + parent = super() + if hasattr(parent, 'post_run_triggers'): + parent.post_run_triggers(bm_data) + + class Bench(MicroBench, _TrackerMixin, MBResourceUsage): + pass + + bench = Bench() + + @bench + def noop(): + pass + + noop() + + assert calls == ['pre', 'post'] + assert len(bench.get_results()[0]['resource_usage']) == 1