Skip to content

fix: unbind disabled plugin handlers before reload#9284

Open
wcqqq1214 wants to merge 2 commits into
AstrBotDevs:masterfrom
wcqqq1214:fix/9280-handler-unbind
Open

fix: unbind disabled plugin handlers before reload#9284
wcqqq1214 wants to merge 2 commits into
AstrBotDevs:masterfrom
wcqqq1214:fix/9280-handler-unbind

Conversation

@wcqqq1214

@wcqqq1214 wcqqq1214 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #9280

Modifications / Changes


Screenshots or Test Results / Verification

Reproduction path covered by the regression test:

  1. Register a plugin handler while the plugin is deactivated.
  2. Enable the plugin through turn_on_plugin().
  3. Verify the old handler is unbound before the plugin is loaded again.
  4. Invoke the handler and verify that the instance and event arguments are passed exactly once.

Automated verification:

  • uv run pytest -q1797 passed, 6 warnings
  • uv run ruff check astrbot/core/star/star_manager.py tests/test_plugin_manager.py — all checks passed
  • uv run ruff format --check astrbot/core/star/star_manager.py tests/test_plugin_manager.py — both files already formatted
  • git diff --check — passed

Manual WebUI verification on AstrBot v4.26.6:

  • Installed astrbot_plugin_livingmemory, disabled it, restarted AstrBot, and enabled it again.
  • Sent a real ChatUI request through the configured model provider.
  • The UI returned OK; no handler argument-count TypeError appeared.
  • An unrelated embedding-provider initialization timeout was observed because no embedding provider was configured.

Checklist

  • If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • My changes have been well-tested, and verification steps are provided above.
  • I have ensured that no new dependencies are introduced.
  • My changes do not introduce malicious code.

Summary by Sourcery

Ensure plugin enablement reloads deactivated plugins with stale handlers correctly by unbinding handlers when turning a plugin back on.

Bug Fixes:

  • Prevent previously disabled plugins from keeping stale handlers that would be wrapped or invoked multiple times after re-enabling.

Tests:

  • Add a regression test verifying that enabling a previously deactivated plugin rebinds its handlers so requests are handled exactly once.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a force_unbind parameter to the plugin reload method, allowing plugins to be unbound during reload even if they are not currently activated. This parameter is utilized when turning on a plugin to ensure handlers are correctly rebound. Additionally, corresponding unit tests have been updated and a new test has been added to verify this behavior. The review feedback suggests adding **kwargs to the signature of a mocked load function in the new test to improve robustness and maintain consistency with other mocks in the test suite.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread tests/test_plugin_manager.py Outdated
async def mock_global_put(*_):
pass

async def mock_load(specified_module_path=None):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For robustness and consistency with other mock_load definitions in this test file, consider adding **kwargs to the signature of mock_load. This prevents the mock from breaking if the arguments passed to load are changed or expanded in the future.

Suggested change
async def mock_load(specified_module_path=None):
async def mock_load(specified_module_path=None, **kwargs):

@wcqqq1214 wcqqq1214 marked this pull request as ready for review July 14, 2026 15:41
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Jul 14, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The new force_unbind parameter on reload changes behavior but isn’t documented in the method’s docstring; consider updating the docstring (and any type hints/comments nearby) to explain when and why force_unbind should be used and what it does.
  • The name force_unbind is a bit vague at the call site (reload(plugin_name, force_unbind=True)); consider a more explicit name like force_unbind_handlers or adding a short inline comment at the call to clarify that it unbinds handlers even for previously deactivated plugins.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `force_unbind` parameter on `reload` changes behavior but isn’t documented in the method’s docstring; consider updating the docstring (and any type hints/comments nearby) to explain when and why `force_unbind` should be used and what it does.
- The name `force_unbind` is a bit vague at the call site (`reload(plugin_name, force_unbind=True)`); consider a more explicit name like `force_unbind_handlers` or adding a short inline comment at the call to clarify that it unbinds handlers even for previously deactivated plugins.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] reload() 跳过 disabled 插件解绑导致 handler 参数+1 / self=None

1 participant