prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Expose builder.tags to web templates.
  This tiny PR exposes the builders' "tags" attribute to the templates, allowing me to customize the templates using that feature.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `master/buildbot/steps/master.py`
  Content:
  ```
  1 # This file is part of Buildbot.  Buildbot is free software: you can
  2 # redistribute it and/or modify it under the terms of the GNU General Public
  3 # License as published by the Free Software Foundation, version 2.
  4 #
  5 # This program is distributed in the hope that it will be useful, but WITHOUT
  6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  7 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  8 # details.
  9 #
  10 # You should have received a copy of the GNU General Public License along with
  11 # this program; if not, write to the Free Software Foundation, Inc., 51
  12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  13 #
  14 # Copyright Buildbot Team Members
  15 
  16 import os, types, re
  17 from twisted.python import runtime
  18 from twisted.internet import reactor
  19 from buildbot.process.buildstep import BuildStep
  20 from buildbot.process.buildstep import SUCCESS, FAILURE
  21 from twisted.internet.protocol import ProcessProtocol
  22 
  23 class MasterShellCommand(BuildStep):
  24     """
  25     Run a shell command locally - on the buildmaster.  The shell command
  26     COMMAND is specified just as for a RemoteShellCommand.  Note that extra
  27     logfiles are not supported.
  28     """
  29     name='MasterShellCommand'
  30     description='Running'
  31     descriptionDone='Ran'
  32     descriptionSuffix = None
  33     renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]
  34     haltOnFailure = True
  35     flunkOnFailure = True
  36 
  37     def __init__(self, command,
  38                  description=None, descriptionDone=None, descriptionSuffix=None,
  39                  env=None, path=None, usePTY=0,
  40                  **kwargs):
  41         BuildStep.__init__(self, **kwargs)
  42 
  43         self.command=command
  44         if description:
  45             self.description = description
  46         if isinstance(self.description, str):
  47             self.description = [self.description]
  48         if descriptionDone:
  49             self.descriptionDone = descriptionDone
  50         if isinstance(self.descriptionDone, str):
  51             self.descriptionDone = [self.descriptionDone]
  52         if descriptionSuffix:
  53             self.descriptionSuffix = descriptionSuffix
  54         if isinstance(self.descriptionSuffix, str):
  55             self.descriptionSuffix = [self.descriptionSuffix]
  56         self.env=env
  57         self.path=path
  58         self.usePTY=usePTY
  59 
  60     class LocalPP(ProcessProtocol):
  61         def __init__(self, step):
  62             self.step = step
  63 
  64         def outReceived(self, data):
  65             self.step.stdio_log.addStdout(data)
  66 
  67         def errReceived(self, data):
  68             self.step.stdio_log.addStderr(data)
  69 
  70         def processEnded(self, status_object):
  71             self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
  72             self.step.processEnded(status_object)
  73 
  74     def start(self):
  75         # render properties
  76         command = self.command
  77         # set up argv
  78         if type(command) in types.StringTypes:
  79             if runtime.platformType  == 'win32':
  80                 argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
  81                 if '/c' not in argv: argv += ['/c']
  82                 argv += [command]
  83             else:
  84                 # for posix, use /bin/sh. for other non-posix, well, doesn't
  85                 # hurt to try
  86                 argv = ['/bin/sh', '-c', command]
  87         else:
  88             if runtime.platformType  == 'win32':
  89                 argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
  90                 if '/c' not in argv: argv += ['/c']
  91                 argv += list(command)
  92             else:
  93                 argv = command
  94 
  95         self.stdio_log = stdio_log = self.addLog("stdio")
  96 
  97         if type(command) in types.StringTypes:
  98             stdio_log.addHeader(command.strip() + "\n\n")
  99         else:
  100             stdio_log.addHeader(" ".join(command) + "\n\n")
  101         stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n")
  102         stdio_log.addHeader(" in dir %s\n" % os.getcwd())
  103         stdio_log.addHeader(" argv: %s\n" % (argv,))
  104         self.step_status.setText(self.describe())
  105 
  106         if self.env is None:
  107             env = os.environ
  108         else:
  109             assert isinstance(self.env, dict)
  110             env = self.env
  111 
  112             # do substitution on variable values matching pattern: ${name}
  113             p = re.compile('\${([0-9a-zA-Z_]*)}')
  114             def subst(match):
  115                 return os.environ.get(match.group(1), "")
  116             newenv = {}
  117             for key in env.keys():
  118                 if env[key] is not None:
  119                     newenv[key] = p.sub(subst, env[key])
  120             env = newenv
  121         stdio_log.addHeader(" env: %r\n" % (env,))
  122 
  123         # TODO add a timeout?
  124         reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
  125                 path=self.path, usePTY=self.usePTY, env=env )
  126         # (the LocalPP object will call processEnded for us)
  127 
  128     def processEnded(self, status_object):
  129         if status_object.value.exitCode != 0:
  130             self.descriptionDone = ["failed (%d)" % status_object.value.exitCode]
  131             self.step_status.setText(self.describe(done=True))
  132             self.finished(FAILURE)
  133         else:
  134             self.step_status.setText(self.describe(done=True))
  135             self.finished(SUCCESS)
  136 
  137     def describe(self, done=False):
  138         desc = self.descriptionDone if done else self.description
  139         if self.descriptionSuffix:
  140             desc = desc[:]
  141             desc.extend(self.descriptionSuffix)
  142         return desc
  143
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/master/buildbot/steps/master.py b/master/buildbot/steps/master.py
  --- a/master/buildbot/steps/master.py
  +++ b/master/buildbot/steps/master.py
  @@ -18,6 +18,7 @@
   from twisted.internet import reactor
   from buildbot.process.buildstep import BuildStep
   from buildbot.process.buildstep import SUCCESS, FAILURE
  +from twisted.internet import error
   from twisted.internet.protocol import ProcessProtocol
   
   class MasterShellCommand(BuildStep):
  @@ -36,7 +37,7 @@
   
       def __init__(self, command,
                    description=None, descriptionDone=None, descriptionSuffix=None,
  -                 env=None, path=None, usePTY=0,
  +                 env=None, path=None, usePTY=0, interruptSignal="KILL",
                    **kwargs):
           BuildStep.__init__(self, **kwargs)
   
  @@ -56,6 +57,7 @@
           self.env=env
           self.path=path
           self.usePTY=usePTY
  +        self.interruptSignal = interruptSignal
   
       class LocalPP(ProcessProtocol):
           def __init__(self, step):
  @@ -68,7 +70,10 @@
               self.step.stdio_log.addStderr(data)
   
           def processEnded(self, status_object):
  -            self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
  +            if status_object.value.exitCode is not None:
  +                self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
  +            if status_object.value.signal is not None:
  +                self.step.stdio_log.addHeader("signal %s\n" % status_object.value.signal)
               self.step.processEnded(status_object)
   
       def start(self):
  @@ -121,12 +126,16 @@
           stdio_log.addHeader(" env: %r\n" % (env,))
   
           # TODO add a timeout?
  -        reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
  +        self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
                   path=self.path, usePTY=self.usePTY, env=env )
           # (the LocalPP object will call processEnded for us)
   
       def processEnded(self, status_object):
  -        if status_object.value.exitCode != 0:
  +        if status_object.value.signal is not None:
  +            self.descriptionDone = ["killed (%s)" % status_object.value.signal]
  +            self.step_status.setText(self.describe(done=True))
  +            self.finished(FAILURE)
  +        elif status_object.value.exitCode != 0:
               self.descriptionDone = ["failed (%d)" % status_object.value.exitCode]
               self.step_status.setText(self.describe(done=True))
               self.finished(FAILURE)
  @@ -140,3 +149,12 @@
               desc = desc[:]
               desc.extend(self.descriptionSuffix)
           return desc
  +
  +    def interrupt(self, reason):
  +        try:
  +            self.process.signalProcess(self.interruptSignal)
  +        except KeyError: # Process not started yet
  +            pass
  +        except error.ProcessExitedAlready:
  +            pass
  +        BuildStep.interrupt(self, reason)
  
verification_info: {"golden_diff": "diff --git a/master/buildbot/steps/master.py b/master/buildbot/steps/master.py\n--- a/master/buildbot/steps/master.py\n+++ b/master/buildbot/steps/master.py\n@@ -18,6 +18,7 @@\n from twisted.internet import reactor\n from buildbot.process.buildstep import BuildStep\n from buildbot.process.buildstep import SUCCESS, FAILURE\n+from twisted.internet import error\n from twisted.internet.protocol import ProcessProtocol\n \n class MasterShellCommand(BuildStep):\n@@ -36,7 +37,7 @@\n \n     def __init__(self, command,\n                  description=None, descriptionDone=None, descriptionSuffix=None,\n-                 env=None, path=None, usePTY=0,\n+                 env=None, path=None, usePTY=0, interruptSignal=\"KILL\",\n                  **kwargs):\n         BuildStep.__init__(self, **kwargs)\n \n@@ -56,6 +57,7 @@\n         self.env=env\n         self.path=path\n         self.usePTY=usePTY\n+        self.interruptSignal = interruptSignal\n \n     class LocalPP(ProcessProtocol):\n         def __init__(self, step):\n@@ -68,7 +70,10 @@\n             self.step.stdio_log.addStderr(data)\n \n         def processEnded(self, status_object):\n-            self.step.stdio_log.addHeader(\"exit status %d\\n\" % status_object.value.exitCode)\n+            if status_object.value.exitCode is not None:\n+                self.step.stdio_log.addHeader(\"exit status %d\\n\" % status_object.value.exitCode)\n+            if status_object.value.signal is not None:\n+                self.step.stdio_log.addHeader(\"signal %s\\n\" % status_object.value.signal)\n             self.step.processEnded(status_object)\n \n     def start(self):\n@@ -121,12 +126,16 @@\n         stdio_log.addHeader(\" env: %r\\n\" % (env,))\n \n         # TODO add a timeout?\n-        reactor.spawnProcess(self.LocalPP(self), argv[0], argv,\n+        self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,\n                 path=self.path, usePTY=self.usePTY, env=env )\n         # (the LocalPP object will call processEnded for us)\n \n     def processEnded(self, status_object):\n-        if status_object.value.exitCode != 0:\n+        if status_object.value.signal is not None:\n+            self.descriptionDone = [\"killed (%s)\" % status_object.value.signal]\n+            self.step_status.setText(self.describe(done=True))\n+            self.finished(FAILURE)\n+        elif status_object.value.exitCode != 0:\n             self.descriptionDone = [\"failed (%d)\" % status_object.value.exitCode]\n             self.step_status.setText(self.describe(done=True))\n             self.finished(FAILURE)\n@@ -140,3 +149,12 @@\n             desc = desc[:]\n             desc.extend(self.descriptionSuffix)\n         return desc\n+\n+    def interrupt(self, reason):\n+        try:\n+            self.process.signalProcess(self.interruptSignal)\n+        except KeyError: # Process not started yet\n+            pass\n+        except error.ProcessExitedAlready:\n+            pass\n+        BuildStep.interrupt(self, reason)\n", "issue": "Expose builder.tags to web templates.\nThis tiny PR exposes the builders' \"tags\" attribute to the templates, allowing me to customize the templates using that feature.\n\n", "before_files": [{"content": "# This file is part of Buildbot.  Buildbot is free software: you can\n# redistribute it and/or modify it under the terms of the GNU General Public\n# License as published by the Free Software Foundation, version 2.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\n# details.\n#\n# You should have received a copy of the GNU General Public License along with\n# this program; if not, write to the Free Software Foundation, Inc., 51\n# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Copyright Buildbot Team Members\n\nimport os, types, re\nfrom twisted.python import runtime\nfrom twisted.internet import reactor\nfrom buildbot.process.buildstep import BuildStep\nfrom buildbot.process.buildstep import SUCCESS, FAILURE\nfrom twisted.internet.protocol import ProcessProtocol\n\nclass MasterShellCommand(BuildStep):\n    \"\"\"\n    Run a shell command locally - on the buildmaster.  The shell command\n    COMMAND is specified just as for a RemoteShellCommand.  Note that extra\n    logfiles are not supported.\n    \"\"\"\n    name='MasterShellCommand'\n    description='Running'\n    descriptionDone='Ran'\n    descriptionSuffix = None\n    renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]\n    haltOnFailure = True\n    flunkOnFailure = True\n\n    def __init__(self, command,\n                 description=None, descriptionDone=None, descriptionSuffix=None,\n                 env=None, path=None, usePTY=0,\n                 **kwargs):\n        BuildStep.__init__(self, **kwargs)\n\n        self.command=command\n        if description:\n            self.description = description\n        if isinstance(self.description, str):\n            self.description = [self.description]\n        if descriptionDone:\n            self.descriptionDone = descriptionDone\n        if isinstance(self.descriptionDone, str):\n            self.descriptionDone = [self.descriptionDone]\n        if descriptionSuffix:\n            self.descriptionSuffix = descriptionSuffix\n        if isinstance(self.descriptionSuffix, str):\n            self.descriptionSuffix = [self.descriptionSuffix]\n        self.env=env\n        self.path=path\n        self.usePTY=usePTY\n\n    class LocalPP(ProcessProtocol):\n        def __init__(self, step):\n            self.step = step\n\n        def outReceived(self, data):\n            self.step.stdio_log.addStdout(data)\n\n        def errReceived(self, data):\n            self.step.stdio_log.addStderr(data)\n\n        def processEnded(self, status_object):\n            self.step.stdio_log.addHeader(\"exit status %d\\n\" % status_object.value.exitCode)\n            self.step.processEnded(status_object)\n\n    def start(self):\n        # render properties\n        command = self.command\n        # set up argv\n        if type(command) in types.StringTypes:\n            if runtime.platformType  == 'win32':\n                argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args\n                if '/c' not in argv: argv += ['/c']\n                argv += [command]\n            else:\n                # for posix, use /bin/sh. for other non-posix, well, doesn't\n                # hurt to try\n                argv = ['/bin/sh', '-c', command]\n        else:\n            if runtime.platformType  == 'win32':\n                argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args\n                if '/c' not in argv: argv += ['/c']\n                argv += list(command)\n            else:\n                argv = command\n\n        self.stdio_log = stdio_log = self.addLog(\"stdio\")\n\n        if type(command) in types.StringTypes:\n            stdio_log.addHeader(command.strip() + \"\\n\\n\")\n        else:\n            stdio_log.addHeader(\" \".join(command) + \"\\n\\n\")\n        stdio_log.addHeader(\"** RUNNING ON BUILDMASTER **\\n\")\n        stdio_log.addHeader(\" in dir %s\\n\" % os.getcwd())\n        stdio_log.addHeader(\" argv: %s\\n\" % (argv,))\n        self.step_status.setText(self.describe())\n\n        if self.env is None:\n            env = os.environ\n        else:\n            assert isinstance(self.env, dict)\n            env = self.env\n\n            # do substitution on variable values matching pattern: ${name}\n            p = re.compile('\\${([0-9a-zA-Z_]*)}')\n            def subst(match):\n                return os.environ.get(match.group(1), \"\")\n            newenv = {}\n            for key in env.keys():\n                if env[key] is not None:\n                    newenv[key] = p.sub(subst, env[key])\n            env = newenv\n        stdio_log.addHeader(\" env: %r\\n\" % (env,))\n\n        # TODO add a timeout?\n        reactor.spawnProcess(self.LocalPP(self), argv[0], argv,\n                path=self.path, usePTY=self.usePTY, env=env )\n        # (the LocalPP object will call processEnded for us)\n\n    def processEnded(self, status_object):\n        if status_object.value.exitCode != 0:\n            self.descriptionDone = [\"failed (%d)\" % status_object.value.exitCode]\n            self.step_status.setText(self.describe(done=True))\n            self.finished(FAILURE)\n        else:\n            self.step_status.setText(self.describe(done=True))\n            self.finished(SUCCESS)\n\n    def describe(self, done=False):\n        desc = self.descriptionDone if done else self.description\n        if self.descriptionSuffix:\n            desc = desc[:]\n            desc.extend(self.descriptionSuffix)\n        return desc\n", "path": "master/buildbot/steps/master.py"}], "after_files": [{"content": "# This file is part of Buildbot.  Buildbot is free software: you can\n# redistribute it and/or modify it under the terms of the GNU General Public\n# License as published by the Free Software Foundation, version 2.\n#\n# This program is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\n# details.\n#\n# You should have received a copy of the GNU General Public License along with\n# this program; if not, write to the Free Software Foundation, Inc., 51\n# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Copyright Buildbot Team Members\n\nimport os, types, re\nfrom twisted.python import runtime\nfrom twisted.internet import reactor\nfrom buildbot.process.buildstep import BuildStep\nfrom buildbot.process.buildstep import SUCCESS, FAILURE\nfrom twisted.internet import error\nfrom twisted.internet.protocol import ProcessProtocol\n\nclass MasterShellCommand(BuildStep):\n    \"\"\"\n    Run a shell command locally - on the buildmaster.  The shell command\n    COMMAND is specified just as for a RemoteShellCommand.  Note that extra\n    logfiles are not supported.\n    \"\"\"\n    name='MasterShellCommand'\n    description='Running'\n    descriptionDone='Ran'\n    descriptionSuffix = None\n    renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]\n    haltOnFailure = True\n    flunkOnFailure = True\n\n    def __init__(self, command,\n                 description=None, descriptionDone=None, descriptionSuffix=None,\n                 env=None, path=None, usePTY=0, interruptSignal=\"KILL\",\n                 **kwargs):\n        BuildStep.__init__(self, **kwargs)\n\n        self.command=command\n        if description:\n            self.description = description\n        if isinstance(self.description, str):\n            self.description = [self.description]\n        if descriptionDone:\n            self.descriptionDone = descriptionDone\n        if isinstance(self.descriptionDone, str):\n            self.descriptionDone = [self.descriptionDone]\n        if descriptionSuffix:\n            self.descriptionSuffix = descriptionSuffix\n        if isinstance(self.descriptionSuffix, str):\n            self.descriptionSuffix = [self.descriptionSuffix]\n        self.env=env\n        self.path=path\n        self.usePTY=usePTY\n        self.interruptSignal = interruptSignal\n\n    class LocalPP(ProcessProtocol):\n        def __init__(self, step):\n            self.step = step\n\n        def outReceived(self, data):\n            self.step.stdio_log.addStdout(data)\n\n        def errReceived(self, data):\n            self.step.stdio_log.addStderr(data)\n\n        def processEnded(self, status_object):\n            if status_object.value.exitCode is not None:\n                self.step.stdio_log.addHeader(\"exit status %d\\n\" % status_object.value.exitCode)\n            if status_object.value.signal is not None:\n                self.step.stdio_log.addHeader(\"signal %s\\n\" % status_object.value.signal)\n            self.step.processEnded(status_object)\n\n    def start(self):\n        # render properties\n        command = self.command\n        # set up argv\n        if type(command) in types.StringTypes:\n            if runtime.platformType  == 'win32':\n                argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args\n                if '/c' not in argv: argv += ['/c']\n                argv += [command]\n            else:\n                # for posix, use /bin/sh. for other non-posix, well, doesn't\n                # hurt to try\n                argv = ['/bin/sh', '-c', command]\n        else:\n            if runtime.platformType  == 'win32':\n                argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args\n                if '/c' not in argv: argv += ['/c']\n                argv += list(command)\n            else:\n                argv = command\n\n        self.stdio_log = stdio_log = self.addLog(\"stdio\")\n\n        if type(command) in types.StringTypes:\n            stdio_log.addHeader(command.strip() + \"\\n\\n\")\n        else:\n            stdio_log.addHeader(\" \".join(command) + \"\\n\\n\")\n        stdio_log.addHeader(\"** RUNNING ON BUILDMASTER **\\n\")\n        stdio_log.addHeader(\" in dir %s\\n\" % os.getcwd())\n        stdio_log.addHeader(\" argv: %s\\n\" % (argv,))\n        self.step_status.setText(self.describe())\n\n        if self.env is None:\n            env = os.environ\n        else:\n            assert isinstance(self.env, dict)\n            env = self.env\n\n            # do substitution on variable values matching pattern: ${name}\n            p = re.compile('\\${([0-9a-zA-Z_]*)}')\n            def subst(match):\n                return os.environ.get(match.group(1), \"\")\n            newenv = {}\n            for key in env.keys():\n                if env[key] is not None:\n                    newenv[key] = p.sub(subst, env[key])\n            env = newenv\n        stdio_log.addHeader(\" env: %r\\n\" % (env,))\n\n        # TODO add a timeout?\n        self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,\n                path=self.path, usePTY=self.usePTY, env=env )\n        # (the LocalPP object will call processEnded for us)\n\n    def processEnded(self, status_object):\n        if status_object.value.signal is not None:\n            self.descriptionDone = [\"killed (%s)\" % status_object.value.signal]\n            self.step_status.setText(self.describe(done=True))\n            self.finished(FAILURE)\n        elif status_object.value.exitCode != 0:\n            self.descriptionDone = [\"failed (%d)\" % status_object.value.exitCode]\n            self.step_status.setText(self.describe(done=True))\n            self.finished(FAILURE)\n        else:\n            self.step_status.setText(self.describe(done=True))\n            self.finished(SUCCESS)\n\n    def describe(self, done=False):\n        desc = self.descriptionDone if done else self.description\n        if self.descriptionSuffix:\n            desc = desc[:]\n            desc.extend(self.descriptionSuffix)\n        return desc\n\n    def interrupt(self, reason):\n        try:\n            self.process.signalProcess(self.interruptSignal)\n        except KeyError: # Process not started yet\n            pass\n        except error.ProcessExitedAlready:\n            pass\n        BuildStep.interrupt(self, reason)\n", "path": "master/buildbot/steps/master.py"}]}