internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: beetbox/beets

Issue:
%title{ } Capitalize after apostrophe
### Problem

When you add %title{} to something for example %title{$title}, the capitalization is also done after an apostrophe, leading to some weird capitalization like "Can'T" "Don'T" "I'M" ...


Example : 

"50 Cent - If I Can't" become "50 Cent - If I Can'T"

### Setup

* OS: Arch Linux
* Python version: Latest 
* beets version: Latest
* Turning off plugins made problem go away (yes/no): N/A



Discussion:
Good point! This could be smarter than Python’s built-in `str.title`, especially when it comes to Unicode. This would be a good first issue for anyone getting into hacking on beets.
Looks like replacing it with `capwords` should do it: https://stackoverflow.com/a/8199981/2664985
Awesome; good find, @jackwilsdon. Do you know whether it works with Unicode punctuation like ‘’?
Looks like it works as expected :+1:

```
>>> import string
>>> string.capwords("Testing the q‘uote’s", " ")
'Testing The Q‘uote’s'
```

Resolving patch:
diff --git a/beets/library.py b/beets/library.py
--- a/beets/library.py
+++ b/beets/library.py
@@ -23,6 +23,7 @@
 import time
 import re
 import six
+import string
 
 from beets import logging
 from beets.mediafile import MediaFile, UnreadableFileError
@@ -1456,7 +1457,7 @@ def tmpl_upper(s):
     @staticmethod
     def tmpl_title(s):
         """Convert a string to title case."""
-        return s.title()
+        return string.capwords(s)
 
     @staticmethod
     def tmpl_left(s, chars):


Test patch:
diff --git a/test/test_library.py b/test/test_library.py
--- a/test/test_library.py
+++ b/test/test_library.py
@@ -589,6 +589,10 @@ def test_title_case_variable(self):
         self._setf(u'%title{$title}')
         self._assert_dest(b'/base/The Title')
 
+    def test_title_case_variable_aphostrophe(self):
+        self._setf(u'%title{I can\'t}')
+        self._assert_dest(b'/base/I Can\'t')
+
     def test_asciify_variable(self):
         self._setf(u'%asciify{ab\xa2\xbdd}')
         self._assert_dest(b'/base/abC_ 1_2 d')
Repository: beetbox/beets

Issue:
no error raised about malformed yml
It seems like that the loading of malformed yml files included in the configuration through the ìnclude`key does not raise the expected error.

### Problem
Whilst working on PR #3498 I purposefully included a malformed yml file just to test if the newly introduced warning would also catch the error about it:
```yml
include: 
    - badformat.yml
```
and with the 'badformat.yml' file:
```yml
this
    will
        not
            pass
        as
    ok
