Skip to content

fix: mbpseudo issues when applying pseudorelease#6512

Merged
snejus merged 11 commits intobeetbox:masterfrom
MartinCa:fix/mbpseudo-raw-data
May 8, 2026
Merged

fix: mbpseudo issues when applying pseudorelease#6512
snejus merged 11 commits intobeetbox:masterfrom
MartinCa:fix/mbpseudo-raw-data

Conversation

@MartinCa
Copy link
Copy Markdown
Contributor

@MartinCa MartinCa commented Apr 9, 2026

Description

I have not created an issue for this but I tried to use mbpseudo to apply this pseudorelease: https://musicbrainz.org/release/6c100fef-6abf-41c4-bd21-6f9becaaab6c

When doing that I encountered two errors as seen below, this PR should fix those issues. The second issue was only apparent once the first issue was fixed.

Sending event: import_task_choice
Traceback (most recent call last):
  File "/lsiopy/bin/beet", line 6, in <module>
    sys.exit(main())
             ^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/ui/__init__.py", line 1013, in main
    _raw_main(args)
  File "/lsiopy/lib/python3.12/site-packages/beets/ui/__init__.py", line 992, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/lsiopy/lib/python3.12/site-packages/beets/ui/commands/import_/__init__.py", line 131, in import_func
    import_files(lib, byte_paths, query)
  File "/lsiopy/lib/python3.12/site-packages/beets/ui/commands/import_/__init__.py", line 75, in import_files
    session.run()
  File "/lsiopy/lib/python3.12/site-packages/beets/importer/session.py", line 237, in run
    pl.run_parallel(QUEUE_SIZE)
  File "/lsiopy/lib/python3.12/site-packages/beets/util/pipeline.py", line 471, in run_parallel
    raise exc_info[1].with_traceback(exc_info[2])
  File "/lsiopy/lib/python3.12/site-packages/beets/util/pipeline.py", line 336, in run
    out = self.coro.send(msg)
          ^^^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/util/pipeline.py", line 195, in coro
    task = func(*args, task)
           ^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/importer/stages.py", line 217, in user_query
    _apply_choice(session, task)
  File "/lsiopy/lib/python3.12/site-packages/beets/importer/stages.py", line 323, in _apply_choice
    task.apply_metadata()
  File "/lsiopy/lib/python3.12/site-packages/beets/importer/tasks.py", line 263, in apply_metadata
    self.match.apply_metadata()
  File "/lsiopy/lib/python3.12/site-packages/beets/autotag/hooks.py", line 609, in apply_metadata
    for item, data in self.merged_pairs:
                      ^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/autotag/hooks.py", line 603, in merged_pairs
    (i, ti.merge_with_album(self.info))
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/autotag/hooks.py", line 482, in merge_with_album
    album = album_info.raw_data
            ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/functools.py", line 998, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/autotag/hooks.py", line 301, in raw_data
    data = {**super().raw_data}
              ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/functools.py", line 998, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/lsiopy/lib/python3.12/site-packages/beets/autotag/hooks.py", line 176, in raw_data
    data = self.__class__(**self.copy())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: PseudoAlbumInfo.__init__() missing 2 required positional arguments: 'pseudo_release' and 'official_release'
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/martin/personal/src-ext/beets/beets/__main__.py", line 24, in <module>
    main(sys.argv[1:])
    ~~~~^^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/ui/__init__.py", line 1013, in main
    _raw_main(args)
    ~~~~~~~~~^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/ui/__init__.py", line 992, in _raw_main
    subcommand.func(lib, suboptions, subargs)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/ui/commands/import_/__init__.py", line 131, in import_func
    import_files(lib, byte_paths, query)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/ui/commands/import_/__init__.py", line 75, in import_files
    session.run()
    ~~~~~~~~~~~^^
  File "/home/martin/personal/src-ext/beets/beets/importer/session.py", line 237, in run
    pl.run_parallel(QUEUE_SIZE)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/util/pipeline.py", line 471, in run_parallel
    raise exc_info[1].with_traceback(exc_info[2])
  File "/home/martin/personal/src-ext/beets/beets/util/pipeline.py", line 336, in run
    out = self.coro.send(msg)
  File "/home/martin/personal/src-ext/beets/beets/util/pipeline.py", line 195, in coro
    task = func(*args, task)
  File "/home/martin/personal/src-ext/beets/beets/importer/stages.py", line 217, in user_query
    _apply_choice(session, task)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/importer/stages.py", line 326, in _apply_choice
    task.add(session.lib)
    ~~~~~~~~^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/importer/tasks.py", line 503, in add
    self.album = lib.add_album(self.imported_items())
                 ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/library/library.py", line 83, in add_album
    item.add(self)
    ~~~~~~~~^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/library/models.py", line 84, in add
    super().add(lib)
    ~~~~~~~~~~~^^^^^
  File "/home/martin/personal/src-ext/beets/beets/dbcore/db.py", line 717, in add
    self.store()
    ~~~~~~~~~~^^
  File "/home/martin/personal/src-ext/beets/beets/library/models.py", line 74, in store
    super().store(fields)
    ~~~~~~~~~~~~~^^^^^^^^
  File "/home/martin/personal/src-ext/beets/beets/dbcore/db.py", line 659, in store
    tx.mutate(
    ~~~~~~~~~^
        f"INSERT INTO {self._flex_table} "
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...
        (self.id, key, value),
        ^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/martin/personal/src-ext/beets/beets/dbcore/db.py", line 1039, in mutate
    return self.db._connection().execute(statement, subvals).lastrowid
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
sqlite3.ProgrammingError: Error binding parameter 3: type 'dict' is not supported
  • [ x ] Documentation.
  • [ x ] Changelog.
  • [ x ] Tests.

@MartinCa MartinCa requested review from a team and asardaes as code owners April 9, 2026 08:35
Copilot AI review requested due to automatic review settings April 9, 2026 08:35
@github-actions github-actions Bot added the mbpseudo mbpseudo plugin label Apr 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fix mbpseudo crash when user pick pseudo-release during import. It make PseudoAlbumInfo.raw_data work with new Info.raw_data behavior, and it stop bad dict data from leaking into item/album flex fields.

Changes:

  • Override PseudoAlbumInfo.raw_data to build plain AlbumInfo for raw export, so no TypeError from self.__class__(**self.copy()).
  • Fix _adjust_final_album_match to write new mapping to match.mapping (not into album_info dict data).
  • Add regression tests and changelog entry for both crash cases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
beetsplug/mbpseudo.py Fix raw_data construction for PseudoAlbumInfo and fix mapping update target.
test/plugins/test_mbpseudo.py Add regression tests for raw_data and mapping leak to prevent sqlite bind crash.
docs/changelog.rst Document both fixed crashes for users.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.15%. Comparing base (e58d404) to head (cde2dd1).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6512      +/-   ##
==========================================
+ Coverage   72.11%   72.15%   +0.03%     
==========================================
  Files         159      159              
  Lines       20641    20645       +4     
  Branches     3269     3269              
==========================================
+ Hits        14886    14897      +11     
+ Misses       5048     5041       -7     
  Partials      707      707              
Files with missing lines Coverage Δ
beetsplug/mbpseudo.py 84.81% <100.00%> (+4.93%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@snejus snejus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - just simplify the changelog note to a higher-level description.

Comment thread docs/changelog.rst Outdated
@snejus
Copy link
Copy Markdown
Member

snejus commented Apr 14, 2026

Thanks!

@snejus snejus enabled auto-merge April 14, 2026 23:21
auto-merge was automatically disabled May 8, 2026 10:25

Head branch was pushed to by a user without write access

@snejus snejus enabled auto-merge May 8, 2026 12:38
@snejus snejus disabled auto-merge May 8, 2026 12:53
@snejus snejus merged commit 3248770 into beetbox:master May 8, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mbpseudo mbpseudo plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants