* Move genre-to-genres migration into a dedicated Migration class and
wire it into Library._migrations for items and albums.
* Add batched SQL updates via mutate_many and share the multi-value
delimiter as a constant.
* Cover migration behavior with new tests.
I initially attempted to migrate using our model infrastructure
/ Model.store(), see the comparison below:
Durations migrating my library of ~9000 items and ~2300 albums:
1. Using our Python logic: 11 minutes
2. Using SQL directly: 4 seconds
That's why I've gone ahead with option 2.
* Update configuration handling to use fully typed confuse API which
will be released in confuse `v2.2.0`.
* Use `Subview`, `.sequence()`, `MappingTemplate`, and typed `OneOf`.
* Replace 'naked' configuration dictionary access with typed
`.get/.as_*` equivalents.
* Add typing annotations and `cached_property` where appropriate.
* Fix related issues in `discogs`, `fetchart`, `lyrics`, `playlist`,
`smartplaylist`, and `titlecase` plugins.
> [!IMPORTANT]
> Depends on https://github.com/beetbox/confuse/pull/187 being merged
and released (as `v2.2.0`)
Added note about setting the translator resource region to Global to
avoid 401 errors.
## Description
Had a bit of trouble with the lyrics plugin where the translator was not
working. Creating a global resource instead of a regional one fixed the
issue. Added a small note to the documentation so that people won't run
into the same issue in the future.
For a bit more info, you need to specify the region in the request
headers if its a regional resource. This is not required for a global
one.
I got a little bit nerdsniped by the problems observed in #5027. In
short, my high-level diagnosis in
https://github.com/beetbox/beets/pull/5027#issuecomment-1857953929 seems
to have been correct: other tests were suppressing the legitimate
failure of a flaky test.
I found the problem by running other tests before the problem test, like
this:
```
$ pytest -k 'test_nonexistant_db or test_delete_removes_item' test/test_ui.py
```
When running `test_nonexistant_db` alone, it fails. When running it like
this with another test that goes first, it passes. That's the problem.
However, `test_delete_removes_item` is just one example that works to
make this problem happen. It appeared that _any_ test in a class that
used our `_common.TestCase` base class had this power. I tracked down
the issue to our `DummyIO` utility, which was having an unintentional
effect even when it was never actually used.
Here's the solution. Instead of restoring `sys.stdin` to
`sys.__stdin__`, we now restore it to whatever it was before we
installed out dummy I/O hooks. This is relevant in pytest, for example,
which installs its *own* `sys.stdin`, which we were then clobbering.
This was leading to the suppression of test failures observed in #5021
and addressed in #5027.
The CI will fail for this PR because it now (correctly) exposes a
failing test. Hopefully by combining this with the fixes in the works in
#5027, we'll be back to a passing test suite. 😃 @Phil305, could
you perhaps help validate that hypothesis?
Edit: @snejus:
I've now consolidated test I/O handling by removing the legacy
`control_stdin`/`capture_stdout` context managers and the custom
`DummyOut` stream, replacing them with a pytest-driven `io` fixture
that:
- provides controllable `stdin` via a lightweight `DummyIn`
- captures `stdout` via `capteesys`
- attaches a `DummyIO` helper to test classes as `self.io`
## Description
Fixes#6302
Todo: Test. I could not figure out how to add a test for this bug.
<!--
- If you believe one of below checkpoints is not required for the change
you
are submitting, cross it out and check the box nonetheless to let us
know.
For example: - [x] ~Changelog~
- Regarding the changelog, often it makes sense to add your entry only
once
reviewing is finished. That way you might prevent conflicts from other
PR's in
that file, as well as keep the chance high your description fits with
the
latest revision of your feature/fix.
- Regarding documentation, bugfixes often don't require additions to the
docs.
- Please remove the descriptive sentences in braces from the enumeration
below,
which helps to unclutter your PR description.
-->
- [x] Documentation. (If you've added a new command-line flag, for
example, find the appropriate page under `docs/` to describe it.)
- [x] Changelog. (Add an entry to `docs/changelog.rst` to the bottom of
one of the lists near the top of the document.)
- [x] Tests. (Very much encouraged but not strictly required.)
This PR hardens the release/changelog generation pipeline so ReST ->
Markdown conversion produces stable, correctly formatted links and
inline code.
- Fix broken rendering of generated references by ensuring RST
`~`-shortened forms like ``` `:class:`~beetsplug._utils...``` are
converted into real Markdown links.
- Updates `extra/release.py` to generate clearer link text for CLI
command refs (e.g., `list-cmd` becomes 'list command') while keeping the
same documentation targets.
- Simplifies the Markdown post-processing step by removing the redundant
`MD_REPLACEMENTS` layer, reducing ad-hoc formatting logic in the release
script.
- Standardizes changelog section header structure in
`docs/changelog.rst` (and the release template) to align with
Sphinx/ReST conventions and avoid ambiguous colon-based headers.
- Strengthens CI by extending `lint-docs` in `pyproject.toml` to fail on
single-backtick inline literals in `.rst`, enforcing double-backtick
literals so `pandoc` does not emit meaningless `<span
class="title-ref">...` output that breaks Markdown rendering.
Net effect: more predictable release notes output, fewer conversion edge
cases, and earlier detection of docs formatting that would render
incorrectly downstream.
Create a centralised pytest fixture to provide controllable stdin and
captured stdout in all tests. Simplify DummyIO/DummyIn and remove the
custom DummyOut implementation and make use of pytest builtin fixtures.
Create a centralised pytest fixture to provide controllable stdin and
captured stdout that can be applied to any tests, regardless whether
they are based on pytest or unittest.
* `io` fixture can be used as a fixture in pytest-based tests
* `IOMixin` can be used to attach `io` attribute to any test class,
including `unittest.TestCase`
Fixes#6355
- Fix `plugins/musicbrainz` handling of very large MusicBrainz releases
by passing the missing `limit` and `includes` kwargs to
`mb_api.browse_recordings`.