beets icon indicating copy to clipboard operation
beets copied to clipboard

Python 3.13 support

Open stefanor opened this issue 1 year ago • 2 comments

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 ==========

stefanor avatar Sep 14 '24 07:09 stefanor

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.

stefanor avatar Sep 20 '24 16:09 stefanor

Relevant in mediafile (which is where the import is): https://github.com/beetbox/mediafile/issues/67 https://github.com/beetbox/mediafile/pull/75

jackwilsdon avatar Sep 30 '24 09:09 jackwilsdon

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

theol0403 avatar Nov 02 '24 16:11 theol0403

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

uklotzde avatar Nov 03 '24 13:11 uklotzde