beetbox / beets

music library manager and MusicBrainz tagger
http://beets.io/
MIT License
12.88k stars 1.82k forks source link

Crash in print_and_modify when trying to modify "added" and choosing "select" #4880

Open JOJ0 opened 1 year ago

JOJ0 commented 1 year ago

Problem

Running this command

$ beet mod -a added='2002-06-03 00:00:00' kruder kicks

Led to this problem:

Modifying 2 albums.
1996 - Kruder & Dorfmeister - [!K7046CDX] DJ-Kicks: Kruder & Dorfmeister  a:02-06/ASIS b:128k [17/17]
  added: 2002-06-03 -> 2002-06-03
1996 - Kruder & Dorfmeister - [PM 511] DJ-Kicks: Kruder & Dorfmeister  a:23-07/MusicBrainz b:812k [17/17]
  added: 2023-07-26 -> 2002-06-03
Really modify, move and write tags? (Yes/no/select) s

Traceback (most recent call last):
  File "/home/jojo/.pyenv/versions/beets/bin/beet", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/jojo/git/beets/beets/ui/__init__.py", line 1301, in main
    _raw_main(args)
  File "/home/jojo/git/beets/beets/ui/__init__.py", line 1288, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/home/jojo/git/beets/beets/ui/commands.py", line 1587, in modify_func
    modify_items(lib, mods, dels, query, ui.should_write(opts.write),
  File "/home/jojo/git/beets/beets/ui/commands.py", line 1537, in modify_items
    changed = ui.input_select_objects(
              ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/ui/__init__.py", line 398, in input_select_objects
    rep(obj)
  File "/home/jojo/git/beets/beets/ui/commands.py", line 1539, in <lambda>
    lambda o: print_and_modify(o, mods, dels)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/ui/commands.py", line 1561, in print_and_modify
    return ui.show_model_changes(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/ui/__init__.py", line 709, in show_model_changes
    line = _field_diff(field, old, old_fmt, new, new_fmt)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/ui/__init__.py", line 671, in _field_diff
    newstr = new_fmt.get(field, '')
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/dbcore/db.py", line 124, in get
    return super().get(key, default)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen _collections_abc>", line 774, in get
  File "/home/jojo/git/beets/beets/dbcore/db.py", line 103, in __getitem__
    return self._get_formatted(self.model, key)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/dbcore/db.py", line 127, in _get_formatted
    value = model._type(key).format(model.get(key))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jojo/git/beets/beets/library.py", line 153, in format
    time.localtime(value or 0))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'str' object cannot be interpreted as an integer

Setup

I tried with my custom time config

time_format: '%Y-%m-%d'

but also with the default

# time_format: '%Y-%m-%d'

same result.

sampsyo commented 1 year ago

Huh; this is mysterious and bad! To expand a little bit, the problem is arising here: https://github.com/beetbox/beets/blob/62859f4389715d87af36827b6042d21a82e91fdc/beets/library.py#L152-L153

And the problem is that value is a string when it should be a number (int or float). The problem probably occurs earlier, when we set the added field on one of the items. However, the parse method of the type should be taking care of converting the string to a number: https://github.com/beetbox/beets/blob/62859f4389715d87af36827b6042d21a82e91fdc/beets/library.py#L155

So the place to start hunting for a root cause is around there… i.e., trying to identify why we're not putting a number in that field in the first place.

JOJ0 commented 1 year ago

Thanks a lot for the pointers, very much appreciated. I'll try to move on with this topic at some point but even though it's a bug it doesn't bother me too much and is not on the very top of my priorities list :-)