yml
```
I expected a confuse.ConfigReadError but no errors were raised.
This is what I got:
```bash
$ ./beet
configuration error: musicbrainz.host not found
```

More investigation is needed.

### Setup

* OS: macos 10.13.6 (17G11023)
* Python version: 3.7.6
* beets version: 1.4.9
* Turning off plugins made problem go away (yes/no): no
* My configuration (output of `beet config`) is:  malformed :):):)




Discussion:

Resolving patch:
diff --git a/beets/ui/commands.py b/beets/ui/commands.py
--- a/beets/ui/commands.py
+++ b/beets/ui/commands.py
@@ -1376,10 +1376,10 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
     # objects.
     print_(u'Modifying {0} {1}s.'
            .format(len(objs), u'album' if album else u'item'))
-    changed = set()
+    changed = []
     for obj in objs:
-        if print_and_modify(obj, mods, dels):
-            changed.add(obj)
+        if print_and_modify(obj, mods, dels) and obj not in changed:
+            changed.append(obj)
 
     # Still something to do?
     if not changed:


Test patch:
Repository: beetbox/beets

Issue:
Selection interface: option to "skip remaining tracks" and take action
### Problem

I love the `modify` command's select mode, because it means you don't have to write super-specific queries - instead you can write a more general query and then simply type an `n` to skip those tracks you don't want to retag.

Unfortunately, there seems to be no way to "skip remaining tracks". For example, say I got through 50 out of 100 tracks that a query returned. I've answered `y` to most of them, but `n` to just a few. If I hit Ctrl-C at this point, I notice that the tags do not get written to the tracks I answered `y` to.

Perhaps we could add an `s` option that skips remaining tracks but still updates those that we answered `y` to. Alternatively, we could update tracks as-and-when we answer `y`, allowing us to Ctrl-C out of the process without losing work.


Discussion:
Sounds good to me!

Resolving patch:
diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py
--- a/beets/ui/__init__.py
+++ b/beets/ui/__init__.py
@@ -408,9 +408,14 @@ def input_select_objects(prompt, objs, rep):
         out = []
         for obj in objs:
             rep(obj)
-            if input_yn(u'%s? (yes/no)' % prompt, True):
+            answer = input_options(
+                ('y', 'n', 'q'), True, u'%s? (yes/no/quit)' % prompt,
+                u'Enter Y or N:'
+            )
+            if answer == u'y':
                 out.append(obj)
-            print()  # go to a new line
+            elif answer == u'q':
+                return out
         return out
 
     else:  # No.


Test patch:
diff --git a/test/test_ui_init.py b/test/test_ui_init.py
--- a/test/test_ui_init.py
+++ b/test/test_ui_init.py
@@ -73,6 +73,16 @@ def test_input_select_objects(self):
             lambda s: self._print_helper2(s, "Prefix"))
         self.assertEqual(items, ['1', '2', '4'])
 
+        # Test selective 3
+        self.io.addinput('s')
+        self.io.addinput('y')
+        self.io.addinput('n')
+        self.io.addinput('y')
+        self.io.addinput('q')
+        items = ui.input_select_objects(
+            "Prompt", full_items, self._print_helper)
+        self.assertEqual(items, ['1', '3'])
+
 
 class InitTest(_common.LibTestCase):
     def setUp(self):
Repository: beetbox/beets

Issue:
BadFiles plugin crashes beets with latest git master
### Problem

If the `badfiles` plugin is activated, beets crashes when starting an import task.

Running this command in verbose (`-vv`) mode:

```sh
$ beet -vv import --write /data/music
user configuration: /home/jan/.config/beets/config.yaml
data directory: /home/jan/.config/beets
plugin paths:
Sending event: pluginload
artresizer: method is (2, (7, 0, 8))
lyrics: Disabling google source: no API key configured.
library database: /home/jan/beets.db
library directory: /data/music
Sending event: library_opened
Traceback (most recent call last):
  File "/home/jan/.local/bin/beet", line 11, in <module>
    load_entry_point('beets', 'console_scripts', 'beet')()
  File "/data/jan/Projects/beets/beets/ui/__init__.py", line 1266, in main
    _raw_main(args)
  File "/data/jan/Projects/beets/beets/ui/__init__.py", line 1253, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/data/jan/Projects/beets/beets/ui/commands.py", line 955, in import_func
    import_files(lib, paths, query)
  File "/data/jan/Projects/beets/beets/ui/commands.py", line 925, in import_files
    session.run()
  File "/data/jan/Projects/beets/beets/importer.py", line 316, in run
    for stage_func in plugins.early_import_stages():
  File "/data/jan/Projects/beets/beets/plugins.py", line 426, in early_import_stages
    stages += plugin.get_early_import_stages()
  File "/data/jan/Projects/beets/beets/plugins.py", line 112, in get_early_import_stages
    return self._set_stage_log_level(self.early_import_stages)
