prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  max_retries is ignored when using thrift
  connection/thrift.py does not catch socket.error in perform_request which cause max_retries to be ignored in the transport.
  
  One can argue that this socket.error exception should be translated into a TException in the offical thrift-library but I think it's better to have it included here aswell.
  
  
  </issue>
  <code>
  [start of elasticsearch/connection/thrift.py]
  1 from __future__ import absolute_import
  2 from socket import timeout as SocketTimeout
  3 import time
  4 import logging
  5 
  6 try:
  7     from .esthrift import Rest
  8     from .esthrift.ttypes import Method, RestRequest
  9 
  10     from thrift.transport import TTransport, TSocket, TSSLSocket
  11     from thrift.protocol import TBinaryProtocol
  12     from thrift.Thrift import TException
  13     THRIFT_AVAILABLE = True
  14 except ImportError:
  15     THRIFT_AVAILABLE = False
  16 
  17 from ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout
  18 from .pooling import PoolingConnection
  19 
  20 logger = logging.getLogger('elasticsearch')
  21 
  22 class ThriftConnection(PoolingConnection):
  23     """
  24     Connection using the `thrift` protocol to communicate with elasticsearch.
  25 
  26     See https://github.com/elasticsearch/elasticsearch-transport-thrift for additional info.
  27     """
  28     transport_schema = 'thrift'
  29 
  30     def __init__(self, host='localhost', port=9500, framed_transport=False, use_ssl=False, **kwargs):
  31         """
  32         :arg framed_transport: use `TTransport.TFramedTransport` instead of
  33             `TTransport.TBufferedTransport`
  34         """
  35         if not THRIFT_AVAILABLE:
  36             raise ImproperlyConfigured("Thrift is not available.")
  37 
  38         super(ThriftConnection, self).__init__(host=host, port=port, **kwargs)
  39         self._framed_transport = framed_transport
  40         self._tsocket_class = TSocket.TSocket
  41         if use_ssl:
  42             self._tsocket_class = TSSLSocket.TSSLSocket 
  43         self._tsocket_args = (host, port)
  44 
  45     def _make_connection(self):
  46         socket = self._tsocket_class(*self._tsocket_args)
  47         socket.setTimeout(self.timeout * 1000.0)
  48         if self._framed_transport:
  49             transport = TTransport.TFramedTransport(socket)
  50         else:
  51             transport = TTransport.TBufferedTransport(socket)
  52 
  53         protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
  54         client = Rest.Client(protocol)
  55         client.transport = transport
  56         transport.open()
  57         return client
  58 
  59     def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):
  60         request = RestRequest(method=Method._NAMES_TO_VALUES[method.upper()], uri=url,
  61                     parameters=params, body=body)
  62 
  63         start = time.time()
  64         tclient = None
  65         try:
  66             tclient = self._get_connection()
  67             response = tclient.execute(request)
  68             duration = time.time() - start
  69         except SocketTimeout as e:
  70             self.log_request_fail(method, url, body, time.time() - start, exception=e)
  71             raise ConnectionTimeout('TIMEOUT', str(e), e)
  72         except (TException, SocketTimeout) as e:
  73             self.log_request_fail(method, url, body, time.time() - start, exception=e)
  74             if tclient:
  75                 try:
  76                     # try closing transport socket
  77                     tclient.transport.close()
  78                 except Exception as e:
  79                     logger.warning(
  80                         'Exception %s occured when closing a failed thrift connection.',
  81                         e, exc_info=True
  82                     )
  83             raise ConnectionError('N/A', str(e), e)
  84 
  85         self._release_connection(tclient)
  86 
  87         if not (200 <= response.status < 300) and response.status not in ignore:
  88             self.log_request_fail(method, url, body, duration, response.status)
  89             self._raise_error(response.status, response.body)
  90 
  91         self.log_request_success(method, url, url, body, response.status,
  92             response.body, duration)
  93 
  94         headers = {}
  95         if response.headers:
  96             headers = dict((k.lower(), v) for k, v in response.headers.items())
  97         return response.status, headers, response.body or ''
  98 
  99
  [end of elasticsearch/connection/thrift.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/elasticsearch/connection/thrift.py b/elasticsearch/connection/thrift.py
  --- a/elasticsearch/connection/thrift.py
  +++ b/elasticsearch/connection/thrift.py
  @@ -1,5 +1,6 @@
   from __future__ import absolute_import
   from socket import timeout as SocketTimeout
  +from socket import error as SocketError
   import time
   import logging
   
  @@ -69,7 +70,7 @@
           except SocketTimeout as e:
               self.log_request_fail(method, url, body, time.time() - start, exception=e)
               raise ConnectionTimeout('TIMEOUT', str(e), e)
  -        except (TException, SocketTimeout) as e:
  +        except (TException, SocketError) as e:
               self.log_request_fail(method, url, body, time.time() - start, exception=e)
               if tclient:
                   try:
  
verification_info: {"golden_diff": "diff --git a/elasticsearch/connection/thrift.py b/elasticsearch/connection/thrift.py\n--- a/elasticsearch/connection/thrift.py\n+++ b/elasticsearch/connection/thrift.py\n@@ -1,5 +1,6 @@\n from __future__ import absolute_import\n from socket import timeout as SocketTimeout\n+from socket import error as SocketError\n import time\n import logging\n \n@@ -69,7 +70,7 @@\n         except SocketTimeout as e:\n             self.log_request_fail(method, url, body, time.time() - start, exception=e)\n             raise ConnectionTimeout('TIMEOUT', str(e), e)\n-        except (TException, SocketTimeout) as e:\n+        except (TException, SocketError) as e:\n             self.log_request_fail(method, url, body, time.time() - start, exception=e)\n             if tclient:\n                 try:\n", "issue": "max_retries is ignored when using thrift\nconnection/thrift.py does not catch socket.error in perform_request which cause max_retries to be ignored in the transport.\n\nOne can argue that this socket.error exception should be translated into a TException in the offical thrift-library but I think it's better to have it included here aswell.\n\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom socket import timeout as SocketTimeout\nimport time\nimport logging\n\ntry:\n    from .esthrift import Rest\n    from .esthrift.ttypes import Method, RestRequest\n\n    from thrift.transport import TTransport, TSocket, TSSLSocket\n    from thrift.protocol import TBinaryProtocol\n    from thrift.Thrift import TException\n    THRIFT_AVAILABLE = True\nexcept ImportError:\n    THRIFT_AVAILABLE = False\n\nfrom ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout\nfrom .pooling import PoolingConnection\n\nlogger = logging.getLogger('elasticsearch')\n\nclass ThriftConnection(PoolingConnection):\n    \"\"\"\n    Connection using the `thrift` protocol to communicate with elasticsearch.\n\n    See https://github.com/elasticsearch/elasticsearch-transport-thrift for additional info.\n    \"\"\"\n    transport_schema = 'thrift'\n\n    def __init__(self, host='localhost', port=9500, framed_transport=False, use_ssl=False, **kwargs):\n        \"\"\"\n        :arg framed_transport: use `TTransport.TFramedTransport` instead of\n            `TTransport.TBufferedTransport`\n        \"\"\"\n        if not THRIFT_AVAILABLE:\n            raise ImproperlyConfigured(\"Thrift is not available.\")\n\n        super(ThriftConnection, self).__init__(host=host, port=port, **kwargs)\n        self._framed_transport = framed_transport\n        self._tsocket_class = TSocket.TSocket\n        if use_ssl:\n            self._tsocket_class = TSSLSocket.TSSLSocket \n        self._tsocket_args = (host, port)\n\n    def _make_connection(self):\n        socket = self._tsocket_class(*self._tsocket_args)\n        socket.setTimeout(self.timeout * 1000.0)\n        if self._framed_transport:\n            transport = TTransport.TFramedTransport(socket)\n        else:\n            transport = TTransport.TBufferedTransport(socket)\n\n        protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)\n        client = Rest.Client(protocol)\n        client.transport = transport\n        transport.open()\n        return client\n\n    def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):\n        request = RestRequest(method=Method._NAMES_TO_VALUES[method.upper()], uri=url,\n                    parameters=params, body=body)\n\n        start = time.time()\n        tclient = None\n        try:\n            tclient = self._get_connection()\n            response = tclient.execute(request)\n            duration = time.time() - start\n        except SocketTimeout as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionTimeout('TIMEOUT', str(e), e)\n        except (TException, SocketTimeout) as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            if tclient:\n                try:\n                    # try closing transport socket\n                    tclient.transport.close()\n                except Exception as e:\n                    logger.warning(\n                        'Exception %s occured when closing a failed thrift connection.',\n                        e, exc_info=True\n                    )\n            raise ConnectionError('N/A', str(e), e)\n\n        self._release_connection(tclient)\n\n        if not (200 <= response.status < 300) and response.status not in ignore:\n            self.log_request_fail(method, url, body, duration, response.status)\n            self._raise_error(response.status, response.body)\n\n        self.log_request_success(method, url, url, body, response.status,\n            response.body, duration)\n\n        headers = {}\n        if response.headers:\n            headers = dict((k.lower(), v) for k, v in response.headers.items())\n        return response.status, headers, response.body or ''\n\n", "path": "elasticsearch/connection/thrift.py"}]}