Refactor musicbrainz to reduce cognitive complexity#6530
Refactor musicbrainz to reduce cognitive complexity#6530
Conversation
|
Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry. |
7c0b1e3 to
804c835
Compare
There was a problem hiding this comment.
Pull request overview
grug see PR try break big MusicBrainz parse monster into small helpers, plus new test factories, to make brain hurt less. Goal say “no user-facing change”, but grug spot few behavior leaks and test factory sharp edge.
Changes:
- Split
MusicBrainzPlugin.album_infoparsing into smaller helpers and add TypedDict contracts. - Add factory-boy based factories for MusicBrainz payloads and refactor tests to use them (plus one snapshot-style assertion).
- Add
pytest-factoryboydependency (and lockfile updates).
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| beetsplug/musicbrainz.py | Refactor parsing into helpers; new date/alias logic; new medium/track iteration helper. |
| test/plugins/test_musicbrainz.py | Switch tests to new factories and consolidate many assertions into one snapshot-style test. |
| test/plugins/factories/musicbrainz.py | New deterministic-ish payload factories for MusicBrainz structures. |
| test/plugins/factories/init.py | New package marker for factories. |
| pyproject.toml | Add pytest-factoryboy dependency. |
| poetry.lock | Lock dependency graph for new test deps. |
804c835 to
c2528ca
Compare
c2528ca to
2785606
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6530 +/- ##
=======================================
Coverage 70.99% 70.99%
=======================================
Files 150 150
Lines 19124 19124
Branches 3078 3078
=======================================
Hits 13577 13577
Misses 4896 4896
Partials 651 651
🚀 New features to boost your workflow:
|
|
I haven't had a chance to look too closely at the code but at least on my library this doesn't cause any unexpected tagging changes! |
2785606 to
0a40300
Compare
MusicBrainz Plugin Refactor
Summary
A broad internal refactor of
beetsplug/musicbrainz.pyand its test suite. No user-facing behaviour changes are intended. The goal is to make parsing logic easier to understand, test, and maintain.This PR halves the cognitive complexity in
musicbrainzplugin:Before
After
Production Code Changes
Parsing Decomposition
The monolithic
album_infomethod is broken into focused@staticmethodhelpers, each returning a typedTypedDict:_parse_artist_credits_flatten_artist_credit/_multi_artist_credit_parse_release_groupalbumtype,original_year, etc._parse_label_infoslabel,catalognum_parse_genres_parse_external_ids_parse_work_relations_parse_artist_relationsget_tracks_from_mediumEach helper returns a typed
TypedDict, making the data contract explicit and the code easier to compose with**kwargsunpacking intoAlbumInfo/TrackInfo.Other Simplifications
_set_date_str(mutable, side-effecting) is replaced by_get_date, a pure function returning(year, month, day)._preferred_release_eventand_preferred_aliasare simplified.@cached_propertyentries (ignored_media,ignore_data_tracks,ignore_video_tracks) are moved up to sit with other class-level properties.Test Infrastructure Changes
Factory Layer (
test/plugins/factories/musicbrainz.py)factory-boy/pytest-factoryboyare added as test dependencies. A new factory module introduces composable, deterministic factories:AliasFactory,ArtistFactory,ArtistCreditFactoryRecordingFactory,TrackFactory,MediumFactoryReleaseGroupFactory,ReleaseFactoryFactories use a shared
_IdFactorybase class that generates stable, predictable UUIDs (00000000-0000-0000-0000-000000001001, etc.) based on anid_base+indexpair. This makes assertions on IDs readable and deterministic without hard-coded magic strings.Before:
After:
Test Consolidation
Many small single-field assertion tests that each constructed an identical release are collapsed into a single
test_parse_releasesnapshot assertion, covering allAlbumInfofields at once. This reduces redundant fixture setup and makes it immediately obvious what the full output ofalbum_infolooks like for a default release.The hand-rolled
_make_release/_make_recordinghelpers are removed entirely, replaced by composable factory calls using factory-boy's__double-underscore traversal syntax: