We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Pandas DataFrames as Default Values
Parsl does not work with Pandas DataFrames as the default value to a keyword argument.

For example,

```python
data = pd.DataFrame({'x': [None,2,[3]]})
@App('python', dfk)
def f(d=data):
    return d.sum()
f().result()
```
yields an error

```
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-23-cba3cd6e0846> in <module>()
      3 def f(d=data):
      4     return d.sum()
----> 5 f().result()

~/miniconda3/lib/python3.6/site-packages/parsl/app/app_factory.py in __call__(self, *args, **kwargs)
     73                                  walltime=self.walltime,
     74                                  cache=self.cache,
---> 75                                  fn_hash=self.func_hash)
     76         return app_obj(*args, **kwargs)
     77 

~/miniconda3/lib/python3.6/site-packages/parsl/app/python_app.py in __init__(self, func, executor, walltime, cache, sites, fn_hash)
     16         This bit is the same for both bash & python apps.
     17         """
---> 18         super().__init__(func, executor, walltime=walltime, sites=sites, exec_type="python")
     19         self.fn_hash = fn_hash
     20         self.cache = cache

~/miniconda3/lib/python3.6/site-packages/parsl/app/app.py in __init__(self, func, executor, walltime, sites, cache, exec_type)
     47         self.kwargs = {}
     48         for s in sig.parameters:
---> 49             if sig.parameters[s].default != Parameter.empty:
     50                 self.kwargs[s] = sig.parameters[s].default
     51 

~/miniconda3/lib/python3.6/site-packages/pandas/core/generic.py in __nonzero__(self)
   1119         raise ValueError("The truth value of a {0} is ambiguous. "
   1120                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1121                          .format(self.__class__.__name__))
   1122 
   1123     __bool__ = __nonzero__

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().```