AttributeError: 'BadFiles' object has no attribute 'early_import_stages'
```

### Setup

* OS: Arch Linux
* Python version: 3.7.2
* beets version: be118b92
* Turning off plugins made problem go away (yes/no): Yes (Disabling the `badfiles` plugin suffices)

My configuration (output of `beet config`) is: https://gist.github.com/Holzhaus/500b790c06fe2250ac9182bd8a6760da


Discussion:

Resolving patch:
diff --git a/beetsplug/badfiles.py b/beetsplug/badfiles.py
--- a/beetsplug/badfiles.py
+++ b/beetsplug/badfiles.py
@@ -50,6 +50,7 @@ def __init__(self, cmd, oserror):
 
 class BadFiles(BeetsPlugin):
     def __init__(self):
+        super(BadFiles, self).__init__()
         self.verbose = False
 
     def run_command(self, cmd):


Test patch:
Repository: beetbox/beets

Issue:
replaygain ffmpeg backend: ffmpeg exited with status 1
### Problem

Running this command in verbose (`-vv`) mode:

```sh
$ beet -vv replaygain -f
```

Led to this problem:

```
user configuration: /home/samuel/.config/beets/config.yaml
data directory: /home/samuel/.config/beets
plugin paths: 
Sending event: pluginload
library database: /home/samuel/.config/beets/library.db
library directory: /home/samuel/Music
Sending event: library_opened
replaygain: analyzing Air - Moon Safari - Sexy Boy
replaygain: analyzing Air - Moon Safari - Sexy Boy
replaygain: executing ffmpeg -nostats -hide_banner -i /home/samuel/Music/02.flac -map a:0 -filter ebur128=peak=true -f null -
replaygain: ReplayGain error: ffmpeg exited with status 1
Sending event: cli_exit
```
When running the ffmpeg command above manually there is no error.

### Setup

* OS: Linux X240 5.2.5-arch1-1-ARCH #1 SMP PREEMPT Wed Jul 31 08:30:34 UTC 2019 x86_64 GNU/Linux
* Python version: 3.7.4
* beets version: 1.5.0 (c74c9a46a9026c3c550c0c75d12eaf5dee854c5a)
* Turning off plugins made problem go away (yes/no): The error is in a plugin

My configuration (output of `beet config`) is:

```yaml
directory: ~/Music
write: yes
move: yes

plugins: replaygain

paths:
    default: $track
replaygain:
    backend: ffmpeg
    overwrite: no
    auto: yes
    per_disc: no
    peak: 'true'
    targetlevel: 89
    r128: [Opus]
    r128_targetlevel: 84
```



Discussion:
Hmm; I'm not sure what to suggest! Is there any suspicious output from ffmpeg at all when you run it manually?

Any suggestions, @zsinskri?
Thanks for quick response! I can see no suspicious output from the command, and the exit status is 0 (unlike what beets say). The output is a lot of rows similar to this:
```
[Parsed_ebur128_0 @ 0x55b5e8e8a640] t: 298.4      TARGET:-23 LUFS    M:   nan S: -41.4     I:  -9.0 LUFS       LRA:   2.4 LU  FTPK:  -inf  -inf dBFS  TPK:   0.5   0.7 dBFS
```
ending with this:
```
size=N/A time=00:04:58.46 bitrate=N/A speed= 102x    
video:0kB audio:55962kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x55b5e8e8a640] Summary:

  Integrated loudness:
    I:          -9.0 LUFS
    Threshold: -19.0 LUFS

  Loudness range:
    LRA:         2.4 LU
    Threshold: -29.0 LUFS
    LRA low:   -10.2 LUFS
    LRA high:   -7.8 LUFS

  True peak:
    Peak:        0.7 dBFS
