prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Invalid path check in euca-bundle-image
  The -i option uses convert_file in boto/roboto/param.py to verify that the path passed is, indeed, a file. This fails unless the path specified is a boring old file which is not necessary. Indeed it not being necessary is sort of the whole point in unix having a /dev in the first place. Everything is a file.
  
  The code calls os.path.isfile(value) in convert_file(). It should call os.path.exists(value) and not os.path.isdir(value). Directories are the only types of files which need to be considered special in the normal course of events.
  
  
  </issue>
  <code>
  [start of boto/roboto/param.py]
  1 # Copyright (c) 2010 Mitch Garnaat http://garnaat.org/
  2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
  3 #
  4 # Permission is hereby granted, free of charge, to any person obtaining a
  5 # copy of this software and associated documentation files (the
  6 # "Software"), to deal in the Software without restriction, including
  7 # without limitation the rights to use, copy, modify, merge, publish, dis-
  8 # tribute, sublicense, and/or sell copies of the Software, and to permit
  9 # persons to whom the Software is furnished to do so, subject to the fol-
  10 # lowing conditions:
  11 #
  12 # The above copyright notice and this permission notice shall be included
  13 # in all copies or substantial portions of the Software.
  14 #
  15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21 # IN THE SOFTWARE.
  22 
  23 import os
  24 
  25 class Converter(object):
  26 
  27     @classmethod
  28     def convert_string(cls, param, value):
  29         # TODO: could do length validation, etc. here
  30         if not isinstance(value, basestring):
  31             raise ValueError
  32         return value
  33 
  34     @classmethod
  35     def convert_integer(cls, param, value):
  36         # TODO: could do range checking here
  37         return int(value)
  38 
  39     @classmethod
  40     def convert_boolean(cls, param, value):
  41         """
  42         For command line arguments, just the presence
  43         of the option means True so just return True
  44         """
  45         return True
  46 
  47     @classmethod
  48     def convert_file(cls, param, value):
  49         if os.path.isfile(value):
  50             return value
  51         raise ValueError
  52 
  53     @classmethod
  54     def convert_dir(cls, param, value):
  55         if os.path.isdir(value):
  56             return value
  57         raise ValueError
  58 
  59     @classmethod
  60     def convert(cls, param, value):
  61         try:
  62             if hasattr(cls, 'convert_'+param.ptype):
  63                 mthd = getattr(cls, 'convert_'+param.ptype)
  64             else:
  65                 mthd = cls.convert_string
  66             return mthd(param, value)
  67         except:
  68             raise ValidationException(param, '')
  69 
  70 class Param(Converter):
  71 
  72     def __init__(self, name=None, ptype='string', optional=True,
  73                  short_name=None, long_name=None, doc='',
  74                  metavar=None, cardinality=1, default=None,
  75                  choices=None, encoder=None, request_param=True):
  76         self.name = name
  77         self.ptype = ptype
  78         self.optional = optional
  79         self.short_name = short_name
  80         self.long_name = long_name
  81         self.doc = doc
  82         self.metavar = metavar
  83         self.cardinality = cardinality
  84         self.default = default
  85         self.choices = choices
  86         self.encoder = encoder
  87         self.request_param = request_param
  88 
  89     @property
  90     def optparse_long_name(self):
  91         ln = None
  92         if self.long_name:
  93             ln = '--%s' % self.long_name
  94         return ln
  95 
  96     @property
  97     def synopsis_long_name(self):
  98         ln = None
  99         if self.long_name:
  100             ln = '--%s' % self.long_name
  101         return ln
  102 
  103     @property
  104     def getopt_long_name(self):
  105         ln = None
  106         if self.long_name:
  107             ln = '%s' % self.long_name
  108             if self.ptype != 'boolean':
  109                 ln += '='
  110         return ln
  111 
  112     @property
  113     def optparse_short_name(self):
  114         sn = None
  115         if self.short_name:
  116             sn = '-%s' % self.short_name
  117         return sn
  118 
  119     @property
  120     def synopsis_short_name(self):
  121         sn = None
  122         if self.short_name:
  123             sn = '-%s' % self.short_name
  124         return sn
  125 
  126     @property
  127     def getopt_short_name(self):
  128         sn = None
  129         if self.short_name:
  130             sn = '%s' % self.short_name
  131             if self.ptype != 'boolean':
  132                 sn += ':'
  133         return sn
  134 
  135     def convert(self, value):
  136         """
  137         Convert a string value as received in the command line
  138         tools and convert to the appropriate type of value.
  139         Raise a ValidationError if the value can't be converted.
  140 
  141         :type value: str
  142         :param value: The value to convert.  This should always
  143                       be a string.
  144         """
  145         return super(Param, self).convert(self,value)
  146 
  147 
  148
  [end of boto/roboto/param.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/boto/roboto/param.py b/boto/roboto/param.py
  --- a/boto/roboto/param.py
  +++ b/boto/roboto/param.py
  @@ -46,7 +46,7 @@
   
       @classmethod
       def convert_file(cls, param, value):
  -        if os.path.isfile(value):
  +        if os.path.exists(value) and not os.path.isdir(value):
               return value
           raise ValueError
  
verification_info: {"golden_diff": "diff --git a/boto/roboto/param.py b/boto/roboto/param.py\n--- a/boto/roboto/param.py\n+++ b/boto/roboto/param.py\n@@ -46,7 +46,7 @@\n \n     @classmethod\n     def convert_file(cls, param, value):\n-        if os.path.isfile(value):\n+        if os.path.exists(value) and not os.path.isdir(value):\n             return value\n         raise ValueError\n", "issue": "Invalid path check in euca-bundle-image\nThe -i option uses convert_file in boto/roboto/param.py to verify that the path passed is, indeed, a file. This fails unless the path specified is a boring old file which is not necessary. Indeed it not being necessary is sort of the whole point in unix having a /dev in the first place. Everything is a file.\n\nThe code calls os.path.isfile(value) in convert_file(). It should call os.path.exists(value) and not os.path.isdir(value). Directories are the only types of files which need to be considered special in the normal course of events.\n\n", "before_files": [{"content": "# Copyright (c) 2010 Mitch Garnaat http://garnaat.org/\n# Copyright (c) 2010, Eucalyptus Systems, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish, dis-\n# tribute, sublicense, and/or sell copies of the Software, and to permit\n# persons to whom the Software is furnished to do so, subject to the fol-\n# lowing conditions:\n#\n# The above copyright notice and this permission notice shall be included\n# in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-\n# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\nimport os\n\nclass Converter(object):\n\n    @classmethod\n    def convert_string(cls, param, value):\n        # TODO: could do length validation, etc. here\n        if not isinstance(value, basestring):\n            raise ValueError\n        return value\n\n    @classmethod\n    def convert_integer(cls, param, value):\n        # TODO: could do range checking here\n        return int(value)\n\n    @classmethod\n    def convert_boolean(cls, param, value):\n        \"\"\"\n        For command line arguments, just the presence\n        of the option means True so just return True\n        \"\"\"\n        return True\n\n    @classmethod\n    def convert_file(cls, param, value):\n        if os.path.isfile(value):\n            return value\n        raise ValueError\n\n    @classmethod\n    def convert_dir(cls, param, value):\n        if os.path.isdir(value):\n            return value\n        raise ValueError\n\n    @classmethod\n    def convert(cls, param, value):\n        try:\n            if hasattr(cls, 'convert_'+param.ptype):\n                mthd = getattr(cls, 'convert_'+param.ptype)\n            else:\n                mthd = cls.convert_string\n            return mthd(param, value)\n        except:\n            raise ValidationException(param, '')\n\nclass Param(Converter):\n\n    def __init__(self, name=None, ptype='string', optional=True,\n                 short_name=None, long_name=None, doc='',\n                 metavar=None, cardinality=1, default=None,\n                 choices=None, encoder=None, request_param=True):\n        self.name = name\n        self.ptype = ptype\n        self.optional = optional\n        self.short_name = short_name\n        self.long_name = long_name\n        self.doc = doc\n        self.metavar = metavar\n        self.cardinality = cardinality\n        self.default = default\n        self.choices = choices\n        self.encoder = encoder\n        self.request_param = request_param\n\n    @property\n    def optparse_long_name(self):\n        ln = None\n        if self.long_name:\n            ln = '--%s' % self.long_name\n        return ln\n\n    @property\n    def synopsis_long_name(self):\n        ln = None\n        if self.long_name:\n            ln = '--%s' % self.long_name\n        return ln\n\n    @property\n    def getopt_long_name(self):\n        ln = None\n        if self.long_name:\n            ln = '%s' % self.long_name\n            if self.ptype != 'boolean':\n                ln += '='\n        return ln\n\n    @property\n    def optparse_short_name(self):\n        sn = None\n        if self.short_name:\n            sn = '-%s' % self.short_name\n        return sn\n\n    @property\n    def synopsis_short_name(self):\n        sn = None\n        if self.short_name:\n            sn = '-%s' % self.short_name\n        return sn\n\n    @property\n    def getopt_short_name(self):\n        sn = None\n        if self.short_name:\n            sn = '%s' % self.short_name\n            if self.ptype != 'boolean':\n                sn += ':'\n        return sn\n\n    def convert(self, value):\n        \"\"\"\n        Convert a string value as received in the command line\n        tools and convert to the appropriate type of value.\n        Raise a ValidationError if the value can't be converted.\n\n        :type value: str\n        :param value: The value to convert.  This should always\n                      be a string.\n        \"\"\"\n        return super(Param, self).convert(self,value)\n\n\n", "path": "boto/roboto/param.py"}]}