Python 3.13 support
Problem
Python 3.13 removed the imghdr module as part of PEP-594 cleanup.
https://docs.python.org/3.13/whatsnew/3.13.html#summary-release-highlights
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build; python3.13 -m pytest -k "not test_completion"
============================= test session starts ==============================
platform linux -- Python 3.13.0rc2, pytest-8.3.2, pluggy-1.5.0
cachedir: /tmp/pytest_cache
rootdir: /<<PKGBUILDDIR>>
configfile: setup.cfg
plugins: typeguard-4.3.0, anyio-4.4.0
collected 72 items / 21 errors
==================================== ERRORS ====================================
____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_art_resize.py _____
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_art_resize.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_art_resize.py:22: in <module>
from beets.test import _common
beets/test/_common.py:26: in <module>
import beets.library # noqa: E402
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_autotag.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_autotag.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_autotag.py:21: in <module>
from beets import autotag, config
beets/autotag/__init__.py:20: in <module>
from beets.library import Item
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
__ ERROR collecting .pybuild/cpython3_3.13/build/test/test_config_command.py ___
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_config_command.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_config_command.py:9: in <module>
from beets import config, ui
beets/ui/__init__.py:35: in <module>
from beets import config, library, logging, plugins, util
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_datequery.py _____
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_datequery.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_datequery.py:28: in <module>
from beets.test import _common
beets/test/_common.py:26: in <module>
import beets.library # noqa: E402
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_dbcore.py _______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_dbcore.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_dbcore.py:24: in <module>
from beets.test import _common
beets/test/_common.py:26: in <module>
import beets.library # noqa: E402
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_files.py _______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_files.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_files.py:24: in <module>
import beets.library
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_importer.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_importer.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_importer.py:31: in <module>
from mediafile import MediaFile
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_library.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_library.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_library.py:28: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_logging.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_logging.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_logging.py:11: in <module>
from beets import plugins, ui
beets/plugins.py:25: in <module>
import mediafile
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_m3ufile.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_m3ufile.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_m3ufile.py:23: in <module>
from beets.test._common import RSRC
beets/test/_common.py:26: in <module>
import beets.library # noqa: E402
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
________ ERROR collecting .pybuild/cpython3_3.13/build/test/test_mb.py _________
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_mb.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_mb.py:22: in <module>
from beets.autotag import mb
beets/autotag/__init__.py:20: in <module>
from beets.library import Item
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_metasync.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_metasync.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_metasync.py:22: in <module>
from beets.library import Item
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_plugins.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_plugins.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_plugins.py:22: in <module>
from mediafile import MediaFile
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_query.py _______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_query.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_query.py:24: in <module>
import beets.library
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_sort.py ________
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_sort.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_sort.py:20: in <module>
import beets.library
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
________ ERROR collecting .pybuild/cpython3_3.13/build/test/test_ui.py _________
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_ui.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_ui.py:28: in <module>
from mediafile import MediaFile
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_ui_commands.py ____
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_ui_commands.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_ui_commands.py:23: in <module>
from beets import library, ui
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
____ ERROR collecting .pybuild/cpython3_3.13/build/test/test_ui_importer.py ____
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_ui_importer.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_ui_importer.py:22: in <module>
from test import test_importer
test/test_importer.py:31: in <module>
from mediafile import MediaFile
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_ui_init.py ______
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_ui_init.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_ui_init.py:24: in <module>
from beets import config, ui
beets/ui/__init__.py:35: in <module>
from beets import config, library, logging, plugins, util
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
_______ ERROR collecting .pybuild/cpython3_3.13/build/test/test_util.py ________
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_util.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_util.py:26: in <module>
from beets.test import _common
beets/test/_common.py:26: in <module>
import beets.library # noqa: E402
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
________ ERROR collecting .pybuild/cpython3_3.13/build/test/test_vfs.py ________
ImportError while importing test module '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build/test/test_vfs.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
test/test_vfs.py:19: in <module>
from beets import library, vfs
beets/library.py:26: in <module>
from mediafile import MediaFile, UnreadableFileError
/usr/lib/python3/dist-packages/mediafile.py:52: in <module>
import imghdr
E ModuleNotFoundError: No module named 'imghdr'
=============================== warnings summary ===============================
../../../../../../usr/lib/python3/dist-packages/confuse/util.py:118
/usr/lib/python3/dist-packages/confuse/util.py:118: DeprecationWarning: 'pkgutil.get_loader' is deprecated and slated for removal in Python 3.14; use importlib.util.find_spec() instead
loader = pkgutil.get_loader(name)
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
ERROR test/test_art_resize.py
ERROR test/test_autotag.py
ERROR test/test_config_command.py
ERROR test/test_datequery.py
ERROR test/test_dbcore.py
ERROR test/test_files.py
ERROR test/test_importer.py
ERROR test/test_library.py
ERROR test/test_logging.py
ERROR test/test_m3ufile.py
ERROR test/test_mb.py
ERROR test/test_metasync.py
ERROR test/test_plugins.py
ERROR test/test_query.py
ERROR test/test_sort.py
ERROR test/test_ui.py
ERROR test/test_ui_commands.py
ERROR test/test_ui_importer.py
ERROR test/test_ui_init.py
ERROR test/test_util.py
ERROR test/test_vfs.py
!!!!!!!!!!!!!!!!!!! Interrupted: 21 errors during collection !!!!!!!!!!!!!!!!!!!
======================== 1 warning, 21 errors in 1.86s =========================
E: pybuild pybuild:389: test: plugin distutils failed with: exit code=2: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13/build; python3.13 -m pytest -k "not test_completion"
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build; python3.12 -m pytest -k "not test_completion"
============================= test session starts ==============================
platform linux -- Python 3.12.6, pytest-8.3.2, pluggy-1.5.0
cachedir: /tmp/pytest_cache
rootdir: /<<PKGBUILDDIR>>
configfile: setup.cfg
plugins: typeguard-4.3.0, anyio-4.4.0
collected 1169 items / 1 deselected / 1168 selected
test/test_art_resize.py ssss. [ 5/1168]
test/test_autotag.py .............................................. [ 51/1168]
....................................... [ 90/1168]
test/test_config_command.py ........... [ 101/1168]
test/test_datequery.py ................................ [ 133/1168]
test/test_dbcore.py ............................................... [ 180/1168]
................................. [ 213/1168]
test/test_files.py ...ss.............................s............. [ 261/1168]
...........s..s............ [ 288/1168]
test/test_hidden.py s.s [ 291/1168]
test/test_importer.py ...................s.s....................... [ 336/1168]
...............................................s....s.............. [ 403/1168]
...................... [ 425/1168]
test/test_library.py ....................................ss........ [ 471/1168]
................................................................... [ 538/1168]
..........................................s................ [ 597/1168]
test/test_logging.py ............. [ 610/1168]
test/test_m3ufile.py ....s.s.. [ 619/1168]
test/test_mb.py ................................................... [ 670/1168]
.... [ 674/1168]
test/test_metasync.py ... [ 677/1168]
test/test_pipeline.py ...................... [ 699/1168]
test/test_plugins.py ....ss.................. [ 723/1168]
test/test_query.py ................................................ [ 771/1168]
................................................................... [ 838/1168]
.............. [ 852/1168]
test/test_sort.py ................................. [ 885/1168]
test/test_template.py ............................................. [ 930/1168]
.. [ 932/1168]
test/test_ui.py .......................s........................... [ 983/1168]
...................................s............................... [1050/1168]
............. [1063/1168]
test/test_ui_commands.py ..... [1068/1168]
test/test_ui_importer.py .......................................... [1110/1168]
........................... [1137/1168]
test/test_ui_init.py ..... [1142/1168]
test/test_util.py .s.....s................ [1166/1168]
test/test_vfs.py .. [1168/1168]
=============================== warnings summary ===============================
../../../../../../usr/lib/python3/dist-packages/confuse/util.py:118
/usr/lib/python3/dist-packages/confuse/util.py:118: DeprecationWarning: 'pkgutil.get_loader' is deprecated and slated for removal in Python 3.14; use importlib.util.find_spec() instead
loader = pkgutil.get_loader(name)
../../../../../../usr/lib/python3/dist-packages/mediafile.py:52
/usr/lib/python3/dist-packages/mediafile.py:52: DeprecationWarning: 'imghdr' is deprecated and slated for removal in Python 3.13
import imghdr
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
SKIPPED [1] test/test_art_resize.py:134: ImageMagick not available
SKIPPED [1] test/test_art_resize.py:116: ImageMagick not available
SKIPPED [1] test/test_art_resize.py:121: PIL not available
SKIPPED [1] test/test_art_resize.py:111: PIL not available
SKIPPED [1] test/test_files.py:99: need reflink
SKIPPED [1] test/test_files.py:104: need reflink
SKIPPED [1] test/test_files.py:294: need reflink
SKIPPED [1] test/test_files.py:585: need reflink
SKIPPED [1] test/test_files.py:599: need reflink
SKIPPED [1] test/test_hidden.py:33: sys.platform is not darwin
SKIPPED [1] test/test_hidden.py:50: sys.platform is not windows
SKIPPED [1] test/test_importer.py:282: unrar program not found
SKIPPED [1] test/test_importer.py:282: Implement me!
SKIPPED [1] test/test_importer.py:1229: write me
SKIPPED [1] test/test_importer.py:1337: write me
SKIPPED [1] test/test_library.py:484: unimplemented: #359
SKIPPED [1] test/test_library.py:495: unimplemented: #359
SKIPPED [1] test/test_library.py:1287: fails under some autopkgtests
SKIPPED [1] test/test_m3ufile.py:127: win32
SKIPPED [1] test/test_m3ufile.py:70: win32
SKIPPED [1] test/test_plugins.py:219: unreliable
SKIPPED [1] test/test_plugins.py:245: unreliable
SKIPPED [1] test/test_ui.py:363: not yet implemented
SKIPPED [1] test/test_ui.py:1074: Broken
SKIPPED [1] test/test_util.py:153: fs is case sensitive
SKIPPED [1] test/test_util.py:102: unimplemented: #359
========= 1142 passed, 26 skipped, 1 deselected, 2 warnings in 25.12s ==========
FWIW, the What's New page suggests:
imghdr: The filetype, puremagic, or python-magic libraries should be used as replacements. For example, the puremagic.what() function can be used to replace the imghdr.what() function for all file formats that were supported by imghdr.
Relevant in mediafile (which is where the import is): https://github.com/beetbox/mediafile/issues/67 https://github.com/beetbox/mediafile/pull/75
For those looking to run beets in python3.13, the following command is a good workaround until https://github.com/beetbox/mediafile/pull/75 gets merged:
pip install git+https://github.com/geigerzaehler/mediafile/@replace-imghdr
My workaround on Fedora 41:
sudo dnf install pipx python3.12
pipx install beets --python 3.12`
It is unfortunate that the packaged version simply doesn't work and fails with a verbose error message. Especially for those users like me, who are not familiar with the Python ecosystem.
See also: https://bugzilla.redhat.com/show_bug.cgi?id=2322293