prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  parsl.providers.cluster_provider _write_submit_script should return nothing, rather than constant True
  **Describe the bug**
  
  _write_submit_script in parsl.providers.cluster_provider indicates failure by raising an exception, and so should not be returning a True (or False) value. Instead it should return None by either `return` on its own, or falling off the end of the method without a return statement.
  
  To tidy this up, change that return handling. Edit the docstring to match.
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `parsl/providers/cluster_provider.py`
  Content:
  ```
  1 import logging
  2 from abc import abstractmethod
  3 from string import Template
  4 
  5 from parsl.providers.errors import SchedulerMissingArgs, ScriptPathError
  6 from parsl.launchers.base import Launcher
  7 from parsl.launchers.errors import BadLauncher
  8 from parsl.providers.base import ExecutionProvider
  9 
  10 logger = logging.getLogger(__name__)
  11 
  12 
  13 class ClusterProvider(ExecutionProvider):
  14     """ This class defines behavior common to all cluster/supercompute-style scheduler systems.
  15 
  16     Parameters
  17     ----------
  18       label : str
  19         Label for this provider.
  20       channel : Channel
  21         Channel for accessing this provider. Possible channels include
  22         :class:`~parsl.channels.LocalChannel` (the default),
  23         :class:`~parsl.channels.SSHChannel`, or
  24         :class:`~parsl.channels.SSHInteractiveLoginChannel`.
  25       walltime : str
  26         Walltime requested per block in HH:MM:SS.
  27       launcher : Launcher
  28         Launcher for this provider.
  29       cmd_timeout : int
  30         Timeout for commands made to the scheduler in seconds
  31 
  32     .. code:: python
  33 
  34                                 +------------------
  35                                 |
  36           script_string ------->|  submit
  37                id      <--------|---+
  38                                 |
  39           [ ids ]       ------->|  status
  40           [statuses]   <--------|----+
  41                                 |
  42           [ ids ]       ------->|  cancel
  43           [cancel]     <--------|----+
  44                                 |
  45                                 +-------------------
  46     """
  47 
  48     def __init__(self,
  49                  label,
  50                  channel,
  51                  nodes_per_block,
  52                  init_blocks,
  53                  min_blocks,
  54                  max_blocks,
  55                  parallelism,
  56                  walltime,
  57                  launcher,
  58                  cmd_timeout=10):
  59 
  60         self._label = label
  61         self.channel = channel
  62         self.nodes_per_block = nodes_per_block
  63         self.init_blocks = init_blocks
  64         self.min_blocks = min_blocks
  65         self.max_blocks = max_blocks
  66         self.parallelism = parallelism
  67         self.launcher = launcher
  68         self.walltime = walltime
  69         self.cmd_timeout = cmd_timeout
  70         if not isinstance(self.launcher, Launcher):
  71             raise BadLauncher(self.launcher)
  72 
  73         self.script_dir = None
  74 
  75         # Dictionary that keeps track of jobs, keyed on job_id
  76         self.resources = {}
  77 
  78     def execute_wait(self, cmd, timeout=None):
  79         t = self.cmd_timeout
  80         if timeout is not None:
  81             t = timeout
  82         return self.channel.execute_wait(cmd, t)
  83 
  84     def _write_submit_script(self, template, script_filename, job_name, configs):
  85         """Generate submit script and write it to a file.
  86 
  87         Args:
  88               - template (string) : The template string to be used for the writing submit script
  89               - script_filename (string) : Name of the submit script
  90               - job_name (string) : job name
  91               - configs (dict) : configs that get pushed into the template
  92 
  93         Returns:
  94               - True: on success
  95 
  96         Raises:
  97               SchedulerMissingArgs : If template is missing args
  98               ScriptPathError : Unable to write submit script out
  99         """
  100 
  101         try:
  102             submit_script = Template(template).substitute(jobname=job_name, **configs)
  103             with open(script_filename, 'w') as f:
  104                 f.write(submit_script)
  105 
  106         except KeyError as e:
  107             logger.error("Missing keys for submit script : %s", e)
  108             raise SchedulerMissingArgs(e.args, self.label)
  109 
  110         except IOError as e:
  111             logger.error("Failed writing to submit script: %s", script_filename)
  112             raise ScriptPathError(script_filename, e)
  113         except Exception as e:
  114             print("Template : ", template)
  115             print("Args : ", job_name)
  116             print("Kwargs : ", configs)
  117             logger.error("Uncategorized error: %s", e)
  118             raise e
  119 
  120         return True
  121 
  122     @abstractmethod
  123     def _status(self):
  124         pass
  125 
  126     def status(self, job_ids):
  127         """ Get the status of a list of jobs identified by the job identifiers
  128         returned from the submit request.
  129 
  130         Args:
  131              - job_ids (list) : A list of job identifiers
  132 
  133         Returns:
  134              - A list of JobStatus objects corresponding to each job_id in the job_ids list.
  135 
  136         Raises:
  137              - ExecutionProviderException or its subclasses
  138 
  139         """
  140         if job_ids:
  141             self._status()
  142         return [self.resources[jid]['status'] for jid in job_ids]
  143 
  144     @property
  145     def label(self):
  146         return self._label
  147
  ```
  --- 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/parsl/providers/cluster_provider.py b/parsl/providers/cluster_provider.py
  --- a/parsl/providers/cluster_provider.py
  +++ b/parsl/providers/cluster_provider.py
  @@ -91,7 +91,7 @@
                 - configs (dict) : configs that get pushed into the template
   
           Returns:
  -              - True: on success
  +              - None
   
           Raises:
                 SchedulerMissingArgs : If template is missing args
  @@ -117,8 +117,6 @@
               logger.error("Uncategorized error: %s", e)
               raise e
   
  -        return True
  -
       @abstractmethod
       def _status(self):
           pass
  
