Repository: ray-project/ray

Issue:
[tune] Ray Tune fails to parse typing hints of the function for experiment
### What is the problem?
If the function for experiment has a [typing hint](https://docs.python.org/3/library/typing.html) for its argument `config`, then Ray Tune fails to parse the argument and assumes that there is a reporter signature. The cause of this problem is in this source code:
https://github.com/ray-project/ray/blob/1eaa57c98f8870a43e1ea14ec011b6bd4be97c8d/python/ray/tune/function_runner.py#L250-L257
Changing 
`func_args = inspect.getargspec(train_func).args` 
to
`func_args = inspect.getfullargspec(train_func).args` 
might solve the problem.

*Ray version and other system information (Python version, TensorFlow version, OS):*
Ray: 0.8.0
Python: 3.7.5
OS: Ubuntu 18.04

*Does the problem occur on the [latest wheels](https://ray.readthedocs.io/en/latest/installation.html)?*
I couldn't install the latest wheel. So I can't confirm it.

### Reproduction
The following is a modification of the first examples in the [Ray Tune Documentation](https://ray.readthedocs.io/en/latest/tune.html#quick-start), where I added a typing hint  `config: Dict[str, Any]` for the argument of function `train_mnist`.

```
from typing import Dict, Any

import torch.optim as optim
from ray import tune
from ray.tune.examples.mnist_pytorch import get_data_loaders, ConvNet, train, test


def train_mnist(config: Dict[str, Any]):
    train_loader, test_loader = get_data_loaders()
    model = ConvNet()
    optimizer = optim.SGD(model.parameters(), lr=config["lr"])
    for i in range(10):
        train(model, optimizer, train_loader)
        acc = test(model, test_loader)
        tune.track.log(mean_accuracy=acc)


analysis = tune.run(train_mnist, config={"lr": tune.grid_search([0.001, 0.01, 0.1])})

print("Best config: ", analysis.get_best_config(metric="mean_accuracy"))

# Get a dataframe for analyzing trial results.
df = analysis.dataframe()
```
When running the code you get this error message:
**TypeError: train_mnist() takes 1 positional argument but 2 were given**



Discussion:

Resolving patch:
diff --git a/python/ray/tune/function_runner.py b/python/ray/tune/function_runner.py
--- a/python/ray/tune/function_runner.py
+++ b/python/ray/tune/function_runner.py
@@ -7,6 +7,7 @@
 import inspect
 import threading
 import traceback
+import sys
 from six.moves import queue
 
 from ray.tune import track
@@ -248,7 +249,10 @@ def wrap_function(train_func):
 
     use_track = False
     try:
-        func_args = inspect.getargspec(train_func).args
+        if sys.version_info >= (3, 3):
+            func_args = inspect.getfullargspec(train_func).args
+        else:
+            func_args = inspect.getargspec(train_func).args
         use_track = ("reporter" not in func_args and len(func_args) == 1)
         if use_track:
             logger.info("tune.track signature detected.")


Test patch:
diff --git a/docker/tune_test/Dockerfile b/docker/tune_test/Dockerfile
--- a/docker/tune_test/Dockerfile
+++ b/docker/tune_test/Dockerfile
@@ -6,7 +6,7 @@ FROM ray-project/base-deps
 # a test runner.
 RUN conda install -y numpy
 RUN pip install -U pip
-RUN pip install -U https://ray-wheels.s3-us-west-2.amazonaws.com/latest/ray-0.9.0.dev-cp36-cp36m-manylinux1_x86_64.whl
+RUN pip install -U https://ray-wheels.s3-us-west-2.amazonaws.com/latest/ray-0.9.0.dev0-cp36-cp36m-manylinux1_x86_64.whl
 RUN pip install -U boto3
 # We install this after the latest wheels -- this should not override the latest wheels.
 # Needed to run Tune example with a 'plot' call - which does not actually render a plot, but throws an error.