Fix _remove_plugin and get_hookcallers for multi-impl plugins #646
+80
−5
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.
Summary
Fixes #431
When a plugin registers multiple hook implementations on the same hook (e.g. via
specname), two related issues exist:HookCaller._remove_plugin()only removes the first matchingHookImplfor a plugin, then returns. This means it relies on being called multiple times to remove all implementations.PluginManager.get_hookcallers()returns duplicateHookCallerentries — one perHookImplrather than one perHookCaller. This happens to compensate for_remove_pluginonly removing one impl per call, but it's incorrect behavior for users of the public API.Changes
_remove_plugin: Remove all hookimpls for the given plugin in a single call using a list comprehension filter, instead of deleting only the first match and returning.get_hookcallers: Break out of the inner loop after finding the first matching hookimpl for a hookcaller, so eachHookCallerappears at most once in the result.get_hookcallersreturns no duplicates.431.bugfix.rsttowncrier fragment.Test plan
uv run pytest)uv run pre-commit run -a)🤖 Generated with Claude Code