```
There is no error when i run the same beets command with the bs1770gain backend.
Strange. Maybe we should have the verbose log include the command's stderr output when the exit code is nonzero…

Resolving patch:
diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py
--- a/beetsplug/replaygain.py
+++ b/beetsplug/replaygain.py
@@ -456,7 +456,8 @@ def _construct_cmd(self, item, peak_method):
             "-hide_banner",
             "-i",
             item.path,
-            "-map a:0",
+            "-map",
+            "a:0",
             "-filter",
             "ebur128=peak={0}".format(peak_method),
             "-f",


Test patch:
Repository: beetbox/beets

Issue:
web plugin: Can't do path queries
<!--
Describe your problem, feature request, or discussion topic here.

Please fill out this and the "Setup" section below and remember to include
enough detail so that other people can reproduce the problem.
-->

### Problem

The beets web plugin provides a [JSON API](https://beets.readthedocs.io/en/stable/plugins/web.html?highlight=web#json-api). This JSON API has a `/item/query` endpoint. Using this endpoint I want to perform a [path query](https://beets.readthedocs.io/en/stable/reference/query.html#path-queries). For example:

```
path:/home/nmeum/music/Singles
```

Unfortunately, such path queries do not work with the JSON API due to the `QueryConverter` which is used for the `/query` endpoint:

 https://github.com/beetbox/beets/blob/d43d54e21cde97f57f19486925ab56b419254cc8/beetsplug/web/__init__.py#L175-L183

This class converts the query from above to:

```
path:home,nmeum,music,Singles
```

which obviously does not work as intended. It doesn't make a difference whether the path query is URL encoded or not. Maybe this could be fixed by invoking the `QueryConverter` before URL decoding is performed? Additionally, it seems that the `QueryConverter` behaviour is not actually documented in the JSON API doc.

This issue cannot be workaround by using the `/item/path/...` endpoint, because this endpoint returns a different JSON document.

See also: https://github.com/pallets/flask/issues/900

### Setup

* OS: Alpine Linux
* Python version: 3.8.2
* beets version: 1.4.9
* Turning off plugins made problem go away (yes/no): N/A


Discussion:

Resolving patch:
diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py
--- a/beetsplug/web/__init__.py
+++ b/beetsplug/web/__init__.py
@@ -177,10 +177,11 @@ class QueryConverter(PathConverter):
     """
 
     def to_python(self, value):
-        return value.split('/')
+        queries = value.split('/')
+        return [query.replace('\\', os.sep) for query in queries]
 
     def to_url(self, value):
-        return ','.join(value)
+        return ','.join([v.replace(os.sep, '\\') for v in value])
 
 
 class EverythingConverter(PathConverter):


Test patch:
Repository: beetbox/beets

Issue:
import: support extraction of bzip2 and gzip tarballs
### Use case

I'm trying to use beets to import albums from a set of bzip2/gzip tarballs, i.e. .tar.bz2 and .tar.gz files. Would be nice if we could just import them instead of having to extract them first.

### Solution
<!--
Do you have a proposal for how beets should work?

Try to be as specific as possible—for example, you could propose the name for
a new command-line option or refer to the particular ID3 frame you wish
were supported.
-->
I see that the `tarfile` module can process tar archives with [gzip or bzip2 compression](https://docs.python.org/2/library/tarfile.html), so hopefully this is not too hard to do. Unfortunately I don't know Python so I cannot provide a patch.

### Alternatives
<!--
Have you tried using an existing plugin to do something similar?
Is there any current feature that _almost_ does what you need?
-->
As a workaround I am extracting the tarballs first. Not the end of the world but it would be nice to be able to just point beets to the files, just like we do with rar and zip files.

Thanks for maintaining this great piece of software!


Discussion:
Have you tried importing a `.tar.bz2` or `.tar.gz`? It looks like we should already support it from the source:

https://github.com/beetbox/beets/blob/19ab28e1412dbf4130e015a94557d277b4c699ed/beets/importer.py#L1037-L1038

Resolving patch:
diff --git a/beets/importer.py b/beets/importer.py
--- a/beets/importer.py
+++ b/beets/importer.py
@@ -1034,8 +1034,8 @@ def handlers(cls):
             cls._handlers = []
             from zipfile import is_zipfile, ZipFile
             cls._handlers.append((is_zipfile, ZipFile))
-            from tarfile import is_tarfile, TarFile
-            cls._handlers.append((is_tarfile, TarFile))
+            import tarfile
+            cls._handlers.append((tarfile.is_tarfile, tarfile.open))
             try:
                 from rarfile import is_rarfile, RarFile
             except ImportError:


Test patch:
Repository: beetbox/beets

Issue:
"the" plugin uses incorrect regex
### Problem

Running this command:

```sh
~ ❯ beet move artist:trance -p
Moving 40 items.
M:\TET - Travailleur En Trance\[2008] Cobra Coded Escalation\01-01 - Cobra Reporting In.mp3
  -> M:\‒ Travailleur En Trance, TET\[2008] Cobra Coded Escalation\01-01 - Cobra Reporting In.mp3
