We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Config builders cannot have type annotations in __init__
Trying to build [a config class](https://github.com/raster-foundry/raster-vision-plugin/blob/996044a503d09d311105d07da98b31284b6a6e91/src/rf_raster_vision_plugin/raster_source/config.py) with type annotations, you get:

```
In [7]: RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-2f92db6db3a6> in <module>()
----> 1 RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()

/opt/src/rastervision/core/config.py in build(self)
     99         """
    100         self.validate()
--> 101         arguments = set(inspect.getargspec(self.config_class).args)
    102         keys = set(self.config.keys())
    103         config = {k: self.config[k] for k in (arguments & keys)}

/usr/lib/python3.5/inspect.py in getargspec(func)
   1043         getfullargspec(func)
   1044     if kwonlyargs or ann:
-> 1045         raise ValueError("Function has keyword-only arguments or annotations"
   1046                          ", use getfullargspec() API which can support them")
   1047     return ArgSpec(args, varargs, varkw, defaults)

ValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them
```

Reproduction
-----

- `docker/run` from the linked repo
- `ipython`

```python
>>> from rf_raster_vision_plugin.raster_source.config import RfRasterSourceConfig, RfRasterSourceConfigBuilder
>>> RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()
```

Expected Behavior
-----

Config builder shouldn't choke on type annotations

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `rastervision/core/config.py`
Content:
```
1 from abc import (ABC, abstractmethod)
2 import os
3 import inspect
4 
5 from rastervision.utils.files import download_or_copy
6 
7 
8 class ConfigError(Exception):
9     pass
10 
11 
12 class Config(ABC):
13     @abstractmethod
14     def to_builder(self):
15         """Return a builder based on this config.
16         """
17         pass  # pragma: no cover
18 
19     @abstractmethod
20     def to_proto(self):
21         """Returns the protobuf configuration for this config.
22         """
23         pass  # pragma: no cover
24 
25     def update_for_command(self,
26                            command_type,
27                            experiment_config,
28                            context=None,
29                            io_def=None):
30         """Updates this configuration for the given command
31 
32         Note: While configuration is immutable for client facing operations,
33         this is an internal operation and mutates the configuration.
34 
35         Args:
36             command_type: The command type that is currently being
37                 preprocessed. experiment_config: The experiment configuration
38                 that this configuration is a part of.
39             context: Optional list of parent configurations, to allow for child
40                 configurations contained in collections to understand their
41                 context in the experiment configuration.
42 
43         Returns:
44           Nothing. Call should mutate the configuration object itself.
45         """
46         pass  # pragma: no cover
47 
48     @abstractmethod
49     def report_io(self, command_type, io_def):
50         """Updates the given CommandIODefinition.
51 
52         So that it includes the inputs, outputs, and missing files for this
53         configuration at this command.
54 
55         Args:
56             command_type: The command type that is currently being preprocessed.
57             io_def: The CommandIODefinition that this call should modify.
58 
59         Returns: Nothing. This call should make the appropriate calls to the
60             given io_def to mutate its state.
61         """
62         pass
63 
64     @staticmethod
65     @abstractmethod
66     def builder():
67         """Returns a new builder that takes this configuration
68            as its starting point.
69         """
70         pass  # pragma: no cover
71 
72     @staticmethod
73     @abstractmethod
74     def from_proto(msg):
75         """Creates a Config from the specificed protobuf message
76         TODO: Allow loading from file uri or dict
77         """
78         pass  # pragma: no cover
79 
80 
81 class ConfigBuilder(ABC):
82     def __init__(self, config_class, config=None):
83         """Construct a builder.
84 
85            Args:
86              config_class: The Config class that this builder builds.
87              config: A dictionary of **kwargs that will eventually be passed
88                      into the __init__ method of config_class to build the configuration.
89                      This config is modified with the fluent builder methods.
90         """
91         if config is None:  # pragma: no cover
92             config = {}
93 
94         self.config_class = config_class
95         self.config = config
96 
97     def build(self):
98         """Returns the configuration that is built by this builder.
99         """
100         self.validate()
101         arguments = set(inspect.getargspec(self.config_class).args)
102         keys = set(self.config.keys())
103         config = {k: self.config[k] for k in (arguments & keys)}
104         return self.config_class(**config)
105 
106     def validate(self):
107         """Validate this config, if there is validation on the builder that
108            is not captured by the required arguments of the config.
109         """
110         pass  # pragma: no cover
111 
112     @abstractmethod
113     def from_proto(self, msg):
114         """Return a builder that takes the configuration from the proto message
115            as its starting point.
116         """
117         pass  # pragma: no cover
118 
119 
120 class BundledConfigMixin(ABC):
121     """Mixin for configurations that participate in the bundling of a
122     prediction package"""
123 
124     @abstractmethod
125     def save_bundle_files(self, bundle_dir):
126         """Place files into a bundle directory for bundling into
127         a prediction package.
128 
129         Returns: A tuple of (config, uris) of the modified configuration
130                  with the basenames of URIs in place of the original URIs,
131                  and a list of URIs that are to be bundled.
132         """
133         pass  # pragma: no cover
134 
135     def bundle_file(self, uri, bundle_dir):
136         local_path = download_or_copy(uri, bundle_dir)
137         base_name = os.path.basename(local_path)
138         return (local_path, base_name)
139 
140     @abstractmethod
141     def load_bundle_files(self, bundle_dir):
142         """Load files from a prediction package bundle directory."""
143         pass  # pragma: no cover
144
```
--- 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/rastervision/core/config.py b/rastervision/core/config.py
--- a/rastervision/core/config.py
+++ b/rastervision/core/config.py
@@ -98,7 +98,7 @@
         """Returns the configuration that is built by this builder.
         """
         self.validate()
-        arguments = set(inspect.getargspec(self.config_class).args)
+        arguments = set(inspect.getfullargspec(self.config_class).args)
         keys = set(self.config.keys())
         config = {k: self.config[k] for k in (arguments & keys)}
         return self.config_class(**config)

{"golden_diff": "diff --git a/rastervision/core/config.py b/rastervision/core/config.py\n--- a/rastervision/core/config.py\n+++ b/rastervision/core/config.py\n@@ -98,7 +98,7 @@\n         \"\"\"Returns the configuration that is built by this builder.\n         \"\"\"\n         self.validate()\n-        arguments = set(inspect.getargspec(self.config_class).args)\n+        arguments = set(inspect.getfullargspec(self.config_class).args)\n         keys = set(self.config.keys())\n         config = {k: self.config[k] for k in (arguments & keys)}\n         return self.config_class(**config)\n", "issue": "Config builders cannot have type annotations in __init__\nTrying to build [a config class](https://github.com/raster-foundry/raster-vision-plugin/blob/996044a503d09d311105d07da98b31284b6a6e91/src/rf_raster_vision_plugin/raster_source/config.py) with type annotations, you get:\r\n\r\n```\r\nIn [7]: RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-7-2f92db6db3a6> in <module>()\r\n----> 1 RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()\r\n\r\n/opt/src/rastervision/core/config.py in build(self)\r\n     99         \"\"\"\r\n    100         self.validate()\r\n--> 101         arguments = set(inspect.getargspec(self.config_class).args)\r\n    102         keys = set(self.config.keys())\r\n    103         config = {k: self.config[k] for k in (arguments & keys)}\r\n\r\n/usr/lib/python3.5/inspect.py in getargspec(func)\r\n   1043         getfullargspec(func)\r\n   1044     if kwonlyargs or ann:\r\n-> 1045         raise ValueError(\"Function has keyword-only arguments or annotations\"\r\n   1046                          \", use getfullargspec() API which can support them\")\r\n   1047     return ArgSpec(args, varargs, varkw, defaults)\r\n\r\nValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them\r\n```\r\n\r\nReproduction\r\n-----\r\n\r\n- `docker/run` from the linked repo\r\n- `ipython`\r\n\r\n```python\r\n>>> from rf_raster_vision_plugin.raster_source.config import RfRasterSourceConfig, RfRasterSourceConfigBuilder\r\n>>> RfRasterSourceConfigBuilder(RfRasterSourceConfig).build()\r\n```\r\n\r\nExpected Behavior\r\n-----\r\n\r\nConfig builder shouldn't choke on type annotations\n", "before_files": [{"content": "from abc import (ABC, abstractmethod)\nimport os\nimport inspect\n\nfrom rastervision.utils.files import download_or_copy\n\n\nclass ConfigError(Exception):\n    pass\n\n\nclass Config(ABC):\n    @abstractmethod\n    def to_builder(self):\n        \"\"\"Return a builder based on this config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def to_proto(self):\n        \"\"\"Returns the protobuf configuration for this config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    def update_for_command(self,\n                           command_type,\n                           experiment_config,\n                           context=None,\n                           io_def=None):\n        \"\"\"Updates this configuration for the given command\n\n        Note: While configuration is immutable for client facing operations,\n        this is an internal operation and mutates the configuration.\n\n        Args:\n            command_type: The command type that is currently being\n                preprocessed. experiment_config: The experiment configuration\n                that this configuration is a part of.\n            context: Optional list of parent configurations, to allow for child\n                configurations contained in collections to understand their\n                context in the experiment configuration.\n\n        Returns:\n          Nothing. Call should mutate the configuration object itself.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def report_io(self, command_type, io_def):\n        \"\"\"Updates the given CommandIODefinition.\n\n        So that it includes the inputs, outputs, and missing files for this\n        configuration at this command.\n\n        Args:\n            command_type: The command type that is currently being preprocessed.\n            io_def: The CommandIODefinition that this call should modify.\n\n        Returns: Nothing. This call should make the appropriate calls to the\n            given io_def to mutate its state.\n        \"\"\"\n        pass\n\n    @staticmethod\n    @abstractmethod\n    def builder():\n        \"\"\"Returns a new builder that takes this configuration\n           as its starting point.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @staticmethod\n    @abstractmethod\n    def from_proto(msg):\n        \"\"\"Creates a Config from the specificed protobuf message\n        TODO: Allow loading from file uri or dict\n        \"\"\"\n        pass  # pragma: no cover\n\n\nclass ConfigBuilder(ABC):\n    def __init__(self, config_class, config=None):\n        \"\"\"Construct a builder.\n\n           Args:\n             config_class: The Config class that this builder builds.\n             config: A dictionary of **kwargs that will eventually be passed\n                     into the __init__ method of config_class to build the configuration.\n                     This config is modified with the fluent builder methods.\n        \"\"\"\n        if config is None:  # pragma: no cover\n            config = {}\n\n        self.config_class = config_class\n        self.config = config\n\n    def build(self):\n        \"\"\"Returns the configuration that is built by this builder.\n        \"\"\"\n        self.validate()\n        arguments = set(inspect.getargspec(self.config_class).args)\n        keys = set(self.config.keys())\n        config = {k: self.config[k] for k in (arguments & keys)}\n        return self.config_class(**config)\n\n    def validate(self):\n        \"\"\"Validate this config, if there is validation on the builder that\n           is not captured by the required arguments of the config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def from_proto(self, msg):\n        \"\"\"Return a builder that takes the configuration from the proto message\n           as its starting point.\n        \"\"\"\n        pass  # pragma: no cover\n\n\nclass BundledConfigMixin(ABC):\n    \"\"\"Mixin for configurations that participate in the bundling of a\n    prediction package\"\"\"\n\n    @abstractmethod\n    def save_bundle_files(self, bundle_dir):\n        \"\"\"Place files into a bundle directory for bundling into\n        a prediction package.\n\n        Returns: A tuple of (config, uris) of the modified configuration\n                 with the basenames of URIs in place of the original URIs,\n                 and a list of URIs that are to be bundled.\n        \"\"\"\n        pass  # pragma: no cover\n\n    def bundle_file(self, uri, bundle_dir):\n        local_path = download_or_copy(uri, bundle_dir)\n        base_name = os.path.basename(local_path)\n        return (local_path, base_name)\n\n    @abstractmethod\n    def load_bundle_files(self, bundle_dir):\n        \"\"\"Load files from a prediction package bundle directory.\"\"\"\n        pass  # pragma: no cover\n", "path": "rastervision/core/config.py"}], "after_files": [{"content": "from abc import (ABC, abstractmethod)\nimport os\nimport inspect\n\nfrom rastervision.utils.files import download_or_copy\n\n\nclass ConfigError(Exception):\n    pass\n\n\nclass Config(ABC):\n    @abstractmethod\n    def to_builder(self):\n        \"\"\"Return a builder based on this config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def to_proto(self):\n        \"\"\"Returns the protobuf configuration for this config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    def update_for_command(self,\n                           command_type,\n                           experiment_config,\n                           context=None,\n                           io_def=None):\n        \"\"\"Updates this configuration for the given command\n\n        Note: While configuration is immutable for client facing operations,\n        this is an internal operation and mutates the configuration.\n\n        Args:\n            command_type: The command type that is currently being\n                preprocessed. experiment_config: The experiment configuration\n                that this configuration is a part of.\n            context: Optional list of parent configurations, to allow for child\n                configurations contained in collections to understand their\n                context in the experiment configuration.\n\n        Returns:\n          Nothing. Call should mutate the configuration object itself.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def report_io(self, command_type, io_def):\n        \"\"\"Updates the given CommandIODefinition.\n\n        So that it includes the inputs, outputs, and missing files for this\n        configuration at this command.\n\n        Args:\n            command_type: The command type that is currently being preprocessed.\n            io_def: The CommandIODefinition that this call should modify.\n\n        Returns: Nothing. This call should make the appropriate calls to the\n            given io_def to mutate its state.\n        \"\"\"\n        pass\n\n    @staticmethod\n    @abstractmethod\n    def builder():\n        \"\"\"Returns a new builder that takes this configuration\n           as its starting point.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @staticmethod\n    @abstractmethod\n    def from_proto(msg):\n        \"\"\"Creates a Config from the specificed protobuf message\n        TODO: Allow loading from file uri or dict\n        \"\"\"\n        pass  # pragma: no cover\n\n\nclass ConfigBuilder(ABC):\n    def __init__(self, config_class, config=None):\n        \"\"\"Construct a builder.\n\n           Args:\n             config_class: The Config class that this builder builds.\n             config: A dictionary of **kwargs that will eventually be passed\n                     into the __init__ method of config_class to build the configuration.\n                     This config is modified with the fluent builder methods.\n        \"\"\"\n        if config is None:  # pragma: no cover\n            config = {}\n\n        self.config_class = config_class\n        self.config = config\n\n    def build(self):\n        \"\"\"Returns the configuration that is built by this builder.\n        \"\"\"\n        self.validate()\n        arguments = set(inspect.getfullargspec(self.config_class).args)\n        keys = set(self.config.keys())\n        config = {k: self.config[k] for k in (arguments & keys)}\n        return self.config_class(**config)\n\n    def validate(self):\n        \"\"\"Validate this config, if there is validation on the builder that\n           is not captured by the required arguments of the config.\n        \"\"\"\n        pass  # pragma: no cover\n\n    @abstractmethod\n    def from_proto(self, msg):\n        \"\"\"Return a builder that takes the configuration from the proto message\n           as its starting point.\n        \"\"\"\n        pass  # pragma: no cover\n\n\nclass BundledConfigMixin(ABC):\n    \"\"\"Mixin for configurations that participate in the bundling of a\n    prediction package\"\"\"\n\n    @abstractmethod\n    def save_bundle_files(self, bundle_dir):\n        \"\"\"Place files into a bundle directory for bundling into\n        a prediction package.\n\n        Returns: A tuple of (config, uris) of the modified configuration\n                 with the basenames of URIs in place of the original URIs,\n                 and a list of URIs that are to be bundled.\n        \"\"\"\n        pass  # pragma: no cover\n\n    def bundle_file(self, uri, bundle_dir):\n        local_path = download_or_copy(uri, bundle_dir)\n        base_name = os.path.basename(local_path)\n        return (local_path, base_name)\n\n    @abstractmethod\n    def load_bundle_files(self, bundle_dir):\n        \"\"\"Load files from a prediction package bundle directory.\"\"\"\n        pass  # pragma: no cover\n", "path": "rastervision/core/config.py"}]}