--- 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/app/bash_app.py`
Content:
```
1 import logging
2 
3 from parsl.app.futures import DataFuture
4 from parsl.app.app import AppBase
5 
6 logger = logging.getLogger(__name__)
7 
8 
9 def remote_side_bash_executor(func, *args, **kwargs):
10     """Execute the bash app type function and return the command line string.
11 
12     This string is reformatted with the *args, and **kwargs
13     from call time.
14     """
15     import os
16     import time
17     import subprocess
18     import logging
19     import parsl.app.errors as pe
20 
21     logging.basicConfig(filename='/tmp/bashexec.{0}.log'.format(time.time()), level=logging.DEBUG)
22 
23     # start_t = time.time()
24 
25     func_name = func.__name__
26 
27     # Try to run the func to compose the commandline
28     try:
29         # Execute the func to get the commandline
30         partial_cmdline = func(*args, **kwargs)
31         # Reformat the commandline with current args and kwargs
32         executable = partial_cmdline.format(*args, **kwargs)
33 
34     except AttributeError as e:
35         if partial_cmdline:
36             raise pe.AppBadFormatting("[{}] AppFormatting failed during cmd_line resolution {}".format(func_name,
37                                                                                                        e), None)
38         else:
39             raise pe.BashAppNoReturn("[{}] Bash App returned NoneType, must return str object".format(func_name), None)
40 
41     except IndexError as e:
42         raise pe.AppBadFormatting("[{}] AppFormatting failed during cmd_line resolution {}".format(func_name,
43                                                                                                    e), None)
44     except Exception as e:
45         logging.error("[{}] Caught exception during cmd_line resolution : {}".format(func_name,
46                                                                                      e))
47         raise e
48 
49     # Updating stdout, stderr if values passed at call time.
50     stdout = kwargs.get('stdout', None)
51     stderr = kwargs.get('stderr', None)
52     timeout = kwargs.get('walltime', None)
53     logging.debug("Stdout  : %s", stdout)
54     logging.debug("Stderr  : %s", stderr)
55 
56     try:
57         std_out = open(stdout, 'w') if stdout else None
58     except Exception as e:
59         raise pe.BadStdStreamFile(stdout, e)
60 
61     try:
62         std_err = open(stderr, 'w') if stderr else None
63     except Exception as e:
64         raise pe.BadStdStreamFile(stderr, e)
65 
66     returncode = None
67     try:
68         proc = subprocess.Popen(executable, stdout=std_out, stderr=std_err, shell=True, executable='/bin/bash')
69         proc.wait(timeout=timeout)
70         returncode = proc.returncode
71 
72     except subprocess.TimeoutExpired as e:
73         print("Timeout")
74         raise pe.AppTimeout("[{}] App exceeded walltime: {}".format(func_name, timeout), e)
75 
76     except Exception as e:
77         print("Caught exception : ", e)
78         raise pe.AppException("[{}] App caught exception : {}".format(func_name, proc.returncode), e)
79 
80     if returncode != 0:
81         raise pe.AppFailure("[{}] App Failed exit code: {}".format(func_name, proc.returncode), proc.returncode)
82 
83     # TODO : Add support for globs here
84 
85     missing = []
86     for outputfile in kwargs.get('outputs', []):
87         fpath = outputfile
88         if type(outputfile) != str:
89             fpath = outputfile.filepath
90 
91         if not os.path.exists(fpath):
92             missing.extend([outputfile])
93 
94     if missing:
95         raise pe.MissingOutputs("[{}] Missing outputs".format(func_name), missing)
96 
97     # exec_duration = time.time() - start_t
98     return returncode
99 
100 
101 class BashApp(AppBase):
102 
103     def __init__(self, func, executor, walltime=60, cache=False,
104                  sites='all', fn_hash=None):
105         """Initialize the super.
106 
107         This bit is the same for both bash & python apps.
108         """
109         super().__init__(func, executor, walltime=60, sites=sites, exec_type="bash")
110         self.fn_hash = fn_hash
111         self.cache = cache
112 
113     def __call__(self, *args, **kwargs):
114         """Handle the call to a Bash app.
115 
116         Args:
117              - Arbitrary
118 
119         Kwargs:
120              - Arbitrary
121 
122         Returns:
123              If outputs=[...] was a kwarg then:
124                    App_fut, [Data_Futures...]
125              else:
126                    App_fut
127 
128         """
129         # Update kwargs in the app definition with one's passed in at calltime
130         self.kwargs.update(kwargs)
131 
132         app_fut = self.executor.submit(remote_side_bash_executor, self.func, *args,
133                                        parsl_sites=self.sites,
134                                        fn_hash=self.fn_hash,
135                                        cache=self.cache,
136                                        **self.kwargs)
137 
138         out_futs = [DataFuture(app_fut, o, parent=app_fut, tid=app_fut.tid)
139                     for o in kwargs.get('outputs', [])]
140         app_fut._outputs = out_futs
141 
142         return app_fut
143
```

Path: `parsl/app/app.py`
Content:
```
1 """Definitions for the @App decorator and the APP classes.
2 
3 The APP class encapsulates a generic leaf task that can be executed asynchronously.
4 
5 """
6 import logging
7 from inspect import signature, Parameter
8 
9 # Logging moved here in the PEP8 conformance fixes.
10 logger = logging.getLogger(__name__)
11 
12 
13 class AppBase (object):
14     """This is the base class that defines the two external facing functions that an App must define.
15 
16     The  __init__ () which is called when the interpreter sees the definition of the decorated
17     function, and the __call__ () which is invoked when a decorated function is called by the user.
18 
19     """
20 
21     def __init__(self, func, executor, walltime=60, sites='all', cache=False, exec_type="bash"):
22         """Constructor for the APP object.
23 
24         Args:
25              - func (function): Takes the function to be made into an App
26              - executor (executor): Executor for the execution resource
27 
28         Kwargs:
29              - walltime (int) : Walltime in seconds for the app execution
30              - sites (str|list) : List of site names that this app could execute over. default is 'all'
31              - exec_type (string) : App type (bash|python)
32              - cache (Bool) : Enable caching of this app ?
33 
34         Returns:
35              - APP object.
36 
37         """
38         self.__name__ = func.__name__
39         self.func = func
40         self.executor = executor
41         self.exec_type = exec_type
42         self.status = 'created'
43         self.sites = sites
44         self.cache = cache
45 
46         sig = signature(func)
47         self.kwargs = {}
48         for s in sig.parameters:
49             if sig.parameters[s].default != Parameter.empty:
50                 self.kwargs[s] = sig.parameters[s].default
51 
52         self.stdout = sig.parameters['stdout'].default if 'stdout' in sig.parameters else None
53         self.stderr = sig.parameters['stderr'].default if 'stderr' in sig.parameters else None
54         self.inputs = sig.parameters['inputs'].default if 'inputs' in sig.parameters else []
55         self.outputs = sig.parameters['outputs'].default if 'outputs' in sig.parameters else []
56 
57     def __call__(self, *args, **kwargs):
58         """The __call__ function must be implemented in the subclasses."""
59         raise NotImplementedError
60 
61 
62 def app_wrapper(func):
63 
64     def wrapper(*args, **kwargs):
65         logger.debug("App wrapper begins")
66         x = func(*args, **kwargs)
67         logger.debug("App wrapper ends")
68         return x
69 
70     return wrapper
71 
72 
73 def App(apptype, executor, walltime=60, cache=False, sites='all'):
74     """The App decorator function.
75 
76     Args:
77         - apptype (string) : Apptype can be bash|python
78         - executor (Executor) : Executor object wrapping threads/process pools etc.
79 
80     Kwargs:
81         - walltime (int) : Walltime for app in seconds,
82              default=60
83         - sites (str|List) : List of site names on which the app could execute
84              default='all'
85         - cache (Bool) : Enable caching of the app call
86              default=False
87 
88     Returns:
89          An AppFactory object, which when called runs the apps through the executor.
90     """
91     from parsl import APP_FACTORY_FACTORY
92 
93     def Exec(f):
94         return APP_FACTORY_FACTORY.make(apptype, executor, f,
95                                         sites=sites,
96                                         cache=cache,
97                                         walltime=walltime)
98 
99     return Exec
100
```
--- 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/parsl/app/app.py b/parsl/app/app.py
--- a/parsl/app/app.py
+++ b/parsl/app/app.py
@@ -1,16 +1,14 @@
-"""Definitions for the @App decorator and the APP classes.
-
-The APP class encapsulates a generic leaf task that can be executed asynchronously.
+"""Definitions for the @App decorator and the App classes.
 
+The App class encapsulates a generic leaf task that can be executed asynchronously.
 """
 import logging
-from inspect import signature, Parameter
+from inspect import signature
 
-# Logging moved here in the PEP8 conformance fixes.
 logger = logging.getLogger(__name__)
 
 
-class AppBase (object):
+class AppBase(object):
     """This is the base class that defines the two external facing functions that an App must define.
 
     The  __init__ () which is called when the interpreter sees the definition of the decorated
@@ -43,16 +41,15 @@
         self.sites = sites
         self.cache = cache
 
-        sig = signature(func)
+        params = signature(func).parameters
+
         self.kwargs = {}
-        for s in sig.parameters:
-            if sig.parameters[s].default != Parameter.empty:
-                self.kwargs[s] = sig.parameters[s].default
-
-        self.stdout = sig.parameters['stdout'].default if 'stdout' in sig.parameters else None
-        self.stderr = sig.parameters['stderr'].default if 'stderr' in sig.parameters else None
-        self.inputs = sig.parameters['inputs'].default if 'inputs' in sig.parameters else []
-        self.outputs = sig.parameters['outputs'].default if 'outputs' in sig.parameters else []
+        if 'stdout' in params:
+            self.kwargs['stdout'] = params['stdout'].default
+        if 'stderr' in params:
+            self.kwargs['stderr'] = params['stderr'].default
+        self.outputs = params['outputs'].default if 'outputs' in params else []
+        self.inputs = params['inputs'].default if 'inputs' in params else []
 
     def __call__(self, *args, **kwargs):
         """The __call__ function must be implemented in the subclasses."""
diff --git a/parsl/app/bash_app.py b/parsl/app/bash_app.py
--- a/parsl/app/bash_app.py
+++ b/parsl/app/bash_app.py
@@ -47,11 +47,11 @@
         raise e
 
     # Updating stdout, stderr if values passed at call time.
-    stdout = kwargs.get('stdout', None)
-    stderr = kwargs.get('stderr', None)
-    timeout = kwargs.get('walltime', None)
-    logging.debug("Stdout  : %s", stdout)
-    logging.debug("Stderr  : %s", stderr)
+    stdout = kwargs.get('stdout')
+    stderr = kwargs.get('stderr')
+    timeout = kwargs.get('walltime')
+    logging.debug("Stdout: %s", stdout)
+    logging.debug("Stderr: %s", stderr)
 
     try:
         std_out = open(stdout, 'w') if stdout else None

{"golden_diff": "diff --git a/parsl/app/app.py b/parsl/app/app.py\n--- a/parsl/app/app.py\n+++ b/parsl/app/app.py\n@@ -1,16 +1,14 @@\n-\"\"\"Definitions for the @App decorator and the APP classes.\n-\n-The APP class encapsulates a generic leaf task that can be executed asynchronously.\n+\"\"\"Definitions for the @App decorator and the App classes.\n \n+The App class encapsulates a generic leaf task that can be executed asynchronously.\n \"\"\"\n import logging\n-from inspect import signature, Parameter\n+from inspect import signature\n \n-# Logging moved here in the PEP8 conformance fixes.\n logger = logging.getLogger(__name__)\n \n \n-class AppBase (object):\n+class AppBase(object):\n     \"\"\"This is the base class that defines the two external facing functions that an App must define.\n \n     The  __init__ () which is called when the interpreter sees the definition of the decorated\n@@ -43,16 +41,15 @@\n         self.sites = sites\n         self.cache = cache\n \n-        sig = signature(func)\n+        params = signature(func).parameters\n+\n         self.kwargs = {}\n-        for s in sig.parameters:\n-            if sig.parameters[s].default != Parameter.empty:\n-                self.kwargs[s] = sig.parameters[s].default\n-\n-        self.stdout = sig.parameters['stdout'].default if 'stdout' in sig.parameters else None\n-        self.stderr = sig.parameters['stderr'].default if 'stderr' in sig.parameters else None\n-        self.inputs = sig.parameters['inputs'].default if 'inputs' in sig.parameters else []\n-        self.outputs = sig.parameters['outputs'].default if 'outputs' in sig.parameters else []\n+        if 'stdout' in params:\n+            self.kwargs['stdout'] = params['stdout'].default\n+        if 'stderr' in params:\n+            self.kwargs['stderr'] = params['stderr'].default\n+        self.outputs = params['outputs'].default if 'outputs' in params else []\n+        self.inputs = params['inputs'].default if 'inputs' in params else []\n \n     def __call__(self, *args, **kwargs):\n         \"\"\"The __call__ function must be implemented in the subclasses.\"\"\"\ndiff --git a/parsl/app/bash_app.py b/parsl/app/bash_app.py\n--- a/parsl/app/bash_app.py\n+++ b/parsl/app/bash_app.py\n@@ -47,11 +47,11 @@\n         raise e\n \n     # Updating stdout, stderr if values passed at call time.\n-    stdout = kwargs.get('stdout', None)\n-    stderr = kwargs.get('stderr', None)\n-    timeout = kwargs.get('walltime', None)\n-    logging.debug(\"Stdout  : %s\", stdout)\n-    logging.debug(\"Stderr  : %s\", stderr)\n+    stdout = kwargs.get('stdout')\n+    stderr = kwargs.get('stderr')\n+    timeout = kwargs.get('walltime')\n+    logging.debug(\"Stdout: %s\", stdout)\n+    logging.debug(\"Stderr: %s\", stderr)\n \n     try:\n         std_out = open(stdout, 'w') if stdout else None\n", "issue": "Pandas DataFrames as Default Values\nParsl does not work with Pandas DataFrames as the default value to a keyword argument.\r\n\r\nFor example,\r\n\r\n```python\r\ndata = pd.DataFrame({'x': [None,2,[3]]})\r\n@App('python', dfk)\r\ndef f(d=data):\r\n    return d.sum()\r\nf().result()\r\n```\r\nyields an error\r\n\r\n```\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-23-cba3cd6e0846> in <module>()\r\n      3 def f(d=data):\r\n      4     return d.sum()\r\n----> 5 f().result()\r\n\r\n~/miniconda3/lib/python3.6/site-packages/parsl/app/app_factory.py in __call__(self, *args, **kwargs)\r\n     73                                  walltime=self.walltime,\r\n     74                                  cache=self.cache,\r\n---> 75                                  fn_hash=self.func_hash)\r\n     76         return app_obj(*args, **kwargs)\r\n     77 \r\n\r\n~/miniconda3/lib/python3.6/site-packages/parsl/app/python_app.py in __init__(self, func, executor, walltime, cache, sites, fn_hash)\r\n     16         This bit is the same for both bash & python apps.\r\n     17         \"\"\"\r\n---> 18         super().__init__(func, executor, walltime=walltime, sites=sites, exec_type=\"python\")\r\n     19         self.fn_hash = fn_hash\r\n     20         self.cache = cache\r\n\r\n~/miniconda3/lib/python3.6/site-packages/parsl/app/app.py in __init__(self, func, executor, walltime, sites, cache, exec_type)\r\n     47         self.kwargs = {}\r\n     48         for s in sig.parameters:\r\n---> 49             if sig.parameters[s].default != Parameter.empty:\r\n     50                 self.kwargs[s] = sig.parameters[s].default\r\n     51 \r\n\r\n~/miniconda3/lib/python3.6/site-packages/pandas/core/generic.py in __nonzero__(self)\r\n   1119         raise ValueError(\"The truth value of a {0} is ambiguous. \"\r\n   1120                          \"Use a.empty, a.bool(), a.item(), a.any() or a.all().\"\r\n-> 1121                          .format(self.__class__.__name__))\r\n   1122 \r\n   1123     __bool__ = __nonzero__\r\n\r\nValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().```\n", "before_files": [{"content": "import logging\n\nfrom parsl.app.futures import DataFuture\nfrom parsl.app.app import AppBase\n\nlogger = logging.getLogger(__name__)\n\n\ndef remote_side_bash_executor(func, *args, **kwargs):\n    \"\"\"Execute the bash app type function and return the command line string.\n\n    This string is reformatted with the *args, and **kwargs\n    from call time.\n    \"\"\"\n    import os\n    import time\n    import subprocess\n    import logging\n    import parsl.app.errors as pe\n\n    logging.basicConfig(filename='/tmp/bashexec.{0}.log'.format(time.time()), level=logging.DEBUG)\n\n    # start_t = time.time()\n\n    func_name = func.__name__\n\n    # Try to run the func to compose the commandline\n    try:\n        # Execute the func to get the commandline\n        partial_cmdline = func(*args, **kwargs)\n        # Reformat the commandline with current args and kwargs\n        executable = partial_cmdline.format(*args, **kwargs)\n\n    except AttributeError as e:\n        if partial_cmdline:\n            raise pe.AppBadFormatting(\"[{}] AppFormatting failed during cmd_line resolution {}\".format(func_name,\n                                                                                                       e), None)\n        else:\n            raise pe.BashAppNoReturn(\"[{}] Bash App returned NoneType, must return str object\".format(func_name), None)\n\n    except IndexError as e:\n        raise pe.AppBadFormatting(\"[{}] AppFormatting failed during cmd_line resolution {}\".format(func_name,\n                                                                                                   e), None)\n    except Exception as e:\n        logging.error(\"[{}] Caught exception during cmd_line resolution : {}\".format(func_name,\n                                                                                     e))\n        raise e\n\n    # Updating stdout, stderr if values passed at call time.\n    stdout = kwargs.get('stdout', None)\n    stderr = kwargs.get('stderr', None)\n    timeout = kwargs.get('walltime', None)\n    logging.debug(\"Stdout  : %s\", stdout)\n    logging.debug(\"Stderr  : %s\", stderr)\n\n    try:\n        std_out = open(stdout, 'w') if stdout else None\n    except Exception as e:\n        raise pe.BadStdStreamFile(stdout, e)\n\n    try:\n        std_err = open(stderr, 'w') if stderr else None\n    except Exception as e:\n        raise pe.BadStdStreamFile(stderr, e)\n\n    returncode = None\n    try:\n        proc = subprocess.Popen(executable, stdout=std_out, stderr=std_err, shell=True, executable='/bin/bash')\n        proc.wait(timeout=timeout)\n        returncode = proc.returncode\n\n    except subprocess.TimeoutExpired as e:\n        print(\"Timeout\")\n        raise pe.AppTimeout(\"[{}] App exceeded walltime: {}\".format(func_name, timeout), e)\n\n    except Exception as e:\n        print(\"Caught exception : \", e)\n        raise pe.AppException(\"[{}] App caught exception : {}\".format(func_name, proc.returncode), e)\n\n    if returncode != 0:\n        raise pe.AppFailure(\"[{}] App Failed exit code: {}\".format(func_name, proc.returncode), proc.returncode)\n\n    # TODO : Add support for globs here\n\n    missing = []\n    for outputfile in kwargs.get('outputs', []):\n        fpath = outputfile\n        if type(outputfile) != str:\n            fpath = outputfile.filepath\n\n        if not os.path.exists(fpath):\n            missing.extend([outputfile])\n\n    if missing:\n        raise pe.MissingOutputs(\"[{}] Missing outputs\".format(func_name), missing)\n\n    # exec_duration = time.time() - start_t\n    return returncode\n\n\nclass BashApp(AppBase):\n\n    def __init__(self, func, executor, walltime=60, cache=False,\n                 sites='all', fn_hash=None):\n        \"\"\"Initialize the super.\n\n        This bit is the same for both bash & python apps.\n        \"\"\"\n        super().__init__(func, executor, walltime=60, sites=sites, exec_type=\"bash\")\n        self.fn_hash = fn_hash\n        self.cache = cache\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"Handle the call to a Bash app.\n\n        Args:\n             - Arbitrary\n\n        Kwargs:\n             - Arbitrary\n\n        Returns:\n             If outputs=[...] was a kwarg then:\n                   App_fut, [Data_Futures...]\n             else:\n                   App_fut\n\n        \"\"\"\n        # Update kwargs in the app definition with one's passed in at calltime\n        self.kwargs.update(kwargs)\n\n        app_fut = self.executor.submit(remote_side_bash_executor, self.func, *args,\n                                       parsl_sites=self.sites,\n                                       fn_hash=self.fn_hash,\n                                       cache=self.cache,\n                                       **self.kwargs)\n\n        out_futs = [DataFuture(app_fut, o, parent=app_fut, tid=app_fut.tid)\n                    for o in kwargs.get('outputs', [])]\n        app_fut._outputs = out_futs\n\n        return app_fut\n", "path": "parsl/app/bash_app.py"}, {"content": "\"\"\"Definitions for the @App decorator and the APP classes.\n\nThe APP class encapsulates a generic leaf task that can be executed asynchronously.\n\n\"\"\"\nimport logging\nfrom inspect import signature, Parameter\n\n# Logging moved here in the PEP8 conformance fixes.\nlogger = logging.getLogger(__name__)\n\n\nclass AppBase (object):\n    \"\"\"This is the base class that defines the two external facing functions that an App must define.\n\n    The  __init__ () which is called when the interpreter sees the definition of the decorated\n    function, and the __call__ () which is invoked when a decorated function is called by the user.\n\n    \"\"\"\n\n    def __init__(self, func, executor, walltime=60, sites='all', cache=False, exec_type=\"bash\"):\n        \"\"\"Constructor for the APP object.\n\n        Args:\n             - func (function): Takes the function to be made into an App\n             - executor (executor): Executor for the execution resource\n\n        Kwargs:\n             - walltime (int) : Walltime in seconds for the app execution\n             - sites (str|list) : List of site names that this app could execute over. default is 'all'\n             - exec_type (string) : App type (bash|python)\n             - cache (Bool) : Enable caching of this app ?\n\n        Returns:\n             - APP object.\n\n        \"\"\"\n        self.__name__ = func.__name__\n        self.func = func\n        self.executor = executor\n        self.exec_type = exec_type\n        self.status = 'created'\n        self.sites = sites\n        self.cache = cache\n\n        sig = signature(func)\n        self.kwargs = {}\n        for s in sig.parameters:\n            if sig.parameters[s].default != Parameter.empty:\n                self.kwargs[s] = sig.parameters[s].default\n\n        self.stdout = sig.parameters['stdout'].default if 'stdout' in sig.parameters else None\n        self.stderr = sig.parameters['stderr'].default if 'stderr' in sig.parameters else None\n        self.inputs = sig.parameters['inputs'].default if 'inputs' in sig.parameters else []\n        self.outputs = sig.parameters['outputs'].default if 'outputs' in sig.parameters else []\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"The __call__ function must be implemented in the subclasses.\"\"\"\n        raise NotImplementedError\n\n\ndef app_wrapper(func):\n\n    def wrapper(*args, **kwargs):\n        logger.debug(\"App wrapper begins\")\n        x = func(*args, **kwargs)\n        logger.debug(\"App wrapper ends\")\n        return x\n\n    return wrapper\n\n\ndef App(apptype, executor, walltime=60, cache=False, sites='all'):\n    \"\"\"The App decorator function.\n\n    Args:\n        - apptype (string) : Apptype can be bash|python\n        - executor (Executor) : Executor object wrapping threads/process pools etc.\n\n    Kwargs:\n        - walltime (int) : Walltime for app in seconds,\n             default=60\n        - sites (str|List) : List of site names on which the app could execute\n             default='all'\n        - cache (Bool) : Enable caching of the app call\n             default=False\n\n    Returns:\n         An AppFactory object, which when called runs the apps through the executor.\n    \"\"\"\n    from parsl import APP_FACTORY_FACTORY\n\n    def Exec(f):\n        return APP_FACTORY_FACTORY.make(apptype, executor, f,\n                                        sites=sites,\n                                        cache=cache,\n                                        walltime=walltime)\n\n    return Exec\n", "path": "parsl/app/app.py"}], "after_files": [{"content": "import logging\n\nfrom parsl.app.futures import DataFuture\nfrom parsl.app.app import AppBase\n\nlogger = logging.getLogger(__name__)\n\n\ndef remote_side_bash_executor(func, *args, **kwargs):\n    \"\"\"Execute the bash app type function and return the command line string.\n\n    This string is reformatted with the *args, and **kwargs\n    from call time.\n    \"\"\"\n    import os\n    import time\n    import subprocess\n    import logging\n    import parsl.app.errors as pe\n\n    logging.basicConfig(filename='/tmp/bashexec.{0}.log'.format(time.time()), level=logging.DEBUG)\n\n    # start_t = time.time()\n\n    func_name = func.__name__\n\n    # Try to run the func to compose the commandline\n    try:\n        # Execute the func to get the commandline\n        partial_cmdline = func(*args, **kwargs)\n        # Reformat the commandline with current args and kwargs\n        executable = partial_cmdline.format(*args, **kwargs)\n\n    except AttributeError as e:\n        if partial_cmdline:\n            raise pe.AppBadFormatting(\"[{}] AppFormatting failed during cmd_line resolution {}\".format(func_name,\n                                                                                                       e), None)\n        else:\n            raise pe.BashAppNoReturn(\"[{}] Bash App returned NoneType, must return str object\".format(func_name), None)\n\n    except IndexError as e:\n        raise pe.AppBadFormatting(\"[{}] AppFormatting failed during cmd_line resolution {}\".format(func_name,\n                                                                                                   e), None)\n    except Exception as e:\n        logging.error(\"[{}] Caught exception during cmd_line resolution : {}\".format(func_name,\n                                                                                     e))\n        raise e\n\n    # Updating stdout, stderr if values passed at call time.\n    stdout = kwargs.get('stdout')\n    stderr = kwargs.get('stderr')\n    timeout = kwargs.get('walltime')\n    logging.debug(\"Stdout: %s\", stdout)\n    logging.debug(\"Stderr: %s\", stderr)\n\n    try:\n        std_out = open(stdout, 'w') if stdout else None\n    except Exception as e:\n        raise pe.BadStdStreamFile(stdout, e)\n\n    try:\n        std_err = open(stderr, 'w') if stderr else None\n    except Exception as e:\n        raise pe.BadStdStreamFile(stderr, e)\n\n    returncode = None\n    try:\n        proc = subprocess.Popen(executable, stdout=std_out, stderr=std_err, shell=True, executable='/bin/bash')\n        proc.wait(timeout=timeout)\n        returncode = proc.returncode\n\n    except subprocess.TimeoutExpired as e:\n        print(\"Timeout\")\n        raise pe.AppTimeout(\"[{}] App exceeded walltime: {}\".format(func_name, timeout), e)\n\n    except Exception as e:\n        print(\"Caught exception : \", e)\n        raise pe.AppException(\"[{}] App caught exception : {}\".format(func_name, proc.returncode), e)\n\n    if returncode != 0:\n        raise pe.AppFailure(\"[{}] App Failed exit code: {}\".format(func_name, proc.returncode), proc.returncode)\n\n    # TODO : Add support for globs here\n\n    missing = []\n    for outputfile in kwargs.get('outputs', []):\n        fpath = outputfile\n        if type(outputfile) != str:\n            fpath = outputfile.filepath\n\n        if not os.path.exists(fpath):\n            missing.extend([outputfile])\n\n    if missing:\n        raise pe.MissingOutputs(\"[{}] Missing outputs\".format(func_name), missing)\n\n    # exec_duration = time.time() - start_t\n    return returncode\n\n\nclass BashApp(AppBase):\n\n    def __init__(self, func, executor, walltime=60, cache=False,\n                 sites='all', fn_hash=None):\n        \"\"\"Initialize the super.\n\n        This bit is the same for both bash & python apps.\n        \"\"\"\n        super().__init__(func, executor, walltime=60, sites=sites, exec_type=\"bash\")\n        self.fn_hash = fn_hash\n        self.cache = cache\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"Handle the call to a Bash app.\n\n        Args:\n             - Arbitrary\n\n        Kwargs:\n             - Arbitrary\n\n        Returns:\n             If outputs=[...] was a kwarg then:\n                   App_fut, [Data_Futures...]\n             else:\n                   App_fut\n\n        \"\"\"\n        # Update kwargs in the app definition with one's passed in at calltime\n        self.kwargs.update(kwargs)\n\n        app_fut = self.executor.submit(remote_side_bash_executor, self.func, *args,\n                                       parsl_sites=self.sites,\n                                       fn_hash=self.fn_hash,\n                                       cache=self.cache,\n                                       **self.kwargs)\n\n        out_futs = [DataFuture(app_fut, o, parent=app_fut, tid=app_fut.tid)\n                    for o in kwargs.get('outputs', [])]\n        app_fut._outputs = out_futs\n\n        return app_fut\n", "path": "parsl/app/bash_app.py"}, {"content": "\"\"\"Definitions for the @App decorator and the App classes.\n\nThe App class encapsulates a generic leaf task that can be executed asynchronously.\n\"\"\"\nimport logging\nfrom inspect import signature\n\nlogger = logging.getLogger(__name__)\n\n\nclass AppBase(object):\n    \"\"\"This is the base class that defines the two external facing functions that an App must define.\n\n    The  __init__ () which is called when the interpreter sees the definition of the decorated\n    function, and the __call__ () which is invoked when a decorated function is called by the user.\n\n    \"\"\"\n\n    def __init__(self, func, executor, walltime=60, sites='all', cache=False, exec_type=\"bash\"):\n        \"\"\"Constructor for the APP object.\n\n        Args:\n             - func (function): Takes the function to be made into an App\n             - executor (executor): Executor for the execution resource\n\n        Kwargs:\n             - walltime (int) : Walltime in seconds for the app execution\n             - sites (str|list) : List of site names that this app could execute over. default is 'all'\n             - exec_type (string) : App type (bash|python)\n             - cache (Bool) : Enable caching of this app ?\n\n        Returns:\n             - APP object.\n\n        \"\"\"\n        self.__name__ = func.__name__\n        self.func = func\n        self.executor = executor\n        self.exec_type = exec_type\n        self.status = 'created'\n        self.sites = sites\n        self.cache = cache\n\n        params = signature(func).parameters\n\n        self.kwargs = {}\n        if 'stdout' in params:\n            self.kwargs['stdout'] = params['stdout'].default\n        if 'stderr' in params:\n            self.kwargs['stderr'] = params['stderr'].default\n        self.outputs = params['outputs'].default if 'outputs' in params else []\n        self.inputs = params['inputs'].default if 'inputs' in params else []\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"The __call__ function must be implemented in the subclasses.\"\"\"\n        raise NotImplementedError\n\n\ndef app_wrapper(func):\n\n    def wrapper(*args, **kwargs):\n        logger.debug(\"App wrapper begins\")\n        x = func(*args, **kwargs)\n        logger.debug(\"App wrapper ends\")\n        return x\n\n    return wrapper\n\n\ndef App(apptype, executor, walltime=60, cache=False, sites='all'):\n    \"\"\"The App decorator function.\n\n    Args:\n        - apptype (string) : Apptype can be bash|python\n        - executor (Executor) : Executor object wrapping threads/process pools etc.\n\n    Kwargs:\n        - walltime (int) : Walltime for app in seconds,\n             default=60\n        - sites (str|List) : List of site names on which the app could execute\n             default='all'\n        - cache (Bool) : Enable caching of the app call\n             default=False\n\n    Returns:\n         An AppFactory object, which when called runs the apps through the executor.\n    \"\"\"\n    from parsl import APP_FACTORY_FACTORY\n\n    def Exec(f):\n        return APP_FACTORY_FACTORY.make(apptype, executor, f,\n                                        sites=sites,\n                                        cache=cache,\n                                        walltime=walltime)\n\n    return Exec\n", "path": "parsl/app/app.py"}]}