Commit graph

2966 commits

Author SHA1 Message Date
Henry Oberholtzer
8e644157e8 Refactor tests, adjust changelog, move config option to new features. 2025-09-22 19:47:50 +02:00
Trey Turner
042b5d64eb test(ftintitle): fix flake, massage mypy 2025-09-21 22:27:11 +01:00
Trey Turner
6ad7c5489c test(ftintitle): parameterize tests 2025-09-21 22:27:11 +01:00
Trey Turner
f0a6059685 feat(FtInTitle): support tracks by artists != album artist 2025-09-21 22:27:11 +01:00
henry
e577df0f25
Merge branch 'master' into discogs-disambiguation-fix 2025-09-21 09:34:12 -07:00
Sebastian Mohr
c991b14e7d fix test by changing patch 2025-09-21 08:04:51 -07:00
Sebastian Mohr
34114fe915 New import location for art.py 2025-09-21 08:01:48 -07:00
J0J0 Todos
2e307b519a lastgenre: Also mock try_write in test_pretend..
and add and original genre instead empty string (clarify intention of
test / readability). Remove not really necessary assert items checks.
2025-09-21 07:07:14 +02:00
Alok Saboo
9b1537f226 Add test for --pretend option in LastGenrePlugin to skip library updates 2025-09-21 07:07:14 +02:00
Sebastian Mohr
73dc8f2bc7 fix test by changing patch 2025-09-20 14:04:48 +02:00
Sebastian Mohr
a796d6d799 New import location for art.py 2025-09-20 14:01:38 +02:00
Henry
dda265dc77 Disambiguation fix implemented & tested 2025-09-19 20:46:07 -07:00
Henry Oberholtzer
24fbc566f6 initial changes, changelog adjusted, TODO: test for various artists and update docs 2025-09-20 01:58:56 +02:00
ThinkChaos
eb83058b13 style: remove extraneous pass statements 2025-09-19 21:11:51 +01:00
ThinkChaos
b0caac871a fix: enable tracebacks for "user"/custom sqlite functions
A bit niche but I tried setting my bareasc prefix to an empty string,
and was getting an obtuse error. This should help make clearer what is
happening when queries fail.

The exception is not properly raised up the stack in the first place
because it happens across 2 FFI boundaries: the DB query
(Python -> SQLite), and the custom DB function (SQLite -> Python).
Thus Python cannot forwarded it back to itself through SQLite, and it's
treated as an "unraisable" exception.

We could override `sys.unraisablehook` to not print anything for the
original exception, and store it in a global for the outer Python
interpreter to fetch and raise properly, but that's pretty hacky,
limited to a single DB instance and query at once, and risks swallowing
other "unraisable" exceptions.
Instead we just tell the user to look above for what Python prints.

