Skip to content

Raise ValueError when unregister's plugin and name disagree - #759

Merged
RonnyPfannschmidt merged 5 commits into
mainfrom
claude/project-thread-yz2zw2
Oct 9, 2026
Merged

RonnyPfannschmidt merged 5 commits into
mainfrom
claude/project-thread-yz2zw2

Conversation

@RonnyPfannschmidt

@RonnyPfannschmidt RonnyPfannschmidt commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Requested by Ronny · project thread

🤖 Written by Claude Opus 5.5 via Claude Code for the pluggy maintainers; I prompted it, it did the work, I read it.

Before: PluginManager.unregister(plugin, name) looks up hook callers by plugin but removes the registry entry by name, and never checks that the two refer to the same plugin, even though the docstring says they "must agree". pm.unregister(a, "b") strips a's hookimpls and drops b's registry entry, while b's impl keeps being called. The same happens when plugin is not registered at all but name belongs to another plugin. Separately, a falsy plugin object (for example one whose __len__ returns 0) loses its hookimpls on unregister but keeps its registry entry, so registering it again fails.

After: when both arguments are given and they disagree in either direction, unregister raises ValueError before changing anything. Falsy plugins are fully unregistered. Agreeing arguments and the blocked-name case (test_unregister_blocked) behave as before.

How: a check in the plugin-and-name branch of unregister. Registry entries are now compared with is not None instead of tested for truthiness, both in unregister and in load_setuptools_entrypoints. Added tests for both bugs and a changelog fragment.

This replaces the closed #747, which skipped the check whenever plugin was not registered and so missed the second case. This is an independent implementation.

Follow-ups found while auditing registration, kept out of this PR: #760, #761, #762, #763.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6

claude added 2 commits October 8, 2026 09:09
unregister() looks hook callers up by plugin but removes the registry
entry by name. When both are passed and refer to different plugins,
one plugin loses its hook implementations while another loses its
registry entry. Validate both directions before mutating anything.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6
claude added 2 commits October 8, 2026 09:13
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6
unregister() and load_setuptools_entrypoints() tested registry entries
by truthiness, so a plugin defining __len__ returning 0 lost its
hookimpls but kept its registry entry. Compare against None instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VNXnGZy9Gu3kQqgECeCMM6
RonnyPfannschmidt pushed a commit that referenced this pull request Oct 9, 2026
The old guard skipped the delete when the name maps to None (blocked),
and the assert only existed to narrow the type for mypy (added with the
2019 type annotations). With the earlier branches, the only way to reach
the pop with a blocked name is unregister(plugin, name) where the two
disagree, which #759 turns into a ValueError.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZTVJoihfHRVor2TQqGTRn
@RonnyPfannschmidt
RonnyPfannschmidt added this pull request to stack #769 October 9, 2026 12:13
@RonnyPfannschmidt
RonnyPfannschmidt merged commit 8242055 into main Oct 9, 2026
20 checks passed
@RonnyPfannschmidt
RonnyPfannschmidt deleted the claude/project-thread-yz2zw2 branch October 9, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants