-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Normal
-
Affects Version/s: 3.0.0rc2
-
Component/s: Packaging & Deployment
-
None
Plugins may legitimately import from picard.plugin3.cli (for example the "Create Local Plugin" plugin does `from picard.plugin3.cli import ExitCode, PluginCLI` at module level). In a packaged (PyInstaller) build this import fails at runtime with:
No module named 'picard.plugin3.cli'
Because installing a plugin from the GUI enables it right after install (enable_after_install=True, see picard/plugin3/manager/install.py), the plugin's module is imported during installation, so the failure surfaces in an "Installation Failed" dialog. It can also surface later as a "Plugin Error" when enabling an already-installed plugin.
The error only occurs in frozen/packaged builds. It does not reproduce when running Picard from source (regardless of plugin version), because picard.plugin3.cli is always importable there.
Root cause
==========
picard.plugin3.cli is referenced from Picard core in exactly one place, and that reference is an inline import inside a function used only by the picard-cli entry point:
picard/cli/plugins.py, in _run_plugins():
from picard.plugin3.cli import PluginCLI
There is no module-level import of picard.plugin3.cli reachable from the GUI entry point (tagger.py). PyInstaller's static analysis starts from tagger.py and follows module-level imports; inline imports inside functions are not reliably detected. As a result picard.plugin3.cli (and its transitive-only dependencies) are not included in the frozen GUI build, even though it is part of the plugin API surface that plugins are expected to import.
Steps to reproduce
==================
1. Use a packaged/frozen build of Picard 3 (e.g. the Windows installer build).
2. Install a plugin that imports picard.plugin3.cli at module level (e.g. "Create Local Plugin").
3. Observe the "Installation Failed" dialog: No module named 'picard.plugin3.cli'.
Expected: the plugin loads; picard.plugin3.cli is available to plugins in packaged builds.
Actual: the import fails because the module is not bundled.
Suggested fix
=============
Ensure the plugin3 public API modules that plugins may import are included in frozen builds. The minimal fix is to add picard.plugin3.cli to hiddenimports in picard.spec. Consider also auditing the rest of the picard.plugin3 public API (picard.plugin3.api, picard.plugin3.init_templates, picard.plugin3.project_config, picard.plugin3.categories, etc.) and adding any that are only reached via inline/dynamic imports, so the documented plugin API is fully available in packaged builds.