feat(extract): extract call-form event.listen registrations (events v2)#33
Merged
Conversation
The events extractor now also extracts module-level SQLAlchemy event.listen(Target, "event", fn) statements - the v1 KNOWN GAP - as a new registration family sqlalchemy_listen. fn must resolve to a first-party top-level function of the same module or an imported one (reusing the calls.py import-table machinery, lifted to module level); the registration attaches to the HANDLER's artifact, which may live in another module than the listen() call, and the artifact gains a grounding edge on the registering file's module span (new role registration_site) - wiring in a third module grounds ONE artifact across THREE files (handler + target class + registration site). Only module-level calls are extracted: they run deterministically at import time, so the registration claim holds at confidence 1.0. listen() inside a function/class body, lambda/attribute listeners and the bare from-import form are documented gaps, never a wrong guess. Registrations gained form/registration_module/registration_line payload fields; call-form registrations are sorted before merging so full and incremental indexing stay byte-identical. events extractor_version 1 -> 2: all event_handler ids recompute on the next index (idempotent); purely-decorator handlers keep semantically identical payloads. Tier-1 events gate: the call-form known-gap test becomes a positive test, plus three-file provenance and two new gap assertions (9 -> 12 tests). Headline HARD gates stay fifteen.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The events extractor now also extracts module-level SQLAlchemy
event.listen(Target, "event", fn)statements — the v1 KNOWN GAP — as a new registration familysqlalchemy_listen.fnmust resolve to a first-party top-level function (same module, or imported — reusing the calls.py import-table machinery, lifted to module level with thin class delegates, the_caller_scan_rootprecedent). Precision-first: unresolvablefn(lambda / attribute / non-first-party) is skipped, never guessed.event:{fn_fq}) — which may live in another module than thelisten()call — and the artifact gains a grounding edge on the registering file's module span (new roleregistration_site). Wiring in a third module grounds one artifact across three files: handler + target class + registration site.listen(...)inside a function/class body, lambda listeners, and the barefrom sqlalchemy.event import listenform are documented gaps.form/registration_module/registration_line; call-form registrations sort before merging so full and incremental indexing stay byte-identical.Version bump
eventsextractor_version 1 → 2: allevent_handlerids recompute on the next index (idempotent re-index; orphaned rows go to the deferred GC);kb describeregenerates event-handler descriptions on its next run. Purely-decorator handlers keep semantically identical payloads. Identity rules inkb.idsuntouched.Gate
Tier-1 events oracle: the call-form known-gap test inverts into a positive test;
EXPECTED_EVENTSgains twosqlalchemy_listentuples; new tests: three-file provenance (hooks.py+db.py+wiring.py), function-bodylistengap, lambda-listener gap (9 → 12 tests). Headline HARD gates stay fifteen.Local:
ruffclean,mypy --strictclean,pytest -q→ 115 passed, 1 skipped.