We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `beetsplug/badfiles.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # This file is part of beets.
3 # Copyright 2016, François-Xavier Thomas.
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 
16 """Use command-line tools to check for audio file corruption.
17 """
18 
19 from __future__ import division, absolute_import, print_function
20 
21 from subprocess import check_output, CalledProcessError, list2cmdline, STDOUT
22 
23 import shlex
24 import os
25 import errno
26 import sys
27 import six
28 from beets.plugins import BeetsPlugin
29 from beets.ui import Subcommand
30 from beets.util import displayable_path, confit, par_map
31 from beets import ui
32 
33 
34 class CheckerCommandException(Exception):
35     """Raised when running a checker failed.
36 
37     Attributes:
38         checker: Checker command name.
39         path: Path to the file being validated.
40         errno: Error number from the checker execution error.
41         msg: Message from the checker execution error.
42     """
43 
44     def __init__(self, cmd, oserror):
45         self.checker = cmd[0]
46         self.path = cmd[-1]
47         self.errno = oserror.errno
48         self.msg = str(oserror)
49 
50 
51 class BadFiles(BeetsPlugin):
52     def __init__(self):
53         self.verbose = False
54 
55     def run_command(self, cmd):
56         self._log.debug(u"running command: {}",
57                         displayable_path(list2cmdline(cmd)))
58         try:
59             output = check_output(cmd, stderr=STDOUT)
60             errors = 0
61             status = 0
62         except CalledProcessError as e:
63             output = e.output
64             errors = 1
65             status = e.returncode
66         except OSError as e:
67             raise CheckerCommandException(cmd, e)
68         output = output.decode(sys.getfilesystemencoding())
69         return status, errors, [line for line in output.split("\n") if line]
70 
71     def check_mp3val(self, path):
72         status, errors, output = self.run_command(["mp3val", path])
73         if status == 0:
74             output = [line for line in output if line.startswith("WARNING:")]
75             errors = len(output)
76         return status, errors, output
77 
78     def check_flac(self, path):
79         return self.run_command(["flac", "-wst", path])
80 
81     def check_custom(self, command):
82         def checker(path):
83             cmd = shlex.split(command)
84             cmd.append(path)
85             return self.run_command(cmd)
86         return checker
87 
88     def get_checker(self, ext):
89         ext = ext.lower()
90         try:
91             command = self.config['commands'].get(dict).get(ext)
92         except confit.NotFoundError:
93             command = None
94         if command:
95             return self.check_custom(command)
96         if ext == "mp3":
97             return self.check_mp3val
98         if ext == "flac":
99             return self.check_flac
100 
101     def check_item(self, item):
102         # First, check whether the path exists. If not, the user
103         # should probably run `beet update` to cleanup your library.
104         dpath = displayable_path(item.path)
105         self._log.debug(u"checking path: {}", dpath)
106         if not os.path.exists(item.path):
107             ui.print_(u"{}: file does not exist".format(
108                 ui.colorize('text_error', dpath)))
109 
110         # Run the checker against the file if one is found
111         ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')
112         checker = self.get_checker(ext)
113         if not checker:
114             self._log.error(u"no checker specified in the config for {}",
115                             ext)
116             return
117         path = item.path
118         if not isinstance(path, six.text_type):
119             path = item.path.decode(sys.getfilesystemencoding())
120         try:
121             status, errors, output = checker(path)
122         except CheckerCommandException as e:
123             if e.errno == errno.ENOENT:
124                 self._log.error(
125                     u"command not found: {} when validating file: {}",
126                     e.checker,
127                     e.path
128                 )
129             else:
130                 self._log.error(u"error invoking {}: {}", e.checker, e.msg)
131             return
132         if status > 0:
133             ui.print_(u"{}: checker exited with status {}"
134                       .format(ui.colorize('text_error', dpath), status))
135             for line in output:
136                 ui.print_(u"  {}".format(displayable_path(line)))
137         elif errors > 0:
138             ui.print_(u"{}: checker found {} errors or warnings"
139                       .format(ui.colorize('text_warning', dpath), errors))
140             for line in output:
141                 ui.print_(u"  {}".format(displayable_path(line)))
142         elif self.verbose:
143             ui.print_(u"{}: ok".format(ui.colorize('text_success', dpath)))
144 
145     def command(self, lib, opts, args):
146         # Get items from arguments
147         items = lib.items(ui.decargs(args))
148         self.verbose = opts.verbose
149         par_map(self.check_item, items)
150 
151     def commands(self):
152         bad_command = Subcommand('bad',
153                                  help=u'check for corrupt or missing files')
154         bad_command.parser.add_option(
155             u'-v', u'--verbose',
156             action='store_true', default=False, dest='verbose',
157             help=u'view results for both the bad and uncorrupted files'
158         )
159         bad_command.func = self.command
160         return [bad_command]
161
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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

{"golden_diff": "diff --git a/beetsplug/badfiles.py b/beetsplug/badfiles.py\n--- a/beetsplug/badfiles.py\n+++ b/beetsplug/badfiles.py\n@@ -50,6 +50,7 @@\n \n class BadFiles(BeetsPlugin):\n     def __init__(self):\n+        super(BadFiles, self).__init__()\n         self.verbose = False\n \n     def run_command(self, cmd):\n", "issue": "BadFiles plugin crashes beets with latest git master\n### Problem\r\n\r\nIf the `badfiles` plugin is activated, beets crashes when starting an import task.\r\n\r\nRunning this command in verbose (`-vv`) mode:\r\n\r\n```sh\r\n$ beet -vv import --write /data/music\r\nuser configuration: /home/jan/.config/beets/config.yaml\r\ndata directory: /home/jan/.config/beets\r\nplugin paths:\r\nSending event: pluginload\r\nartresizer: method is (2, (7, 0, 8))\r\nlyrics: Disabling google source: no API key configured.\r\nlibrary database: /home/jan/beets.db\r\nlibrary directory: /data/music\r\nSending event: library_opened\r\nTraceback (most recent call last):\r\n  File \"/home/jan/.local/bin/beet\", line 11, in <module>\r\n    load_entry_point('beets', 'console_scripts', 'beet')()\r\n  File \"/data/jan/Projects/beets/beets/ui/__init__.py\", line 1266, in main\r\n    _raw_main(args)\r\n  File \"/data/jan/Projects/beets/beets/ui/__init__.py\", line 1253, in _raw_main\r\n    subcommand.func(lib, suboptions, subargs)\r\n  File \"/data/jan/Projects/beets/beets/ui/commands.py\", line 955, in import_func\r\n    import_files(lib, paths, query)\r\n  File \"/data/jan/Projects/beets/beets/ui/commands.py\", line 925, in import_files\r\n    session.run()\r\n  File \"/data/jan/Projects/beets/beets/importer.py\", line 316, in run\r\n    for stage_func in plugins.early_import_stages():\r\n  File \"/data/jan/Projects/beets/beets/plugins.py\", line 426, in early_import_stages\r\n    stages += plugin.get_early_import_stages()\r\n  File \"/data/jan/Projects/beets/beets/plugins.py\", line 112, in get_early_import_stages\r\n    return self._set_stage_log_level(self.early_import_stages)\r\nAttributeError: 'BadFiles' object has no attribute 'early_import_stages'\r\n```\r\n\r\n### Setup\r\n\r\n* OS: Arch Linux\r\n* Python version: 3.7.2\r\n* beets version: be118b92\r\n* Turning off plugins made problem go away (yes/no): Yes (Disabling the `badfiles` plugin suffices)\r\n\r\nMy configuration (output of `beet config`) is: https://gist.github.com/Holzhaus/500b790c06fe2250ac9182bd8a6760da\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This file is part of beets.\n# Copyright 2016, Fran\u00e7ois-Xavier Thomas.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Use command-line tools to check for audio file corruption.\n\"\"\"\n\nfrom __future__ import division, absolute_import, print_function\n\nfrom subprocess import check_output, CalledProcessError, list2cmdline, STDOUT\n\nimport shlex\nimport os\nimport errno\nimport sys\nimport six\nfrom beets.plugins import BeetsPlugin\nfrom beets.ui import Subcommand\nfrom beets.util import displayable_path, confit, par_map\nfrom beets import ui\n\n\nclass CheckerCommandException(Exception):\n    \"\"\"Raised when running a checker failed.\n\n    Attributes:\n        checker: Checker command name.\n        path: Path to the file being validated.\n        errno: Error number from the checker execution error.\n        msg: Message from the checker execution error.\n    \"\"\"\n\n    def __init__(self, cmd, oserror):\n        self.checker = cmd[0]\n        self.path = cmd[-1]\n        self.errno = oserror.errno\n        self.msg = str(oserror)\n\n\nclass BadFiles(BeetsPlugin):\n    def __init__(self):\n        self.verbose = False\n\n    def run_command(self, cmd):\n        self._log.debug(u\"running command: {}\",\n                        displayable_path(list2cmdline(cmd)))\n        try:\n            output = check_output(cmd, stderr=STDOUT)\n            errors = 0\n            status = 0\n        except CalledProcessError as e:\n            output = e.output\n            errors = 1\n            status = e.returncode\n        except OSError as e:\n            raise CheckerCommandException(cmd, e)\n        output = output.decode(sys.getfilesystemencoding())\n        return status, errors, [line for line in output.split(\"\\n\") if line]\n\n    def check_mp3val(self, path):\n        status, errors, output = self.run_command([\"mp3val\", path])\n        if status == 0:\n            output = [line for line in output if line.startswith(\"WARNING:\")]\n            errors = len(output)\n        return status, errors, output\n\n    def check_flac(self, path):\n        return self.run_command([\"flac\", \"-wst\", path])\n\n    def check_custom(self, command):\n        def checker(path):\n            cmd = shlex.split(command)\n            cmd.append(path)\n            return self.run_command(cmd)\n        return checker\n\n    def get_checker(self, ext):\n        ext = ext.lower()\n        try:\n            command = self.config['commands'].get(dict).get(ext)\n        except confit.NotFoundError:\n            command = None\n        if command:\n            return self.check_custom(command)\n        if ext == \"mp3\":\n            return self.check_mp3val\n        if ext == \"flac\":\n            return self.check_flac\n\n    def check_item(self, item):\n        # First, check whether the path exists. If not, the user\n        # should probably run `beet update` to cleanup your library.\n        dpath = displayable_path(item.path)\n        self._log.debug(u\"checking path: {}\", dpath)\n        if not os.path.exists(item.path):\n            ui.print_(u\"{}: file does not exist\".format(\n                ui.colorize('text_error', dpath)))\n\n        # Run the checker against the file if one is found\n        ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')\n        checker = self.get_checker(ext)\n        if not checker:\n            self._log.error(u\"no checker specified in the config for {}\",\n                            ext)\n            return\n        path = item.path\n        if not isinstance(path, six.text_type):\n            path = item.path.decode(sys.getfilesystemencoding())\n        try:\n            status, errors, output = checker(path)\n        except CheckerCommandException as e:\n            if e.errno == errno.ENOENT:\n                self._log.error(\n                    u\"command not found: {} when validating file: {}\",\n                    e.checker,\n                    e.path\n                )\n            else:\n                self._log.error(u\"error invoking {}: {}\", e.checker, e.msg)\n            return\n        if status > 0:\n            ui.print_(u\"{}: checker exited with status {}\"\n                      .format(ui.colorize('text_error', dpath), status))\n            for line in output:\n                ui.print_(u\"  {}\".format(displayable_path(line)))\n        elif errors > 0:\n            ui.print_(u\"{}: checker found {} errors or warnings\"\n                      .format(ui.colorize('text_warning', dpath), errors))\n            for line in output:\n                ui.print_(u\"  {}\".format(displayable_path(line)))\n        elif self.verbose:\n            ui.print_(u\"{}: ok\".format(ui.colorize('text_success', dpath)))\n\n    def command(self, lib, opts, args):\n        # Get items from arguments\n        items = lib.items(ui.decargs(args))\n        self.verbose = opts.verbose\n        par_map(self.check_item, items)\n\n    def commands(self):\n        bad_command = Subcommand('bad',\n                                 help=u'check for corrupt or missing files')\n        bad_command.parser.add_option(\n            u'-v', u'--verbose',\n            action='store_true', default=False, dest='verbose',\n            help=u'view results for both the bad and uncorrupted files'\n        )\n        bad_command.func = self.command\n        return [bad_command]\n", "path": "beetsplug/badfiles.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# This file is part of beets.\n# Copyright 2016, Fran\u00e7ois-Xavier Thomas.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Use command-line tools to check for audio file corruption.\n\"\"\"\n\nfrom __future__ import division, absolute_import, print_function\n\nfrom subprocess import check_output, CalledProcessError, list2cmdline, STDOUT\n\nimport shlex\nimport os\nimport errno\nimport sys\nimport six\nfrom beets.plugins import BeetsPlugin\nfrom beets.ui import Subcommand\nfrom beets.util import displayable_path, confit, par_map\nfrom beets import ui\n\n\nclass CheckerCommandException(Exception):\n    \"\"\"Raised when running a checker failed.\n\n    Attributes:\n        checker: Checker command name.\n        path: Path to the file being validated.\n        errno: Error number from the checker execution error.\n        msg: Message from the checker execution error.\n    \"\"\"\n\n    def __init__(self, cmd, oserror):\n        self.checker = cmd[0]\n        self.path = cmd[-1]\n        self.errno = oserror.errno\n        self.msg = str(oserror)\n\n\nclass BadFiles(BeetsPlugin):\n    def __init__(self):\n        super(BadFiles, self).__init__()\n        self.verbose = False\n\n    def run_command(self, cmd):\n        self._log.debug(u\"running command: {}\",\n                        displayable_path(list2cmdline(cmd)))\n        try:\n            output = check_output(cmd, stderr=STDOUT)\n            errors = 0\n            status = 0\n        except CalledProcessError as e:\n            output = e.output\n            errors = 1\n            status = e.returncode\n        except OSError as e:\n            raise CheckerCommandException(cmd, e)\n        output = output.decode(sys.getfilesystemencoding())\n        return status, errors, [line for line in output.split(\"\\n\") if line]\n\n    def check_mp3val(self, path):\n        status, errors, output = self.run_command([\"mp3val\", path])\n        if status == 0:\n            output = [line for line in output if line.startswith(\"WARNING:\")]\n            errors = len(output)\n        return status, errors, output\n\n    def check_flac(self, path):\n        return self.run_command([\"flac\", \"-wst\", path])\n\n    def check_custom(self, command):\n        def checker(path):\n            cmd = shlex.split(command)\n            cmd.append(path)\n            return self.run_command(cmd)\n        return checker\n\n    def get_checker(self, ext):\n        ext = ext.lower()\n        try:\n            command = self.config['commands'].get(dict).get(ext)\n        except confit.NotFoundError:\n            command = None\n        if command:\n            return self.check_custom(command)\n        if ext == \"mp3\":\n            return self.check_mp3val\n        if ext == \"flac\":\n            return self.check_flac\n\n    def check_item(self, item):\n        # First, check whether the path exists. If not, the user\n        # should probably run `beet update` to cleanup your library.\n        dpath = displayable_path(item.path)\n        self._log.debug(u\"checking path: {}\", dpath)\n        if not os.path.exists(item.path):\n            ui.print_(u\"{}: file does not exist\".format(\n                ui.colorize('text_error', dpath)))\n\n        # Run the checker against the file if one is found\n        ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')\n        checker = self.get_checker(ext)\n        if not checker:\n            self._log.error(u\"no checker specified in the config for {}\",\n                            ext)\n            return\n        path = item.path\n        if not isinstance(path, six.text_type):\n            path = item.path.decode(sys.getfilesystemencoding())\n        try:\n            status, errors, output = checker(path)\n        except CheckerCommandException as e:\n            if e.errno == errno.ENOENT:\n                self._log.error(\n                    u\"command not found: {} when validating file: {}\",\n                    e.checker,\n                    e.path\n                )\n            else:\n                self._log.error(u\"error invoking {}: {}\", e.checker, e.msg)\n            return\n        if status > 0:\n            ui.print_(u\"{}: checker exited with status {}\"\n                      .format(ui.colorize('text_error', dpath), status))\n            for line in output:\n                ui.print_(u\"  {}\".format(displayable_path(line)))\n        elif errors > 0:\n            ui.print_(u\"{}: checker found {} errors or warnings\"\n                      .format(ui.colorize('text_warning', dpath), errors))\n            for line in output:\n                ui.print_(u\"  {}\".format(displayable_path(line)))\n        elif self.verbose:\n            ui.print_(u\"{}: ok\".format(ui.colorize('text_success', dpath)))\n\n    def command(self, lib, opts, args):\n        # Get items from arguments\n        items = lib.items(ui.decargs(args))\n        self.verbose = opts.verbose\n        par_map(self.check_item, items)\n\n    def commands(self):\n        bad_command = Subcommand('bad',\n                                 help=u'check for corrupt or missing files')\n        bad_command.parser.add_option(\n            u'-v', u'--verbose',\n            action='store_true', default=False, dest='verbose',\n            help=u'view results for both the bad and uncorrupted files'\n        )\n        bad_command.func = self.command\n        return [bad_command]\n", "path": "beetsplug/badfiles.py"}]}