```

Led to this problem:

"TET" is recognized by the "the" plugin as something it should move. This is because the regex used in the.py, line 26, is
```
PATTERN_THE = u'^[the]{3}\\s'
```
which matches "TET". It should probably be:
```
PATTERN_THE = u'^the\\s'
```

### Setup

* OS: Windows 10 2004
* Python version: 3.8
* beets version: latest trunk
* Turning off plugins made problem go away (yes/no): obviously, if I disable 'the' it no longer does this



Discussion:

Resolving patch:
diff --git a/beetsplug/the.py b/beetsplug/the.py
--- a/beetsplug/the.py
+++ b/beetsplug/the.py
@@ -23,7 +23,7 @@
 __author__ = 'baobab@heresiarch.info'
 __version__ = '1.1'
 
-PATTERN_THE = u'^[the]{3}\\s'
+PATTERN_THE = u'^the\\s'
 PATTERN_A = u'^[a][n]?\\s'
 FORMAT = u'{0}, {1}'
 


Test patch:
diff --git a/test/test_the.py b/test/test_the.py
--- a/test/test_the.py
+++ b/test/test_the.py
@@ -36,6 +36,8 @@ def test_unthe_with_default_patterns(self):
                          u'A Thing, An')
         self.assertEqual(ThePlugin().unthe(u'the An Arse', PATTERN_A),
                          u'the An Arse')
+        self.assertEqual(ThePlugin().unthe(u'TET - Travailleur', PATTERN_THE),
+                         u'TET - Travailleur')
 
     def test_unthe_with_strip(self):
         config['the']['strip'] = True
Repository: beetbox/beets

Issue:
Minor documentation correction:  correct id3.org url
https://github.com/beetbox/beets/blob/master/docs/faq.rst#L303
refers to:
http://www.id3.org/id3v2.4.0-structure
as a reference url for a copy of the ID3v2.4 standard documentation, but this returns a "Not found" error. I've found 2 possibilities for the replacement:
https://id3.org/id3v2.4.0-structure
(with adverts) or
https://github.com/id3/ID3v2.4/raw/master/id3v2.40-structure.txt
(without adverts)



Discussion:
That's great; thank you! If you have a moment, a pull request would not go amiss. :smiley:

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -28,6 +28,13 @@
     'stdlib': ('https://docs.python.org/3/library/%s.html', ''),
 }
 
+linkcheck_ignore = [
+    r'https://github.com/beetbox/beets/issues/',
+    r'https://github.com/\w+$',  # ignore user pages
+    r'.*localhost.*',
+    r'https://www.musixmatch.com/',  # blocks requests
+]
+
 # Options for HTML output
 htmlhelp_basename = 'beetsdoc'
 


Test patch:
diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml
--- a/.github/workflows/integration_test.yaml
+++ b/.github/workflows/integration_test.yaml
@@ -27,6 +27,10 @@ jobs:
         run: |
           tox -e int
 
+      - name: Check external links in docs
+        run: |
+          tox -e links
+
       - name: Notify on failure
         if: ${{ failure() }}
         env:
Repository: beetbox/beets

Issue:
Get genres from MusicBrainz
### Problem

Next release of MusicBrainz will have genre support. An example can be seen at https://beta.musicbrainz.org/release-group/3bd76d40-7f0e-36b7-9348-91a33afee20e (JSON web service output: https://beta.musicbrainz.org/ws/2/release-group/3bd76d40-7f0e-36b7-9348-91a33afee20e?fmt=json&inc=genres )

beets should fetch these and allow MusicBrainz to be used as "genre authority".


Discussion:
Whoa! That's so cool! Somehow I had missed the buzz about this update. We should certainly support it!!
Looks like a PR will be needed on [musicbrianzngs](https://github.com/alastair/python-musicbrainzngs), as it currently doesn't support `genre` as a field (it's not in the whitelist), and it doesn't try to do any parsing either.

It should be relatively simple to add as genres are laid out just like tags, so it's a pretty simple case of adding it to the right dicitonaries and using `parse_tags`.
I’ve been using [fdemmer’s last.fm.ng](https://github.com/fdemmer/Picard-Last.fm.ng-Plugin) plugin with MusicBrainz Picard for ever and a while. I wonder if something like this could be implemented instead? (It derives genres, moods, etc. from _last.fm_.)

MusicBrainz genres will surely take a while to gain momentum, since almost nobody currently tags genres in MusicBrainz.
I'd love to see this feature, implemented similar to how Picard does it. With Picard it will only use the genres I've tagged with, and will fall back to the album artist's genre if I didn't tag a release or release group with one.

It looks like there's a partially completed PR for musicbrainzngs that adds the support: https://github.com/alastair/python-musicbrainzngs/pull/243.

Resolving patch:
diff --git a/beets/autotag/mb.py b/beets/autotag/mb.py
--- a/beets/autotag/mb.py
+++ b/beets/autotag/mb.py
@@ -74,6 +74,8 @@ def get_message(self):
 TRACK_INCLUDES = ['artists', 'aliases']
 if 'work-level-rels' in musicbrainzngs.VALID_INCLUDES['recording']:
     TRACK_INCLUDES += ['work-level-rels', 'artist-rels']
+if 'genres' in musicbrainzngs.VALID_INCLUDES['recording']:
+    RELEASE_INCLUDES += ['genres']
 
 
 def track_url(trackid):
@@ -415,6 +417,10 @@ def album_info(release):
         first_medium = release['medium-list'][0]
         info.media = first_medium.get('format')
 
+    genres = release.get('genre-list')
+    if genres:
+        info.genre = ';'.join(g['name'] for g in genres)
+
     info.decode()
     return info
 


Test patch:
Repository: beetbox/beets

Issue:
mpdstats plugin needs updating to work with python-mpd2 2.0.0
(Sorry, this is just from source code inspection and a search of dependent packages in Debian, rather than a crash that I've genuinely reproduced - I don't currently use beets myself, although I keep meaning to try it.)

https://github.com/Mic92/python-mpd2 version 2.0.0 dropped support for the `use_unicode` parameter to the `MPDClient` constructor. This parameter doesn't do anything in Python 3, which always behaves like `use_unicode=True`. It was important in Python 2.

In Debian's python3-mpd package I've added back compatibility with the use_unicode parameter for now (see Mic92/python-mpd2#142) but I don't know whether that will be accepted upstream.

If beets only supports Python 3, dropping the parameter should be a sufficient fix: replace `MPDClient(use_unicode=True)` with `MPDClient()`.

If it still supports Python 2, something similar to https://github.com/multani/sonata/pull/116 should work.


Discussion:
Thank you for the report, traceback or no! A simple check like in Sonata should do well.

Resolving patch:
diff --git a/beetsplug/mpdstats.py b/beetsplug/mpdstats.py
--- a/beetsplug/mpdstats.py
+++ b/beetsplug/mpdstats.py
@@ -18,6 +18,7 @@
 import mpd
 import socket
 import select
+import sys
 import time
 import os
 
@@ -52,7 +53,13 @@ def __init__(self, log):
         self.music_directory = (
             mpd_config['music_directory'].as_str())
 
-        self.client = mpd.MPDClient(use_unicode=True)
+        if sys.version_info < (3, 0):
+            # On Python 2, use_unicode will enable the utf-8 mode for
+            # python-mpd2
+            self.client = mpd.MPDClient(use_unicode=True)
+        else:
+            # On Python 3, python-mpd2 always uses Unicode
+            self.client = mpd.MPDClient()
 
     def connect(self):
         """Connect to the MPD.


Test patch: