prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  base_component.BaseComponent.__str__ method raising KeyError
  I got a `KeyError` when calling this method: `base_component.BaseComponent.__str__`
  
  Here is the code to reproduce:
  
  ```python
  import os
  from tfx.utils.dsl_utils import csv_input
  from tfx.components.example_gen.csv_example_gen.component import CsvExampleGen
  
  _taxi_root = os.path.join(os.environ['HOME'], 'taxi')
  _data_root = os.path.join(_taxi_root, 'data/simple')
  examples = csv_input(_data_root)
  example_gen = CsvExampleGen(input_base=examples)
  print(example_gen)
  ```
  
  The error trace is:
  
  ```
  /Users/alelevier/Documents/github/tfx/tfx/components/base/base_component.pyc in __str__(self)
       89         input_dict=self.input_dict,
       90         outputs=self.outputs,
  ---> 91         exec_properties=self.exec_properties)
       92 
       93   def __repr__(self):
  
  KeyError: '\n  component_name'
  ```
  
  I looked at the method, it needs use double `{{` and `}}` so change from:
  
  ```
    def __str__(self):
      return """
  {
    component_name: {component_name},
    unique_name: {unique_name},
    driver: {driver},
    executor: {executor},
    input_dict: {input_dict},
    outputs: {outputs},
    exec_properties: {exec_properties}
  }
      """.format(  # pylint: disable=missing-format-argument-key
          component_name=self.component_name,
          unique_name=self.unique_name,
          driver=self.driver,
          executor=self.executor,
          input_dict=self.input_dict,
          outputs=self.outputs,
          exec_properties=self.exec_properties)
  ```
  
  To:
  
  ```
    def __str__(self):
      return """
  {{
    component_name: {component_name},
    unique_name: {unique_name},
    driver: {driver},
    executor: {executor},
    input_dict: {input_dict},
    outputs: {outputs},
    exec_properties: {exec_properties}
  }}
      """.format(  # pylint: disable=missing-format-argument-key
          component_name=self.component_name,
          unique_name=self.unique_name,
          driver=self.driver,
          executor=self.executor,
          input_dict=self.input_dict,
          outputs=self.outputs,
          exec_properties=self.exec_properties)
  ```
  
  </issue>
  <code>
  [start of tfx/components/base/base_component.py]
  1 # Copyright 2019 Google LLC. All Rights Reserved.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 """Base class for all TFX components."""
  15 
  16 from __future__ import absolute_import
  17 from __future__ import division
  18 from __future__ import print_function
  19 
  20 import abc
  21 from six import with_metaclass
  22 from typing import Any
  23 from typing import Dict
  24 from typing import Optional
  25 from typing import Text
  26 
  27 from tfx.utils import channel
  28 
  29 
  30 class ComponentOutputs(object):
  31   """Helper class to wrap outputs from TFX components."""
  32 
  33   def __init__(self, d):
  34     self.__dict__ = d
  35 
  36   def get_all(self):
  37     return self.__dict__
  38 
  39 
  40 class BaseComponent(with_metaclass(abc.ABCMeta, object)):
  41   """Base TFX component.
  42 
  43   This is the parent class of any TFX component.
  44 
  45   Attributes:
  46     component_name: Name of the component, should be unique per component class.
  47     unique_name: Unique name for every component class instance.
  48     driver: Driver class to handle pre-execution behaviors in a component.
  49     executor: Executor class to do the real execution work.
  50     input_dict: A [Text -> Channel] dict serving as the inputs to the component.
  51     exec_properties: A [Text -> Any] dict serving as additional properties
  52       needed for execution.
  53     outputs: Optional Channel destinations of the component.
  54   """
  55 
  56   def __init__(self,
  57                component_name,
  58                driver,
  59                executor,
  60                input_dict,
  61                exec_properties,
  62                unique_name = '',
  63                outputs = ComponentOutputs({})):
  64     self.component_name = component_name
  65     self.driver = driver
  66     self.executor = executor
  67     self.input_dict = input_dict
  68     self.exec_properties = exec_properties
  69     self.unique_name = unique_name
  70     self.outputs = outputs or self._create_outputs()
  71     self._type_check(self.input_dict, self.exec_properties)
  72 
  73   def __str__(self):
  74     return """
  75 {
  76   component_name: {component_name},
  77   unique_name: {unique_name},
  78   driver: {driver},
  79   executor: {executor},
  80   input_dict: {input_dict},
  81   outputs: {outputs},
  82   exec_properties: {exec_properties}
  83 }
  84     """.format(  # pylint: disable=missing-format-argument-key
  85         component_name=self.component_name,
  86         unique_name=self.unique_name,
  87         driver=self.driver,
  88         executor=self.executor,
  89         input_dict=self.input_dict,
  90         outputs=self.outputs,
  91         exec_properties=self.exec_properties)
  92 
  93   def __repr__(self):
  94     return self.__str__()
  95 
  96   @abc.abstractmethod
  97   def _create_outputs(self):
  98     """Creates outputs placeholder for components.
  99 
  100     Returns:
  101       ComponentOutputs object containing the dict of [Text -> Channel]
  102     """
  103     raise NotImplementedError
  104 
  105   @abc.abstractmethod
  106   def _type_check(self, input_dict,
  107                   exec_properties):
  108     """Does type checking for the inputs and exec_properties.
  109 
  110     Args:
  111       input_dict: A Dict[Text, Channel] as the inputs of the Component.
  112       exec_properties: A Dict[Text, Any] as the execution properties of the
  113         component.
  114     """
  115     raise NotImplementedError
  116
  [end of tfx/components/base/base_component.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/tfx/components/base/base_component.py b/tfx/components/base/base_component.py
  --- a/tfx/components/base/base_component.py
  +++ b/tfx/components/base/base_component.py
  @@ -72,7 +72,7 @@
   
     def __str__(self):
       return """
  -{
  +{{
     component_name: {component_name},
     unique_name: {unique_name},
     driver: {driver},
  @@ -80,7 +80,7 @@
     input_dict: {input_dict},
     outputs: {outputs},
     exec_properties: {exec_properties}
  -}
  +}}
       """.format(  # pylint: disable=missing-format-argument-key
           component_name=self.component_name,
           unique_name=self.unique_name,
  
verification_info: {"golden_diff": "diff --git a/tfx/components/base/base_component.py b/tfx/components/base/base_component.py\n--- a/tfx/components/base/base_component.py\n+++ b/tfx/components/base/base_component.py\n@@ -72,7 +72,7 @@\n \n   def __str__(self):\n     return \"\"\"\n-{\n+{{\n   component_name: {component_name},\n   unique_name: {unique_name},\n   driver: {driver},\n@@ -80,7 +80,7 @@\n   input_dict: {input_dict},\n   outputs: {outputs},\n   exec_properties: {exec_properties}\n-}\n+}}\n     \"\"\".format(  # pylint: disable=missing-format-argument-key\n         component_name=self.component_name,\n         unique_name=self.unique_name,\n", "issue": "base_component.BaseComponent.__str__ method raising KeyError\nI got a `KeyError` when calling this method: `base_component.BaseComponent.__str__`\r\n\r\nHere is the code to reproduce:\r\n\r\n```python\r\nimport os\r\nfrom tfx.utils.dsl_utils import csv_input\r\nfrom tfx.components.example_gen.csv_example_gen.component import CsvExampleGen\r\n\r\n_taxi_root = os.path.join(os.environ['HOME'], 'taxi')\r\n_data_root = os.path.join(_taxi_root, 'data/simple')\r\nexamples = csv_input(_data_root)\r\nexample_gen = CsvExampleGen(input_base=examples)\r\nprint(example_gen)\r\n```\r\n\r\nThe error trace is:\r\n\r\n```\r\n/Users/alelevier/Documents/github/tfx/tfx/components/base/base_component.pyc in __str__(self)\r\n     89         input_dict=self.input_dict,\r\n     90         outputs=self.outputs,\r\n---> 91         exec_properties=self.exec_properties)\r\n     92 \r\n     93   def __repr__(self):\r\n\r\nKeyError: '\\n  component_name'\r\n```\r\n\r\nI looked at the method, it needs use double `{{` and `}}` so change from:\r\n\r\n```\r\n  def __str__(self):\r\n    return \"\"\"\r\n{\r\n  component_name: {component_name},\r\n  unique_name: {unique_name},\r\n  driver: {driver},\r\n  executor: {executor},\r\n  input_dict: {input_dict},\r\n  outputs: {outputs},\r\n  exec_properties: {exec_properties}\r\n}\r\n    \"\"\".format(  # pylint: disable=missing-format-argument-key\r\n        component_name=self.component_name,\r\n        unique_name=self.unique_name,\r\n        driver=self.driver,\r\n        executor=self.executor,\r\n        input_dict=self.input_dict,\r\n        outputs=self.outputs,\r\n        exec_properties=self.exec_properties)\r\n```\r\n\r\nTo:\r\n\r\n```\r\n  def __str__(self):\r\n    return \"\"\"\r\n{{\r\n  component_name: {component_name},\r\n  unique_name: {unique_name},\r\n  driver: {driver},\r\n  executor: {executor},\r\n  input_dict: {input_dict},\r\n  outputs: {outputs},\r\n  exec_properties: {exec_properties}\r\n}}\r\n    \"\"\".format(  # pylint: disable=missing-format-argument-key\r\n        component_name=self.component_name,\r\n        unique_name=self.unique_name,\r\n        driver=self.driver,\r\n        executor=self.executor,\r\n        input_dict=self.input_dict,\r\n        outputs=self.outputs,\r\n        exec_properties=self.exec_properties)\r\n```\n", "before_files": [{"content": "# Copyright 2019 Google LLC. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Base class for all TFX components.\"\"\"\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport abc\nfrom six import with_metaclass\nfrom typing import Any\nfrom typing import Dict\nfrom typing import Optional\nfrom typing import Text\n\nfrom tfx.utils import channel\n\n\nclass ComponentOutputs(object):\n  \"\"\"Helper class to wrap outputs from TFX components.\"\"\"\n\n  def __init__(self, d):\n    self.__dict__ = d\n\n  def get_all(self):\n    return self.__dict__\n\n\nclass BaseComponent(with_metaclass(abc.ABCMeta, object)):\n  \"\"\"Base TFX component.\n\n  This is the parent class of any TFX component.\n\n  Attributes:\n    component_name: Name of the component, should be unique per component class.\n    unique_name: Unique name for every component class instance.\n    driver: Driver class to handle pre-execution behaviors in a component.\n    executor: Executor class to do the real execution work.\n    input_dict: A [Text -> Channel] dict serving as the inputs to the component.\n    exec_properties: A [Text -> Any] dict serving as additional properties\n      needed for execution.\n    outputs: Optional Channel destinations of the component.\n  \"\"\"\n\n  def __init__(self,\n               component_name,\n               driver,\n               executor,\n               input_dict,\n               exec_properties,\n               unique_name = '',\n               outputs = ComponentOutputs({})):\n    self.component_name = component_name\n    self.driver = driver\n    self.executor = executor\n    self.input_dict = input_dict\n    self.exec_properties = exec_properties\n    self.unique_name = unique_name\n    self.outputs = outputs or self._create_outputs()\n    self._type_check(self.input_dict, self.exec_properties)\n\n  def __str__(self):\n    return \"\"\"\n{\n  component_name: {component_name},\n  unique_name: {unique_name},\n  driver: {driver},\n  executor: {executor},\n  input_dict: {input_dict},\n  outputs: {outputs},\n  exec_properties: {exec_properties}\n}\n    \"\"\".format(  # pylint: disable=missing-format-argument-key\n        component_name=self.component_name,\n        unique_name=self.unique_name,\n        driver=self.driver,\n        executor=self.executor,\n        input_dict=self.input_dict,\n        outputs=self.outputs,\n        exec_properties=self.exec_properties)\n\n  def __repr__(self):\n    return self.__str__()\n\n  @abc.abstractmethod\n  def _create_outputs(self):\n    \"\"\"Creates outputs placeholder for components.\n\n    Returns:\n      ComponentOutputs object containing the dict of [Text -> Channel]\n    \"\"\"\n    raise NotImplementedError\n\n  @abc.abstractmethod\n  def _type_check(self, input_dict,\n                  exec_properties):\n    \"\"\"Does type checking for the inputs and exec_properties.\n\n    Args:\n      input_dict: A Dict[Text, Channel] as the inputs of the Component.\n      exec_properties: A Dict[Text, Any] as the execution properties of the\n        component.\n    \"\"\"\n    raise NotImplementedError\n", "path": "tfx/components/base/base_component.py"}]}