prompt: 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()
  
  ```
  
golden_diff: 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)
  
verification_info: {"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"}]}