Seems like readthedocs build expects docs dependencies to be available
as an extra, see one of the failing builds:
https://app.readthedocs.org/projects/beets/builds/26079213/.
You can see this has been failing due to missing 'pydata_sphinx_theme'
which is one of our dependencies:
```
raise ThemeError(__('no theme named %r found (missing theme.toml?)') % name)
sphinx.errors.ThemeError: no theme named 'pydata_sphinx_theme' found (missing theme.toml?)
Theme error:
no theme named 'pydata_sphinx_theme' found (missing theme.toml?)
```
This was a very bad idea since this made CI operate within the context
of the *base* branch, which meant that the tests were testing code in
the `master` branch instead of the branch that was to be merged!
Seems like readthedocs build expects docs dependencies to be available
as an extra, see one of the failing builds: https://app.readthedocs.org/projects/beets/builds/26079213/.
You can see this has been failing due to missing 'pydata_sphinx_theme':
raise ThemeError(__('no theme named %r found (missing theme.toml?)') % name)
sphinx.errors.ThemeError: no theme named 'pydata_sphinx_theme' found (missing theme.toml?)
Theme error:
no theme named 'pydata_sphinx_theme' found (missing theme.toml?)
I was running the `convert` plugin with the following config:
```
no_convert: samplerate:..48000 bitdepth:..16
```
but anything that was 24/48 was also not being converted, this was due
to the code returning `False` for `should_transcode` if any part of the
query matches, rather than considering the whole query. This meant that
`bitdepth:...16` was being ignored.
I have changed this so the `no_convert` value is considered as one
query.
Fixes#5456.
This pull request updates the `tekstowo` backend in the `lyrics` plugin
to fetch lyrics directly from the Tekstowo.pl website. Recent updates to
their website made the previous search-based approach unworkable.
## Changes
1. **Refactor Backend Classes:**
- Introduced a new `DirectBackend` class for backends that fetch lyrics
directly.
- Updated `MusiXmatch` and `Tekstowo` classes to inherit from
`DirectBackend`.
2. **Encoding and URL Building:**
- Added `encode` and `build_url` methods to `DirectBackend` for URL
encoding and construction.
- Replaced our custom encoding functionality with `unidecode`.
3. **Tekstowo Backend:**
- Added encoding logic, which converts artist and title to the format
used by tekstowo.
- Removed the search functionality (`parse_search_results`), its test
and related search html files.
- Updated `artist` and `title` checks from `extract_lyrics`.
- Refactored Tekstowo backend to fetch lyrics directly from song pages.
- Added `encode` method to convert artist and title to their URL format,
where non-alphanumeric characters are replaced with underscores.
- Removed the now redundant search functionality and associated tests.
- Simplified `extract_lyrics` method to directly parse lyrics without
any checks.
Fixes#5441
This small change explicitly passes the `for_artist` keyword to the
`plugins.feat_tokens` function that constructs the regex for matching
existing "feat. X" parts in song titles.
Previously, it was not passed and set to the default (`True`), which
caused using the pattern intended for the artist field to also be used
for the title field.
This caused some false positives as shown in #5441
Since the `for_artist` keyword has been removed from
`ftintitle.contains_feat`, the unit tests need to be updated.
This includes the deletion of the test cases that test the
`for_artist=True` delimiters.
Remove the optional `for_artist` keyword in the
`ftintitle.contains_feat` function and hardcode it to False, since it is
always used like this in the ftintitle plugin.
The old version of the `ftintitle.contains_feat` function could lead to
false positives by matching words like "and" and "with" in the title,
even if there was no "feat. X" part.
With this commit, the `for_artist` keyword is explicitly passed to the
`plugins.feat_tokens` function to disable these matches when matching a
title (and not an artist).
The previous version of the `plugins.feat_tokens` regular expression
only matched "feat. X" parts if preceded by a space. This caused missed
detections in the `ftintitle.contains_feat` function.
This commit adds unit tests for the updated regex that also matches
"feat. X" parts within parentheses and brackets
When checking whether a title or artist contains a feature, it now also
detects them when they are in parentheses or brackets, i.e., "Song Name
(feat. XYZ)" will return true.
#### Context
I noticed one of recently merged PRs used `unittest` assertions that we
are migrating from. Thus, I thought it would be a good idea to configure
our linting to catch such issues in the future. Since I was here, I
replaced our multiple linting and formatting tools with a single tool,
Ruff, to simplify and speed up our development workflow.
#### Summary
This PR migrates the codebase from using isort, Black and Flake8 to Ruff
for code formatting and linting. The changes include updates to the
GitHub Actions workflow, pre-commit configuration, and documentation to
reflect the new tooling.
#### Changes
1. **GitHub Actions Workflow**
- Updated `.github/workflows/lint.yml` to use `poetry install
--only=lint` and `poe lint --output-format=github`.
2. **Pre-commit Configuration**
- Replaced Black and Isort with Ruff in `.pre-commit-config.yaml`.
3. **Documentation**
- Updated `CONTRIBUTING.rst` to reflect the use of Ruff for formatting
and linting.
- Modified instructions for running tests and handling external API
requests.
4. **Poetry Configuration**
- Removed Black, Isort, Flake8, and related dependencies from
`poetry.lock` and `pyproject.toml`.
- Added Ruff as the new linter and formatter in `pyproject.toml`.
5. **Setup Configuration**
- Removed Flake8 configuration from `setup.cfg`.
6. **Git blame**
- Introduced `.git-blame-ignore-revs` file to keep git blame clean from
formatting
changes. Configure your local `beets` repository to use this file by
running:
```fish
$ git config --local blame.ignoreRevsFile .git-blame-ignore-revs
```
#### Benefits
- **Performance**: Ruff is known for its speed and efficiency, which
should improve the developer experience.
- **Consolidation**: Using a single tool for both formatting and linting
simplifies the development workflow.
#### How to Test
1. **Linting and Formatting**
- Run `poe check-format` to check for formatting issues.
- Run `poe format` to format the codebase.
- Run `poe lint` to check for linting issues.
2. **Pre-commit Hooks**
- Ensure pre-commit hooks are working correctly by running `pre-commit
run --all-files`.
3. **CI Pipeline**
- Verify that the GitHub Actions workflow completes successfully.
#### Notes
- Contributions migrating existing tests from `unittest` to `pytest` are
welcome.
- External API requests should be mocked using `requests_mock` and
tested weekly in the integration test suite.
#### References
- [Ruff Documentation](https://docs.astral.sh/ruff/)
- [Pre-commit Hooks](https://pre-commit.com/hooks.html)
---
This PR aims to streamline our development process by adopting Ruff, a
modern and efficient tool for Python code formatting and linting.
This commit introduces a `.git-blame-ignore-revs` file to the
repository. The purpose of this file is to list specific commit hashes
that should be ignored when using the `git blame` command. This is
useful for ignoring commits that involve large-scale formatting changes,
refactoring, or other non-functional changes that would otherwise
clutter the blame history.
I added a couple of previous commit hashes which reformatted the code.
Configure this repository to use this file:
git config --local blame.ignoreRevsFile .git-blame-ignore-revs
The variable in `test_ordered_enum` was flagged for naming issues, and
I noticed that `OrderedEnum` is essentially `enum.IntEnum`.
I guess `OrderedEnum` exists because it was created before
`enum.IntEnum` was made available in Python 3.4. We do not need it
anymore though, so it's now gone.
* Replace `noqa` comments in `assert...` method definitions with
a configuration option to ignore these names.
* Use the `__all__` variable to specify importable items from the
module, replacing `*` imports and `noqa` comments for unused imports.
* Address issues with poorly named variables and methods by renaming
them appropriately.
- Fix imports
- Fix pytest issues
- Do not assign lambda as variable
- Use isinstance instead of type to check type
- Rename ambiguously named variables
- Name custom errors with Error suffix