perf: cache inspect.signature() at decoration time (#97) #107
No reviewers
Labels
No Label
ai-changes-requested
ai-pr-opened
ai-reviewed
ai-reviewing
ai-working
in-next-release
status/in-progress
status/pr-open
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-v2#107
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "ai/major-domo-v2-97"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #97
Summary
Moves
inspect.signature(func)calls from inside wrapper functions to the outerdecoratorfunction, so the introspection cost is paid once at decoration time rather than on every invocation.Changes in
utils/decorators.pylogged_command:sig,param_names, andexclude_setare now computed indecorator(func)and closed over bywrapper.wrapper.__signature__reuses the pre-computedsiginstead of callinginspect.signaturea second time.cached_api_call:sig = inspect.signature(func)moved todecoratorscope.bound_args = sig.bind(...)stays in the wrapper since it requires runtime args.cached_single_item: Same pattern ascached_api_call.Test results
11/11 decorator tests pass. 935/935 unaffected tests pass. 18 pre-existing failures from unrelated modified working-tree files (
charts.py,scorecard_tracker.py) — not caused by this change.Other observations
Review: perf: cache inspect.signature() at decoration time (#97)
Verdict: APPROVED (posted as COMMENT — Gitea blocks self-review on cal-owned repos)
Summary
Clean, correct performance optimization. All three
inspect.signature()call movements are semantically safe, and the refactor produces identical observable behavior at a lower per-invocation cost.Correctness Analysis
logged_command:sig,param_names, andexclude_setare all derived purely fromfuncandexclude_params, which are fixed at decoration time. Moving them todecoratorscope is sound. One micro-observation:param_namesandexclude_setare now computed even whenlog_params=False, but this cost is paid once at decoration time so it's negligible.wrapper.__signature__ = sigreuses the same value that was previously re-computed — correct.cached_api_call/cached_single_item:sig = inspect.signature(func)moved todecoratorscope;sig.bind(self, *args, **kwargs)correctly remains inwrapper(needs runtime args). TheSignatureobject is read-only after creation, so sharing it across concurrent async invocations via closure is safe —bind()creates a freshBoundArgumentseach time.requires_draft_period/cache_invalidate: No structural changes.requires_draft_periodalready calledinspect.signature(func)once at decoration time (single-level decorator, not a factory), so nothing to optimize. Cosmetic formatting only.Test Coverage
11/11 existing decorator tests pass and continue to cover all observable behavior: signature preservation, param logging, exclusion, auto-naming, error path, logger fallback. The refactored paths are exercised by these tests. No new tests needed for a pure performance optimization with no behavior change.
cached_api_callandcached_single_itemremain untested (pre-existing gap, not introduced here).Observations
maindirectly (as opposed tonext-release). Recent perf PRs (#100, #101) targetednext-release; this one doesn't. Minor workflow inconsistency but not a blocker for a low-risk optimization.true— no conflicts.No Issues Found
✅ Logic correct
✅ Thread/concurrency safe
✅ No mutation risk on closure-captured values
✅ 935 tests passing, 18 pre-existing unrelated failures
Ready to merge.
678f7d71e0toa3e63f730f