This PR centralises plugin loading logic inside `beets.plugins` module.
- Removed intermediatery `_classes` variable by initialising plugins
immediately.
- Simplified listeners registration by defining listener variables in
the base
`BeetsPlugin` class, and making the `register_listener` method a
`@classmethod`.
- Simplified plugin test setup accordingly.
Centralise plugin loading in `beets.plugins` and refactor the plugin
loading system to be more straightforward and eliminate complex mocking
in tests. Replace the two-stage class collection and instantiation
process with direct instance creation and storage.
Add plugins.PluginImportError and adjust plugin import tests to only
complain about plugin import issues.
Add `py.typed` marker file to support PEP 561 typing
This PR adds a `py.typed` marker file to the package directory to
indicate that the package includes inline type hints and is PEP 561
compliant.
Before:
```
Traceback (most recent call last):
File "/nix/store/yk2m7a9wdmh8fz8ywca0c73sc5ad2zm6-beets-2.3.1/lib/python3.13/site-packages/beetsplug/discogs.py", line 312, in get_album_info
result.refresh()
~~~~~~~~~~~~~~^^
File "/nix/store/007cfg4f295dz064bl9a2cjw10vlpc83-python3.13-discogs-client-2.8/lib/python3.13/site-packages/discogs_client/models.py", line 204, in refresh
data = self.client._get(self.data['resource_url'])
File "/nix/store/007cfg4f295dz064bl9a2cjw10vlpc83-python3.13-discogs-client-2.8/lib/python3.13/site-packages/discogs_client/client.py", line 114, in _get
return self._request('GET', url)
~~~~~~~~~~~~~^^^^^^^^^^^^
File "/nix/store/007cfg4f295dz064bl9a2cjw10vlpc83-python3.13-discogs-client-2.8/lib/python3.13/site-packages/discogs_client/client.py", line 111, in _request
raise HTTPError(body['message'], status_code)
discogs_client.exceptions.HTTPError: 404: That release does not exist or may have been deleted.
```
After:
```
Discogs release not found: <Release 20919814 'Kumi Tanioka, Yae - Final Fantasy Crystal Chronicles Original Soundtrack'>: 404: That release does not exist or may have been deleted.
```
Here's the link to the relevant release, which [shows up in search
results](https://www.discogs.com/search?q=Kumi+Tanioka%2C+Yae+-+Final+Fantasy+Crystal+Chronicles+Original+Soundtrack&type=all)
but 404s if you click on it:
https://www.discogs.com/release/20919814-Kumi-Tanioka-Yae-Final-Fantasy-Crystal-Chronicles-Original-Soundtrack
Add the artist and album information to the item template in the web
plugin.
When searching for an item, Instead of
`` Doo Woop (That Thing)``
the interface now shows
``Lauryn Hill - The Miseducation of Lauryn Hill - Doo Wop (That Thing)``
which is arguably clearer, and matches the default output of `beet ls`
in the cli.
## Summary
See https://github.com/beetbox/beets/discussions/5891 for context.
This PR introduces a deprecation system for module structure changes and
deprecated functionality in the beets codebase:
### Key Changes
**New deprecation infrastructure:**
- Add `deprecate_imports()` utility function to handle deprecated module
imports with warnings
- Implement `__getattr__` hooks in modules to intercept and redirect
deprecated imports
- Deprecate previously removed imports in `beets.library` and
`beets.autotag`
- Deprecate `decargs` function.