Sample output:
```
Exception ignored in: <function unidecode_expect_ascii at
0x7f7fa20bb060>
Traceback (most recent call last):
  File "site-packages/unidecode/__init__.py", line 60, in
unidecode_expect_ascii
    bytestring = string.encode('ASCII')
                 ^^^^^^^^^^^^^
AttributeError: 'bytes' object has no attribute 'encode'
Traceback (most recent call last):
  File "site-packages/beets/dbcore/db.py", line 988, in query
    cursor = self.db._connection().execute(statement, subvals)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: user-defined function raised exception

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "site-packages/beets/__main__.py", line 9, in <module>
    sys.exit(main())
             ^^^^^^
  File "site-packages/beets/ui/__init__.py", line 1865, in main
    _raw_main(args)
  File "site-packages/beets/ui/__init__.py", line 1852, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "site-packages/beets/ui/commands.py", line 1599, in list_func
    list_items(lib, decargs(args), opts.album)
  File "site-packages/beets/ui/commands.py", line 1594, in list_items
    for item in lib.items(query):
                ^^^^^^^^^^^^^^^^
  File "site-packages/beets/library.py", line 1695, in items
    return self._fetch(Item, query, sort or
self.get_default_item_sort())

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "site-packages/beets/library.py", line 1673, in _fetch
    return super()._fetch(model_cls, query, sort)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "site-packages/beets/dbcore/db.py", line 1301, in _fetch
    rows = tx.query(sql, subvals)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "site-packages/beets/dbcore/db.py", line 991, in query
    raise DBCustomFunctionError()
beets.dbcore.db.DBCustomFunctionError: beets defined SQLite function
failed; see the other errors above for details
```
2025-09-19 21:11:51 +01:00
Vrihub
c30f9603eb Fix format and lint errors 2025-09-16 17:31:42 +02:00
Vrihub
6b1c3bc582 Merge remote-tracking branch 'upstream/master' into ffnp 2025-09-16 16:01:25 +02:00
neofright
394d78de97
Replace flowery language (#6002)
Simplify wording by replacing flowery or pretentious terms throughout the project. 

A bouquet refers to trees or flowers. The etymology is pretty clear on
the Latin root via French.

Co-authored-by: Sebastian Mohr <sebastian@mohrenclan.de>
2025-09-15 09:02:22 +00:00
Šarūnas Nejus
3bc653b989
lyrics: xfail sweetslyrics end-to-end test 2025-08-30 23:10:22 +01:00
Šarūnas Nejus
44fda7ca0a
lyrics: use another beatles song for Lyricsmode
Lady Madonna apparently is gone from this website. ¯\_(ツ)_/¯
2025-08-30 23:10:22 +01:00
Šarūnas Nejus
d6b6ac3387
Replace logging f-strings with arguments 2025-08-30 23:10:21 +01:00
Šarūnas Nejus
d93ddf8dd4
Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
Šarūnas Nejus
2fccf64efe
Do not use backslashes to deal with long strings 2025-08-30 23:10:20 +01:00
Šarūnas Nejus
1c16b2b308
Replace string concatenation (' + ')
- Join hardcoded strings
- Replace concatenated variables with f-strings
2025-08-30 23:10:15 +01:00
Šarūnas Nejus
a7c83d91e9
Replace slightly more advanced attempts to use format calls 2025-08-30 22:35:00 +01:00
Šarūnas Nejus
9352a79e41
Replace percent formatting 2025-08-30 22:35:00 +01:00
Šarūnas Nejus
4a361bd501
Replace format calls with f-strings 2025-08-30 18:42:26 +01:00
Sebastian Mohr
abffa7900b Fixed tests as query formatting changed slightly. 2025-08-26 13:41:11 +02:00
J0J0 Todos
f85ba7ab3b lastgenre: Fix test_get_genre loading whitelist
- The default whitelist files were not loaded properly (at least in
  local test environments, not sure about CI yet...anyway...)
2025-08-24 09:20:36 +02:00
J0J0 Todos
7f7b900f1b lastgenre: Test canonicalization
- Test non-whitelisted genres resolving "up" in the tree.
- Test whitelisted original and whitelisted new genre resolving "up"
- Test non-whitelisted original genre resolving "up" (and deduplication
  works)
2025-08-24 09:20:36 +02:00
Šarūnas Nejus
c0675fefb8
Merge branch 'master' into multivalued-flexible-fields 2025-08-19 13:39:34 +01:00
Šarūnas Nejus
13080c17a3
Update release conversion logic accordingly 2025-08-10 16:25:05 +01:00
Šarūnas Nejus
2059a3a802
Move EventType definition to plugins.py and fix test_hook types 2025-08-09 15:44:35 +01:00
Šarūnas Nejus
54b31d01e9
Use only plugins/disabled_plugins config in plugin loading 2025-08-09 15:11:58 +01:00
Šarūnas Nejus
e9feb41709
Refactor plugin registration tests 2025-08-09 15:06:07 +01:00
Šarūnas Nejus
52bdb58a46
Simplify plugin loading mechanism
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.
2025-08-09 15:06:06 +01:00
Šarūnas Nejus
788e31b619
Slightly simplify listener registration 2025-08-09 15:04:01 +01:00
Sebastian Mohr
c2d1bc3aaf
Add py.typed marker file to support PEP 561 typing (#5906)
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.
2025-08-09 13:31:55 +02:00
Sebastian Mohr
3f23f35353 Removed duplicate importlib import. 2025-08-09 13:17:27 +02:00
Sebastian Mohr
84ae11657e Added a check for gstream plugin issues on windows. 2025-08-09 13:17:27 +02:00
Sebastian Mohr
1696789cbe Removed re and added brackets 2025-08-09 13:17:27 +02:00
Sebastian Mohr
a2136e1100 Removed now unused _is_spec_avilable function 2025-08-09 13:17:27 +02:00
Sebastian Mohr
8d134d1389 Skip module not found checks in favor for only running the test in
the ci.
2025-08-09 13:17:27 +02:00
Sebastian Mohr
586b89016b Using fixture to unload plugins. Enhance comment. Simplified get available
plugins function.
2025-08-09 13:17:27 +02:00
Sebastian Mohr
8b0af15b83 Use load_plugins directly as the plugin mixin version wants
to create an instance which is not wanted here.
2025-08-09 13:17:27 +02:00
Sebastian Mohr
3a2b6d85a4 Using plugin mixin to unload plugins. 2025-08-09 13:17:27 +02:00
Sebastian Mohr
8aa298d646 Added module cleanup, might fix errors. 2025-08-09 13:17:27 +02:00
Sebastian Mohr
4723f3de7d Instead of trying to import all plugins together, opted to test
one plugin at a time.
2025-08-09 13:17:27 +02:00
Sebastian Mohr
cfab2eb56e Some typos 2025-08-09 13:17:27 +02:00
Sebastian Mohr
355e4d3fed Added a load all plugins test. 2025-08-09 13:17:27 +02:00
Maxr1998
8db661b115
Add test 2025-07-16 21:46:03 +02:00
Šarūnas Nejus
3be4a89aee
refactor: convert _types from class attributes to cached properties
Convert static _types dictionaries to dynamic cached class properties to
enable proper plugin type inheritance and avoid mutating shared state.

Key changes:
- Replace static _types dicts with @cached_classproperty decorators
- Update cached_classproperty to support proper caching with class names
- Remove manual _types mutation in plugin loading/unloading
- Add pluginload event and cache clearing for proper plugin integration
- Fix test to trigger type checking during item creation

This ensures plugin types are properly inherited through the class
hierarchy and eliminates issues with shared mutable state between
test runs.
2025-07-16 14:45:25 +01:00
Šarūnas Nejus
e1162b7e0f
Rename test_player -> test_bpd 2025-07-16 14:06:35 +01:00
Šarūnas Nejus
a5bbe57490
Fix types in test_player 2025-07-16 14:06:34 +01:00
Šarūnas Nejus
21459c70ee
importer: provides search_ids into lookup_candidates explicitly 2025-07-16 14:06:33 +01:00
Sebastian Mohr
178e27f11f Fixed imports for all tests and added a bit of stricter type checking. 2025-07-15 15:03:14 +02:00
Šarūnas Nejus
0dd6cb3b6d
Replace assert_equal_path 2025-07-09 09:21:52 +01:00
Šarūnas Nejus
ca3adfe525
Replace assertPrem 2025-07-09 09:21:52 +01:00
Šarūnas Nejus
8dcc69e6d8
Replace _assert_image_operated 2025-07-09 09:21:52 +01:00
Šarūnas Nejus
9f6d5063d1
Replace _assertImageIsValidArt 2025-07-09 09:21:51 +01:00
Šarūnas Nejus
72caf0d2cd
Replace assertCount 2025-07-09 09:21:51 +01:00
Šarūnas Nejus
111cb562ea
Replace assertContains and assertExcludes 2025-07-09 09:21:51 +01:00
Šarūnas Nejus
3c8179a762
Replace assertAlbumImport 2025-07-09 09:21:51 +01:00
Šarūnas Nejus
c6b5b3bed3
Replace assertFileTag and assertNoFileTag 2025-07-09 09:21:50 +01:00
Šarūnas Nejus
43b8cce063
Replace assertIsDir 2025-07-09 09:21:50 +01:00
Šarūnas Nejus
ca4fa6ba10
Replace assertIsFile 2025-07-09 09:21:50 +01:00
Šarūnas Nejus
038843cdb2
Replace assertAlmostEqual and assertEqualTimes 2025-07-09 09:21:50 +01:00
Šarūnas Nejus
e36e8f1f51
Remove assert_file_in_lib 2025-07-09 09:21:49 +01:00
Šarūnas Nejus
452644bbf3
Remove assert_lib_dir_empty 2025-07-09 09:21:49 +01:00
Šarūnas Nejus
e6d5f73964
Use pathlib.Path in test_convert 2025-07-09 09:21:49 +01:00
Šarūnas Nejus
31dbd51222
Replace assertExists and assertNotExist 2025-07-09 09:21:49 +01:00
Šarūnas Nejus
c706f62fb2
Replace assertExists in test_files 2025-07-09 09:21:48 +01:00
Šarūnas Nejus
e40c7fd71c
Introduce Album.art_filepath to simplify existence checks 2025-07-09 09:21:47 +01:00
Šarūnas Nejus
d017270196
Use pathlib.Path in test_smartplaylist.py 2025-07-09 09:17:14 +01:00
Šarūnas Nejus
edd3df99ba
Introduce TestHelper.temp_dir_path 2025-07-09 09:17:14 +01:00
Šarūnas Nejus
9e4b117454
Speed up tests that only need IOMixin 2025-07-09 09:17:13 +01:00
Šarūnas Nejus
605cea9bdc
Rip away io stuff from TestHelper to IOMixin 2025-07-09 09:17:13 +01:00
Šarūnas Nejus
7cada1c9f8
Remove no-op decargs 2025-07-08 11:37:33 +01:00
Šarūnas Nejus
09b22949c0
Refactor test_query
And rewrite test_query.py
2025-07-06 16:15:30 +01:00
Šarūnas Nejus
2c6f314f4f
Replace assertNegationProperties 2025-07-06 16:15:29 +01:00
Šarūnas Nejus
2b306de0fe
Replace assertInResult and assertNotInResult 2025-07-06 16:15:29 +01:00
Šarūnas Nejus
9d088ab69f
Move human formatting functions under beets.util.units 2025-07-06 16:09:50 +01:00
Šarūnas Nejus
8937978d5f
Refactor PathQuery and add docs 2025-07-06 16:09:50 +01:00
Šarūnas Nejus
45f92ac641
Remove case_sensitive from PathQuery.__init__
The case_sensitive parameter was only used in tests, which now use
monkeypatch to control the behavior of util.case_sensitive() instead.
This simplifies the PathQuery initialization logic while maintaining
test coverage.
2025-07-06 16:09:50 +01:00
Šarūnas Nejus
a38918380d
Rewrite path query tests using pytest.mark.parametrize
And remove `force_implicit_query_detection` attribute from `PathQuery`
class.
2025-07-06 16:09:49 +01:00
Šarūnas Nejus
b40ce836d5
Add NullPathType and types to PathType 2025-07-06 16:09:49 +01:00
Šarūnas Nejus
1a045c9166
Copy paste query, types from library to dbcore 2025-07-06 16:03:46 +01:00
dhruvravii
dd6cb538ac
Fix: Spotify plugin unable to recognize Chinese and Japanese albums. (#5705)
Fixes an issue where each spotify query was converted to ascii before sending. Adds a 
new config option to enable legacy behaviour.

A file called japanese_track_request.json was made to mimic the Spotify
API response since I don't have the credentials. Entries in that will
need to be modified with the actual entries.

Co-authored-by: Sebastian Mohr <sebastian@mohrenclan.de>
Co-authored-by: Sebastian Mohr <39738318+semohr@users.noreply.github.com>
Co-authored-by: J0J0 Todos <2733783+JOJ0@users.noreply.github.com>
2025-07-01 11:08:54 +02:00
Nicolas Mémeint
4893cee5e5 Fix the MusicBrainz search not taking into account the album/recording aliases 2025-06-15 21:33:20 +01:00
Ben Stolovitz
2f98f11d57 fix local langdetect test failures
avoid linter error

avoid other linter error

fix format

changing deps (no lock!)

poetry lock?

lint & format

attempt 2 at poetry lock

crlf -> lf line endings

changelog!
2025-05-31 18:56:21 -04:00
Šarūnas Nejus
cb246c28bc
Remove dead chartlyrics
This integration test failed because `chartlyrics.com` website is no
longer available, so I'm removing it.
2025-05-31 19:17:43 +01:00
Šarūnas Nejus
0da6192a4a
Test sanitize_pairs 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
318a840af2
Rewrite distance tests 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
adbd50b237
Move distance to a separate module 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
01b6ea7898
Simplify and speed up plurality/album tags retrieval tests 2025-05-31 19:17:42 +01:00
Šarūnas Nejus
1c9aebd36c
match.current_metadata -> util.get_most_common_tags 2025-05-31 17:58:23 +01:00
Šarūnas Nejus
509cbdcbe4
Move sanitize_pairs/choices from plugins to util module 2025-05-31 17:55:41 +01:00
Ian McCowan
0f76312f31
Fix duplicate database change event send on Library.add (#5561)
## Description

Fixes #5560. Also a couple other incidental changes / improvements:
* Add `EventType` that holds the actual string literals used for event
sending. With type checking, this can prevent subtle bugs resulting from
misspelled event names.
* Fix `HiddenFileTest` by using `bytestring_path()`

## To Do

- [x] ~Documentation.~
- [x] Changelog.
- [x] Tests.

---------

Co-authored-by: J0J0 Todos <jojo@peek-a-boo.at>
Co-authored-by: J0J0 Todos <2733783+JOJ0@users.noreply.github.com>
2025-05-30 13:41:29 +00:00
Uncorrupt3318
dd2f203090
Feat: Add replace plugin (#5644)
Adds replace plugin. The plugin allows the user to replace the audio
file of a song, while keeping the tags and file name.

Some music servers keep track of favourite songs via paths and tags. Now
there won't be a need to 'refavourite'. Plus, this skips the
import/merge steps.
2025-05-27 00:17:52 +02:00
Ben Stolovitz
da5ec00aaf
[Test] Fix path tests on windows (#5803)
## Description

Fixes #5802.

Today, tests fail on most Windows machines because we hard-code `D:` as
the root drive, but most machines use `C:`. This change uses the same
normalization function in the test assertion to ensure the drives match.

## To Do

- [ ] ~~Documentation.~~
- [x] Changelog.
- [x] Tests. (this is a tests change)

## What changed?

* Updated tests to generate the drive name via normalization, instead of
hard-coding `D:`.
* Updated the `Item::destination()` method to document the
`relative_to_libdir` param.

## How tested?

* [x] Tests pass locally.
2025-05-26 19:24:57 +02:00