verification_info: {"golden_diff": "diff --git a/parsl/providers/cluster_provider.py b/parsl/providers/cluster_provider.py\n--- a/parsl/providers/cluster_provider.py\n+++ b/parsl/providers/cluster_provider.py\n@@ -91,7 +91,7 @@\n               - configs (dict) : configs that get pushed into the template\n \n         Returns:\n-              - True: on success\n+              - None\n \n         Raises:\n               SchedulerMissingArgs : If template is missing args\n@@ -117,8 +117,6 @@\n             logger.error(\"Uncategorized error: %s\", e)\n             raise e\n \n-        return True\n-\n     @abstractmethod\n     def _status(self):\n         pass\n", "issue": "parsl.providers.cluster_provider _write_submit_script should return nothing, rather than constant True\n**Describe the bug**\r\n\r\n_write_submit_script in parsl.providers.cluster_provider indicates failure by raising an exception, and so should not be returning a True (or False) value. Instead it should return None by either `return` on its own, or falling off the end of the method without a return statement.\r\n\r\nTo tidy this up, change that return handling. Edit the docstring to match.\r\n\r\n\n", "before_files": [{"content": "import logging\nfrom abc import abstractmethod\nfrom string import Template\n\nfrom parsl.providers.errors import SchedulerMissingArgs, ScriptPathError\nfrom parsl.launchers.base import Launcher\nfrom parsl.launchers.errors import BadLauncher\nfrom parsl.providers.base import ExecutionProvider\n\nlogger = logging.getLogger(__name__)\n\n\nclass ClusterProvider(ExecutionProvider):\n    \"\"\" This class defines behavior common to all cluster/supercompute-style scheduler systems.\n\n    Parameters\n    ----------\n      label : str\n        Label for this provider.\n      channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n      walltime : str\n        Walltime requested per block in HH:MM:SS.\n      launcher : Launcher\n        Launcher for this provider.\n      cmd_timeout : int\n        Timeout for commands made to the scheduler in seconds\n\n    .. code:: python\n\n                                +------------------\n                                |\n          script_string ------->|  submit\n               id      <--------|---+\n                                |\n          [ ids ]       ------->|  status\n          [statuses]   <--------|----+\n                                |\n          [ ids ]       ------->|  cancel\n          [cancel]     <--------|----+\n                                |\n                                +-------------------\n    \"\"\"\n\n    def __init__(self,\n                 label,\n                 channel,\n                 nodes_per_block,\n                 init_blocks,\n                 min_blocks,\n                 max_blocks,\n                 parallelism,\n                 walltime,\n                 launcher,\n                 cmd_timeout=10):\n\n        self._label = label\n        self.channel = channel\n        self.nodes_per_block = nodes_per_block\n        self.init_blocks = init_blocks\n        self.min_blocks = min_blocks\n        self.max_blocks = max_blocks\n        self.parallelism = parallelism\n        self.launcher = launcher\n        self.walltime = walltime\n        self.cmd_timeout = cmd_timeout\n        if not isinstance(self.launcher, Launcher):\n            raise BadLauncher(self.launcher)\n\n        self.script_dir = None\n\n        # Dictionary that keeps track of jobs, keyed on job_id\n        self.resources = {}\n\n    def execute_wait(self, cmd, timeout=None):\n        t = self.cmd_timeout\n        if timeout is not None:\n            t = timeout\n        return self.channel.execute_wait(cmd, t)\n\n    def _write_submit_script(self, template, script_filename, job_name, configs):\n        \"\"\"Generate submit script and write it to a file.\n\n        Args:\n              - template (string) : The template string to be used for the writing submit script\n              - script_filename (string) : Name of the submit script\n              - job_name (string) : job name\n              - configs (dict) : configs that get pushed into the template\n\n        Returns:\n              - True: on success\n\n        Raises:\n              SchedulerMissingArgs : If template is missing args\n              ScriptPathError : Unable to write submit script out\n        \"\"\"\n\n        try:\n            submit_script = Template(template).substitute(jobname=job_name, **configs)\n            with open(script_filename, 'w') as f:\n                f.write(submit_script)\n\n        except KeyError as e:\n            logger.error(\"Missing keys for submit script : %s\", e)\n            raise SchedulerMissingArgs(e.args, self.label)\n\n        except IOError as e:\n            logger.error(\"Failed writing to submit script: %s\", script_filename)\n            raise ScriptPathError(script_filename, e)\n        except Exception as e:\n            print(\"Template : \", template)\n            print(\"Args : \", job_name)\n            print(\"Kwargs : \", configs)\n            logger.error(\"Uncategorized error: %s\", e)\n            raise e\n\n        return True\n\n    @abstractmethod\n    def _status(self):\n        pass\n\n    def status(self, job_ids):\n        \"\"\" Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Args:\n             - job_ids (list) : A list of job identifiers\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        \"\"\"\n        if job_ids:\n            self._status()\n        return [self.resources[jid]['status'] for jid in job_ids]\n\n    @property\n    def label(self):\n        return self._label\n", "path": "parsl/providers/cluster_provider.py"}], "after_files": [{"content": "import logging\nfrom abc import abstractmethod\nfrom string import Template\n\nfrom parsl.providers.errors import SchedulerMissingArgs, ScriptPathError\nfrom parsl.launchers.base import Launcher\nfrom parsl.launchers.errors import BadLauncher\nfrom parsl.providers.base import ExecutionProvider\n\nlogger = logging.getLogger(__name__)\n\n\nclass ClusterProvider(ExecutionProvider):\n    \"\"\" This class defines behavior common to all cluster/supercompute-style scheduler systems.\n\n    Parameters\n    ----------\n      label : str\n        Label for this provider.\n      channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n      walltime : str\n        Walltime requested per block in HH:MM:SS.\n      launcher : Launcher\n        Launcher for this provider.\n      cmd_timeout : int\n        Timeout for commands made to the scheduler in seconds\n\n    .. code:: python\n\n                                +------------------\n                                |\n          script_string ------->|  submit\n               id      <--------|---+\n                                |\n          [ ids ]       ------->|  status\n          [statuses]   <--------|----+\n                                |\n          [ ids ]       ------->|  cancel\n          [cancel]     <--------|----+\n                                |\n                                +-------------------\n    \"\"\"\n\n    def __init__(self,\n                 label,\n                 channel,\n                 nodes_per_block,\n                 init_blocks,\n                 min_blocks,\n                 max_blocks,\n                 parallelism,\n                 walltime,\n                 launcher,\n                 cmd_timeout=10):\n\n        self._label = label\n        self.channel = channel\n        self.nodes_per_block = nodes_per_block\n        self.init_blocks = init_blocks\n        self.min_blocks = min_blocks\n        self.max_blocks = max_blocks\n        self.parallelism = parallelism\n        self.launcher = launcher\n        self.walltime = walltime\n        self.cmd_timeout = cmd_timeout\n        if not isinstance(self.launcher, Launcher):\n            raise BadLauncher(self.launcher)\n\n        self.script_dir = None\n\n        # Dictionary that keeps track of jobs, keyed on job_id\n        self.resources = {}\n\n    def execute_wait(self, cmd, timeout=None):\n        t = self.cmd_timeout\n        if timeout is not None:\n            t = timeout\n        return self.channel.execute_wait(cmd, t)\n\n    def _write_submit_script(self, template, script_filename, job_name, configs):\n        \"\"\"Generate submit script and write it to a file.\n\n        Args:\n              - template (string) : The template string to be used for the writing submit script\n              - script_filename (string) : Name of the submit script\n              - job_name (string) : job name\n              - configs (dict) : configs that get pushed into the template\n\n        Returns:\n              - None\n\n        Raises:\n              SchedulerMissingArgs : If template is missing args\n              ScriptPathError : Unable to write submit script out\n        \"\"\"\n\n        try:\n            submit_script = Template(template).substitute(jobname=job_name, **configs)\n            with open(script_filename, 'w') as f:\n                f.write(submit_script)\n\n        except KeyError as e:\n            logger.error(\"Missing keys for submit script : %s\", e)\n            raise SchedulerMissingArgs(e.args, self.label)\n\n        except IOError as e:\n            logger.error(\"Failed writing to submit script: %s\", script_filename)\n            raise ScriptPathError(script_filename, e)\n        except Exception as e:\n            print(\"Template : \", template)\n            print(\"Args : \", job_name)\n            print(\"Kwargs : \", configs)\n            logger.error(\"Uncategorized error: %s\", e)\n            raise e\n\n    @abstractmethod\n    def _status(self):\n        pass\n\n    def status(self, job_ids):\n        \"\"\" Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Args:\n             - job_ids (list) : A list of job identifiers\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        \"\"\"\n        if job_ids:\n            self._status()\n        return [self.resources[jid]['status'] for jid in job_ids]\n\n    @property\n    def label(self):\n        return self._label\n", "path": "parsl/providers/cluster_provider.py"}]}