You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ns...@apache.org on 2016/02/04 06:28:50 UTC

[6/8] thrift git commit: THRIFT-3596 Better conformance to PEP8

http://git-wip-us.apache.org/repos/asf/thrift/blob/10308cb9/lib/py/src/server/TProcessPoolServer.py
----------------------------------------------------------------------
diff --git a/lib/py/src/server/TProcessPoolServer.py b/lib/py/src/server/TProcessPoolServer.py
index b2c2308..fe6dc81 100644
--- a/lib/py/src/server/TProcessPoolServer.py
+++ b/lib/py/src/server/TProcessPoolServer.py
@@ -19,13 +19,14 @@
 
 
 import logging
-logger = logging.getLogger(__name__)
 
-from multiprocessing import  Process, Value, Condition, reduction
+from multiprocessing import Process, Value, Condition
 
 from .TServer import TServer
 from thrift.transport.TTransport import TTransportException
 
+logger = logging.getLogger(__name__)
+
 
 class TProcessPoolServer(TServer):
     """Server with a fixed size pool of worker subprocesses to service requests
@@ -59,7 +60,7 @@ class TProcessPoolServer(TServer):
             try:
                 client = self.serverTransport.accept()
                 if not client:
-                  continue
+                    continue
                 self.serveClient(client)
             except (KeyboardInterrupt, SystemExit):
                 return 0
@@ -76,7 +77,7 @@ class TProcessPoolServer(TServer):
         try:
             while True:
                 self.processor.process(iprot, oprot)
-        except TTransportException as tx:
+        except TTransportException:
             pass
         except Exception as x:
             logger.exception(x)

http://git-wip-us.apache.org/repos/asf/thrift/blob/10308cb9/lib/py/src/server/TServer.py
----------------------------------------------------------------------
diff --git a/lib/py/src/server/TServer.py b/lib/py/src/server/TServer.py
index 30f063b..d5d9c98 100644
--- a/lib/py/src/server/TServer.py
+++ b/lib/py/src/server/TServer.py
@@ -18,262 +18,259 @@
 #
 
 from six.moves import queue
+import logging
 import os
-import sys
 import threading
-import traceback
-
-import logging
-logger = logging.getLogger(__name__)
 
-from thrift.Thrift import TProcessor
 from thrift.protocol import TBinaryProtocol
 from thrift.transport import TTransport
 
+logger = logging.getLogger(__name__)
+
 
 class TServer(object):
-  """Base interface for a server, which must have a serve() method.
-
-  Three constructors for all servers:
-  1) (processor, serverTransport)
-  2) (processor, serverTransport, transportFactory, protocolFactory)
-  3) (processor, serverTransport,
-      inputTransportFactory, outputTransportFactory,
-      inputProtocolFactory, outputProtocolFactory)
-  """
-  def __init__(self, *args):
-    if (len(args) == 2):
-      self.__initArgs__(args[0], args[1],
-                        TTransport.TTransportFactoryBase(),
-                        TTransport.TTransportFactoryBase(),
-                        TBinaryProtocol.TBinaryProtocolFactory(),
-                        TBinaryProtocol.TBinaryProtocolFactory())
-    elif (len(args) == 4):
-      self.__initArgs__(args[0], args[1], args[2], args[2], args[3], args[3])
-    elif (len(args) == 6):
-      self.__initArgs__(args[0], args[1], args[2], args[3], args[4], args[5])
-
-  def __initArgs__(self, processor, serverTransport,
-                   inputTransportFactory, outputTransportFactory,
-                   inputProtocolFactory, outputProtocolFactory):
-    self.processor = processor
-    self.serverTransport = serverTransport
-    self.inputTransportFactory = inputTransportFactory
-    self.outputTransportFactory = outputTransportFactory
-    self.inputProtocolFactory = inputProtocolFactory
-    self.outputProtocolFactory = outputProtocolFactory
-
-  def serve(self):
-    pass
+    """Base interface for a server, which must have a serve() method.
+
+    Three constructors for all servers:
+    1) (processor, serverTransport)
+    2) (processor, serverTransport, transportFactory, protocolFactory)
+    3) (processor, serverTransport,
+        inputTransportFactory, outputTransportFactory,
+        inputProtocolFactory, outputProtocolFactory)
+    """
+    def __init__(self, *args):
+        if (len(args) == 2):
+            self.__initArgs__(args[0], args[1],
+                              TTransport.TTransportFactoryBase(),
+                              TTransport.TTransportFactoryBase(),
+                              TBinaryProtocol.TBinaryProtocolFactory(),
+                              TBinaryProtocol.TBinaryProtocolFactory())
+        elif (len(args) == 4):
+            self.__initArgs__(args[0], args[1], args[2], args[2], args[3], args[3])
+        elif (len(args) == 6):
+            self.__initArgs__(args[0], args[1], args[2], args[3], args[4], args[5])
+
+    def __initArgs__(self, processor, serverTransport,
+                     inputTransportFactory, outputTransportFactory,
+                     inputProtocolFactory, outputProtocolFactory):
+        self.processor = processor
+        self.serverTransport = serverTransport
+        self.inputTransportFactory = inputTransportFactory
+        self.outputTransportFactory = outputTransportFactory
+        self.inputProtocolFactory = inputProtocolFactory
+        self.outputProtocolFactory = outputProtocolFactory
+
+    def serve(self):
+        pass
 
 
 class TSimpleServer(TServer):
-  """Simple single-threaded server that just pumps around one transport."""
-
-  def __init__(self, *args):
-    TServer.__init__(self, *args)
-
-  def serve(self):
-    self.serverTransport.listen()
-    while True:
-      client = self.serverTransport.accept()
-      if not client:
-        continue
-      itrans = self.inputTransportFactory.getTransport(client)
-      otrans = self.outputTransportFactory.getTransport(client)
-      iprot = self.inputProtocolFactory.getProtocol(itrans)
-      oprot = self.outputProtocolFactory.getProtocol(otrans)
-      try:
+    """Simple single-threaded server that just pumps around one transport."""
+
+    def __init__(self, *args):
+        TServer.__init__(self, *args)
+
+    def serve(self):
+        self.serverTransport.listen()
         while True:
-          self.processor.process(iprot, oprot)
-      except TTransport.TTransportException as tx:
-        pass
-      except Exception as x:
-        logger.exception(x)
+            client = self.serverTransport.accept()
+            if not client:
+                continue
+            itrans = self.inputTransportFactory.getTransport(client)
+            otrans = self.outputTransportFactory.getTransport(client)
+            iprot = self.inputProtocolFactory.getProtocol(itrans)
+            oprot = self.outputProtocolFactory.getProtocol(otrans)
+            try:
+                while True:
+                    self.processor.process(iprot, oprot)
+            except TTransport.TTransportException:
+                pass
+            except Exception as x:
+                logger.exception(x)
 
-      itrans.close()
-      otrans.close()
+            itrans.close()
+            otrans.close()
 
 
 class TThreadedServer(TServer):
-  """Threaded server that spawns a new thread per each connection."""
-
-  def __init__(self, *args, **kwargs):
-    TServer.__init__(self, *args)
-    self.daemon = kwargs.get("daemon", False)
-
-  def serve(self):
-    self.serverTransport.listen()
-    while True:
-      try:
-        client = self.serverTransport.accept()
-        if not client:
-          continue
-        t = threading.Thread(target=self.handle, args=(client,))
-        t.setDaemon(self.daemon)
-        t.start()
-      except KeyboardInterrupt:
-        raise
-      except Exception as x:
-        logger.exception(x)
-
-  def handle(self, client):
-    itrans = self.inputTransportFactory.getTransport(client)
-    otrans = self.outputTransportFactory.getTransport(client)
-    iprot = self.inputProtocolFactory.getProtocol(itrans)
-    oprot = self.outputProtocolFactory.getProtocol(otrans)
-    try:
-      while True:
-        self.processor.process(iprot, oprot)
-    except TTransport.TTransportException as tx:
-      pass
-    except Exception as x:
-      logger.exception(x)
-
-    itrans.close()
-    otrans.close()
+    """Threaded server that spawns a new thread per each connection."""
+
+    def __init__(self, *args, **kwargs):
+        TServer.__init__(self, *args)
+        self.daemon = kwargs.get("daemon", False)
+
+    def serve(self):
+        self.serverTransport.listen()
+        while True:
+            try:
+                client = self.serverTransport.accept()
+                if not client:
+                    continue
+                t = threading.Thread(target=self.handle, args=(client,))
+                t.setDaemon(self.daemon)
+                t.start()
+            except KeyboardInterrupt:
+                raise
+            except Exception as x:
+                logger.exception(x)
+
+    def handle(self, client):
+        itrans = self.inputTransportFactory.getTransport(client)
+        otrans = self.outputTransportFactory.getTransport(client)
+        iprot = self.inputProtocolFactory.getProtocol(itrans)
+        oprot = self.outputProtocolFactory.getProtocol(otrans)
+        try:
+            while True:
+                self.processor.process(iprot, oprot)
+        except TTransport.TTransportException:
+            pass
+        except Exception as x:
+            logger.exception(x)
+
+        itrans.close()
+        otrans.close()
 
 
 class TThreadPoolServer(TServer):
-  """Server with a fixed size pool of threads which service requests."""
-
-  def __init__(self, *args, **kwargs):
-    TServer.__init__(self, *args)
-    self.clients = queue.Queue()
-    self.threads = 10
-    self.daemon = kwargs.get("daemon", False)
-
-  def setNumThreads(self, num):
-    """Set the number of worker threads that should be created"""
-    self.threads = num
-
-  def serveThread(self):
-    """Loop around getting clients from the shared queue and process them."""
-    while True:
-      try:
-        client = self.clients.get()
-        self.serveClient(client)
-      except Exception as x:
-        logger.exception(x)
-
-  def serveClient(self, client):
-    """Process input/output from a client for as long as possible"""
-    itrans = self.inputTransportFactory.getTransport(client)
-    otrans = self.outputTransportFactory.getTransport(client)
-    iprot = self.inputProtocolFactory.getProtocol(itrans)
-    oprot = self.outputProtocolFactory.getProtocol(otrans)
-    try:
-      while True:
-        self.processor.process(iprot, oprot)
-    except TTransport.TTransportException as tx:
-      pass
-    except Exception as x:
-      logger.exception(x)
-
-    itrans.close()
-    otrans.close()
-
-  def serve(self):
-    """Start a fixed number of worker threads and put client into a queue"""
-    for i in range(self.threads):
-      try:
-        t = threading.Thread(target=self.serveThread)
-        t.setDaemon(self.daemon)
-        t.start()
-      except Exception as x:
-        logger.exception(x)
-
-    # Pump the socket for clients
-    self.serverTransport.listen()
-    while True:
-      try:
-        client = self.serverTransport.accept()
-        if not client:
-          continue
-        self.clients.put(client)
-      except Exception as x:
-        logger.exception(x)
+    """Server with a fixed size pool of threads which service requests."""
 
+    def __init__(self, *args, **kwargs):
+        TServer.__init__(self, *args)
+        self.clients = queue.Queue()
+        self.threads = 10
+        self.daemon = kwargs.get("daemon", False)
 
-class TForkingServer(TServer):
-  """A Thrift server that forks a new process for each request
-
-  This is more scalable than the threaded server as it does not cause
-  GIL contention.
-
-  Note that this has different semantics from the threading server.
-  Specifically, updates to shared variables will no longer be shared.
-  It will also not work on windows.
-
-  This code is heavily inspired by SocketServer.ForkingMixIn in the
-  Python stdlib.
-  """
-  def __init__(self, *args):
-    TServer.__init__(self, *args)
-    self.children = []
-
-  def serve(self):
-    def try_close(file):
-      try:
-        file.close()
-      except IOError as e:
-        logger.warning(e, exc_info=True)
-
-    self.serverTransport.listen()
-    while True:
-      client = self.serverTransport.accept()
-      if not client:
-        continue
-      try:
-        pid = os.fork()
-
-        if pid:  # parent
-          # add before collect, otherwise you race w/ waitpid
-          self.children.append(pid)
-          self.collect_children()
-
-          # Parent must close socket or the connection may not get
-          # closed promptly
-          itrans = self.inputTransportFactory.getTransport(client)
-          otrans = self.outputTransportFactory.getTransport(client)
-          try_close(itrans)
-          try_close(otrans)
-        else:
-          itrans = self.inputTransportFactory.getTransport(client)
-          otrans = self.outputTransportFactory.getTransport(client)
-
-          iprot = self.inputProtocolFactory.getProtocol(itrans)
-          oprot = self.outputProtocolFactory.getProtocol(otrans)
-
-          ecode = 0
-          try:
+    def setNumThreads(self, num):
+        """Set the number of worker threads that should be created"""
+        self.threads = num
+
+    def serveThread(self):
+        """Loop around getting clients from the shared queue and process them."""
+        while True:
             try:
-              while True:
+                client = self.clients.get()
+                self.serveClient(client)
+            except Exception as x:
+                logger.exception(x)
+
+    def serveClient(self, client):
+        """Process input/output from a client for as long as possible"""
+        itrans = self.inputTransportFactory.getTransport(client)
+        otrans = self.outputTransportFactory.getTransport(client)
+        iprot = self.inputProtocolFactory.getProtocol(itrans)
+        oprot = self.outputProtocolFactory.getProtocol(otrans)
+        try:
+            while True:
                 self.processor.process(iprot, oprot)
-            except TTransport.TTransportException:
-              pass
-            except Exception as e:
-              logger.exception(e)
-              ecode = 1
-          finally:
-            try_close(itrans)
-            try_close(otrans)
+        except TTransport.TTransportException:
+            pass
+        except Exception as x:
+            logger.exception(x)
 
-          os._exit(ecode)
+        itrans.close()
+        otrans.close()
 
-      except TTransport.TTransportException:
-        pass
-      except Exception as x:
-        logger.exception(x)
-
-  def collect_children(self):
-    while self.children:
-      try:
-        pid, status = os.waitpid(0, os.WNOHANG)
-      except os.error:
-        pid = None
-
-      if pid:
-        self.children.remove(pid)
-      else:
-        break
+    def serve(self):
+        """Start a fixed number of worker threads and put client into a queue"""
+        for i in range(self.threads):
+            try:
+                t = threading.Thread(target=self.serveThread)
+                t.setDaemon(self.daemon)
+                t.start()
+            except Exception as x:
+                logger.exception(x)
+
+        # Pump the socket for clients
+        self.serverTransport.listen()
+        while True:
+            try:
+                client = self.serverTransport.accept()
+                if not client:
+                    continue
+                self.clients.put(client)
+            except Exception as x:
+                logger.exception(x)
+
+
+class TForkingServer(TServer):
+    """A Thrift server that forks a new process for each request
+
+    This is more scalable than the threaded server as it does not cause
+    GIL contention.
+
+    Note that this has different semantics from the threading server.
+    Specifically, updates to shared variables will no longer be shared.
+    It will also not work on windows.
+
+    This code is heavily inspired by SocketServer.ForkingMixIn in the
+    Python stdlib.
+    """
+    def __init__(self, *args):
+        TServer.__init__(self, *args)
+        self.children = []
+
+    def serve(self):
+        def try_close(file):
+            try:
+                file.close()
+            except IOError as e:
+                logger.warning(e, exc_info=True)
+
+        self.serverTransport.listen()
+        while True:
+            client = self.serverTransport.accept()
+            if not client:
+                continue
+            try:
+                pid = os.fork()
+
+                if pid:  # parent
+                    # add before collect, otherwise you race w/ waitpid
+                    self.children.append(pid)
+                    self.collect_children()
+
+                    # Parent must close socket or the connection may not get
+                    # closed promptly
+                    itrans = self.inputTransportFactory.getTransport(client)
+                    otrans = self.outputTransportFactory.getTransport(client)
+                    try_close(itrans)
+                    try_close(otrans)
+                else:
+                    itrans = self.inputTransportFactory.getTransport(client)
+                    otrans = self.outputTransportFactory.getTransport(client)
+
+                    iprot = self.inputProtocolFactory.getProtocol(itrans)
+                    oprot = self.outputProtocolFactory.getProtocol(otrans)
+
+                    ecode = 0
+                    try:
+                        try:
+                            while True:
+                                self.processor.process(iprot, oprot)
+                        except TTransport.TTransportException:
+                            pass
+                        except Exception as e:
+                            logger.exception(e)
+                            ecode = 1
+                    finally:
+                        try_close(itrans)
+                        try_close(otrans)
+
+                    os._exit(ecode)
+
+            except TTransport.TTransportException:
+                pass
+            except Exception as x:
+                logger.exception(x)
+
+    def collect_children(self):
+        while self.children:
+            try:
+                pid, status = os.waitpid(0, os.WNOHANG)
+            except os.error:
+                pid = None
+
+            if pid:
+                self.children.remove(pid)
+            else:
+                break

http://git-wip-us.apache.org/repos/asf/thrift/blob/10308cb9/lib/py/src/transport/THttpClient.py
----------------------------------------------------------------------
diff --git a/lib/py/src/transport/THttpClient.py b/lib/py/src/transport/THttpClient.py
index 5abd41c..95f118c 100644
--- a/lib/py/src/transport/THttpClient.py
+++ b/lib/py/src/transport/THttpClient.py
@@ -26,130 +26,130 @@ import warnings
 from six.moves import urllib
 from six.moves import http_client
 
-from .TTransport import *
+from .TTransport import TTransportBase
 import six
 
 
 class THttpClient(TTransportBase):
-  """Http implementation of TTransport base."""
-
-  def __init__(self, uri_or_host, port=None, path=None):
-    """THttpClient supports two different types constructor parameters.
-
-    THttpClient(host, port, path) - deprecated
-    THttpClient(uri)
-
-    Only the second supports https.
-    """
-    if port is not None:
-      warnings.warn(
-        "Please use the THttpClient('http://host:port/path') syntax",
-        DeprecationWarning,
-        stacklevel=2)
-      self.host = uri_or_host
-      self.port = port
-      assert path
-      self.path = path
-      self.scheme = 'http'
-    else:
-      parsed = urllib.parse.urlparse(uri_or_host)
-      self.scheme = parsed.scheme
-      assert self.scheme in ('http', 'https')
-      if self.scheme == 'http':
-        self.port = parsed.port or http_client.HTTP_PORT
-      elif self.scheme == 'https':
-        self.port = parsed.port or http_client.HTTPS_PORT
-      self.host = parsed.hostname
-      self.path = parsed.path
-      if parsed.query:
-        self.path += '?%s' % parsed.query
-    self.__wbuf = BytesIO()
-    self.__http = None
-    self.__http_response = None
-    self.__timeout = None
-    self.__custom_headers = None
-
-  def open(self):
-    if self.scheme == 'http':
-      self.__http = http_client.HTTPConnection(self.host, self.port)
-    else:
-      self.__http = http_client.HTTPSConnection(self.host, self.port)
-
-  def close(self):
-    self.__http.close()
-    self.__http = None
-    self.__http_response = None
-
-  def isOpen(self):
-    return self.__http is not None
-
-  def setTimeout(self, ms):
-    if not hasattr(socket, 'getdefaulttimeout'):
-      raise NotImplementedError
-
-    if ms is None:
-      self.__timeout = None
-    else:
-      self.__timeout = ms / 1000.0
-
-  def setCustomHeaders(self, headers):
-    self.__custom_headers = headers
-
-  def read(self, sz):
-    return self.__http_response.read(sz)
-
-  def write(self, buf):
-    self.__wbuf.write(buf)
-
-  def __withTimeout(f):
-    def _f(*args, **kwargs):
-      orig_timeout = socket.getdefaulttimeout()
-      socket.setdefaulttimeout(args[0].__timeout)
-      try:
-        result = f(*args, **kwargs)
-      finally:
-        socket.setdefaulttimeout(orig_timeout)
-      return result
-    return _f
-
-  def flush(self):
-    if self.isOpen():
-      self.close()
-    self.open()
-
-    # Pull data out of buffer
-    data = self.__wbuf.getvalue()
-    self.__wbuf = BytesIO()
-
-    # HTTP request
-    self.__http.putrequest('POST', self.path)
-
-    # Write headers
-    self.__http.putheader('Content-Type', 'application/x-thrift')
-    self.__http.putheader('Content-Length', str(len(data)))
-
-    if not self.__custom_headers or 'User-Agent' not in self.__custom_headers:
-      user_agent = 'Python/THttpClient'
-      script = os.path.basename(sys.argv[0])
-      if script:
-        user_agent = '%s (%s)' % (user_agent, urllib.parse.quote(script))
-      self.__http.putheader('User-Agent', user_agent)
-
-    if self.__custom_headers:
-        for key, val in six.iteritems(self.__custom_headers):
-            self.__http.putheader(key, val)
-
-    self.__http.endheaders()
-
-    # Write payload
-    self.__http.send(data)
-
-    # Get reply to flush the request
-    self.__http_response = self.__http.getresponse()
-    self.code = self.__http_response.status
-    self.message = self.__http_response.reason
-    self.headers = self.__http_response.msg
-
-  # Decorate if we know how to timeout
-  if hasattr(socket, 'getdefaulttimeout'):
-    flush = __withTimeout(flush)
+    """Http implementation of TTransport base."""
+
+    def __init__(self, uri_or_host, port=None, path=None):
+        """THttpClient supports two different types constructor parameters.
+
+        THttpClient(host, port, path) - deprecated
+        THttpClient(uri)
+
+        Only the second supports https.
+        """
+        if port is not None:
+            warnings.warn(
+                "Please use the THttpClient('http://host:port/path') syntax",
+                DeprecationWarning,
+                stacklevel=2)
+            self.host = uri_or_host
+            self.port = port
+            assert path
+            self.path = path
+            self.scheme = 'http'
+        else:
+            parsed = urllib.parse.urlparse(uri_or_host)
+            self.scheme = parsed.scheme
+            assert self.scheme in ('http', 'https')
+            if self.scheme == 'http':
+                self.port = parsed.port or http_client.HTTP_PORT
+            elif self.scheme == 'https':
+                self.port = parsed.port or http_client.HTTPS_PORT
+            self.host = parsed.hostname
+            self.path = parsed.path
+            if parsed.query:
+                self.path += '?%s' % parsed.query
+        self.__wbuf = BytesIO()
+        self.__http = None
+        self.__http_response = None
+        self.__timeout = None
+        self.__custom_headers = None
+
+    def open(self):
+        if self.scheme == 'http':
+            self.__http = http_client.HTTPConnection(self.host, self.port)
+        else:
+            self.__http = http_client.HTTPSConnection(self.host, self.port)
+
+    def close(self):
+        self.__http.close()
+        self.__http = None
+        self.__http_response = None
+
+    def isOpen(self):
+        return self.__http is not None
+
+    def setTimeout(self, ms):
+        if not hasattr(socket, 'getdefaulttimeout'):
+            raise NotImplementedError
+
+        if ms is None:
+            self.__timeout = None
+        else:
+            self.__timeout = ms / 1000.0
+
+    def setCustomHeaders(self, headers):
+        self.__custom_headers = headers
+
+    def read(self, sz):
+        return self.__http_response.read(sz)
+
+    def write(self, buf):
+        self.__wbuf.write(buf)
+
+    def __withTimeout(f):
+        def _f(*args, **kwargs):
+            orig_timeout = socket.getdefaulttimeout()
+            socket.setdefaulttimeout(args[0].__timeout)
+            try:
+                result = f(*args, **kwargs)
+            finally:
+                socket.setdefaulttimeout(orig_timeout)
+            return result
+        return _f
+
+    def flush(self):
+        if self.isOpen():
+            self.close()
+        self.open()
+
+        # Pull data out of buffer
+        data = self.__wbuf.getvalue()
+        self.__wbuf = BytesIO()
+
+        # HTTP request
+        self.__http.putrequest('POST', self.path)
+
+        # Write headers
+        self.__http.putheader('Content-Type', 'application/x-thrift')
+        self.__http.putheader('Content-Length', str(len(data)))
+
+        if not self.__custom_headers or 'User-Agent' not in self.__custom_headers:
+            user_agent = 'Python/THttpClient'
+            script = os.path.basename(sys.argv[0])
+            if script:
+                user_agent = '%s (%s)' % (user_agent, urllib.parse.quote(script))
+            self.__http.putheader('User-Agent', user_agent)
+
+        if self.__custom_headers:
+            for key, val in six.iteritems(self.__custom_headers):
+                self.__http.putheader(key, val)
+
+        self.__http.endheaders()
+
+        # Write payload
+        self.__http.send(data)
+
+        # Get reply to flush the request
+        self.__http_response = self.__http.getresponse()
+        self.code = self.__http_response.status
+        self.message = self.__http_response.reason
+        self.headers = self.__http_response.msg
+
+    # Decorate if we know how to timeout
+    if hasattr(socket, 'getdefaulttimeout'):
+        flush = __withTimeout(flush)

http://git-wip-us.apache.org/repos/asf/thrift/blob/10308cb9/lib/py/src/transport/TSSLSocket.py
----------------------------------------------------------------------
diff --git a/lib/py/src/transport/TSSLSocket.py b/lib/py/src/transport/TSSLSocket.py
index 9be0912..3f1a909 100644
--- a/lib/py/src/transport/TSSLSocket.py
+++ b/lib/py/src/transport/TSSLSocket.py
@@ -32,345 +32,345 @@ warnings.filterwarnings('default', category=DeprecationWarning, module=__name__)
 
 
 class TSSLBase(object):
-  # SSLContext is not available for Python < 2.7.9
-  _has_ssl_context = sys.hexversion >= 0x020709F0
-
-  # ciphers argument is not available for Python < 2.7.0
-  _has_ciphers = sys.hexversion >= 0x020700F0
-
-  # For pythoon >= 2.7.9, use latest TLS that both client and server supports.
-  # SSL 2.0 and 3.0 are disabled via ssl.OP_NO_SSLv2 and ssl.OP_NO_SSLv3.
-  # For pythoon < 2.7.9, use TLS 1.0 since TLSv1_X nare OP_NO_SSLvX are unavailable.
-  _default_protocol = ssl.PROTOCOL_SSLv23 if _has_ssl_context else ssl.PROTOCOL_TLSv1
-
-  def _init_context(self, ssl_version):
-    if self._has_ssl_context:
-      self._context = ssl.SSLContext(ssl_version)
-      if self._context.protocol == ssl.PROTOCOL_SSLv23:
-        self._context.options |= ssl.OP_NO_SSLv2
-        self._context.options |= ssl.OP_NO_SSLv3
-    else:
-      self._context = None
-      self._ssl_version = ssl_version
-
-  @property
-  def ssl_version(self):
-    if self._has_ssl_context:
-      return self.ssl_context.protocol
-    else:
-      return self._ssl_version
-
-  @property
-  def ssl_context(self):
-    return self._context
-
-  SSL_VERSION = _default_protocol
-  """
+    # SSLContext is not available for Python < 2.7.9
+    _has_ssl_context = sys.hexversion >= 0x020709F0
+
+    # ciphers argument is not available for Python < 2.7.0
+    _has_ciphers = sys.hexversion >= 0x020700F0
+
+    # For pythoon >= 2.7.9, use latest TLS that both client and server supports.
+    # SSL 2.0 and 3.0 are disabled via ssl.OP_NO_SSLv2 and ssl.OP_NO_SSLv3.
+    # For pythoon < 2.7.9, use TLS 1.0 since TLSv1_X nare OP_NO_SSLvX are unavailable.
+    _default_protocol = ssl.PROTOCOL_SSLv23 if _has_ssl_context else ssl.PROTOCOL_TLSv1
+
+    def _init_context(self, ssl_version):
+        if self._has_ssl_context:
+            self._context = ssl.SSLContext(ssl_version)
+            if self._context.protocol == ssl.PROTOCOL_SSLv23:
+                self._context.options |= ssl.OP_NO_SSLv2
+                self._context.options |= ssl.OP_NO_SSLv3
+        else:
+            self._context = None
+            self._ssl_version = ssl_version
+
+    @property
+    def ssl_version(self):
+        if self._has_ssl_context:
+            return self.ssl_context.protocol
+        else:
+            return self._ssl_version
+
+    @property
+    def ssl_context(self):
+        return self._context
+
+    SSL_VERSION = _default_protocol
+    """
   Default SSL version.
   For backword compatibility, it can be modified.
   Use __init__ keywoard argument "ssl_version" instead.
   """
 
-  def _deprecated_arg(self, args, kwargs, pos, key):
-    if len(args) <= pos:
-      return
-    real_pos = pos + 3
-    warnings.warn(
-        '%dth positional argument is deprecated. Use keyward argument insteand.' % real_pos,
-        DeprecationWarning)
-    if key in kwargs:
-      raise TypeError('Duplicate argument: %dth argument and %s keyward argument.', (real_pos, key))
-    kwargs[key] = args[pos]
-
-  def _unix_socket_arg(self, host, port, args, kwargs):
-    key = 'unix_socket'
-    if host is None and port is None and len(args) == 1 and key not in kwargs:
-      kwargs[key] = args[0]
-      return True
-    return False
-
-  def __getattr__(self, key):
-    if key == 'SSL_VERSION':
-      warnings.warn('Use ssl_version attribute instead.', DeprecationWarning)
-      return self.ssl_version
-
-  def __init__(self, server_side, host, ssl_opts):
-    self._server_side = server_side
-    if TSSLBase.SSL_VERSION != self._default_protocol:
-      warnings.warn('SSL_VERSION is deprecated. Use ssl_version keyward argument instead.', DeprecationWarning)
-    self._context = ssl_opts.pop('ssl_context', None)
-    self._server_hostname = None
-    if not self._server_side:
-      self._server_hostname = ssl_opts.pop('server_hostname', host)
-    if self._context:
-      self._custom_context = True
-      if ssl_opts:
-        raise ValueError('Incompatible arguments: ssl_context and %s' % ' '.join(ssl_opts.keys()))
-      if not self._has_ssl_context:
-        raise ValueError('ssl_context is not available for this version of Python')
-    else:
-      self._custom_context = False
-      ssl_version = ssl_opts.pop('ssl_version', TSSLBase.SSL_VERSION)
-      self._init_context(ssl_version)
-      self.cert_reqs = ssl_opts.pop('cert_reqs', ssl.CERT_REQUIRED)
-      self.ca_certs = ssl_opts.pop('ca_certs', None)
-      self.keyfile = ssl_opts.pop('keyfile', None)
-      self.certfile = ssl_opts.pop('certfile', None)
-      self.ciphers = ssl_opts.pop('ciphers', None)
-
-      if ssl_opts:
-        raise ValueError('Unknown keyword arguments: ', ' '.join(ssl_opts.keys()))
-
-      if self.cert_reqs != ssl.CERT_NONE:
-        if not self.ca_certs:
-          raise ValueError('ca_certs is needed when cert_reqs is not ssl.CERT_NONE')
-        if not os.access(self.ca_certs, os.R_OK):
-          raise IOError('Certificate Authority ca_certs file "%s" '
-                        'is not readable, cannot validate SSL '
-                        'certificates.' % (self.ca_certs))
-
-  @property
-  def certfile(self):
-    return self._certfile
-
-  @certfile.setter
-  def certfile(self, certfile):
-    if self._server_side and not certfile:
-      raise ValueError('certfile is needed for server-side')
-    if certfile and not os.access(certfile, os.R_OK):
-      raise IOError('No such certfile found: %s' % (certfile))
-    self._certfile = certfile
-
-  def _wrap_socket(self, sock):
-    if self._has_ssl_context:
-      if not self._custom_context:
-        self.ssl_context.verify_mode = self.cert_reqs
-        if self.certfile:
-          self.ssl_context.load_cert_chain(self.certfile, self.keyfile)
-        if self.ciphers:
-          self.ssl_context.set_ciphers(self.ciphers)
-        if self.ca_certs:
-          self.ssl_context.load_verify_locations(self.ca_certs)
-      return self.ssl_context.wrap_socket(sock, server_side=self._server_side,
-                                          server_hostname=self._server_hostname)
-    else:
-      ssl_opts = {
-        'ssl_version': self._ssl_version,
-        'server_side': self._server_side,
-        'ca_certs': self.ca_certs,
-        'keyfile': self.keyfile,
-        'certfile': self.certfile,
-        'cert_reqs': self.cert_reqs,
-      }
-      if self.ciphers:
-        if self._has_ciphers:
-          ssl_opts['ciphers'] = self.ciphers
+    def _deprecated_arg(self, args, kwargs, pos, key):
+        if len(args) <= pos:
+            return
+        real_pos = pos + 3
+        warnings.warn(
+            '%dth positional argument is deprecated. Use keyward argument insteand.' % real_pos,
+            DeprecationWarning)
+        if key in kwargs:
+            raise TypeError('Duplicate argument: %dth argument and %s keyward argument.', (real_pos, key))
+        kwargs[key] = args[pos]
+
+    def _unix_socket_arg(self, host, port, args, kwargs):
+        key = 'unix_socket'
+        if host is None and port is None and len(args) == 1 and key not in kwargs:
+            kwargs[key] = args[0]
+            return True
+        return False
+
+    def __getattr__(self, key):
+        if key == 'SSL_VERSION':
+            warnings.warn('Use ssl_version attribute instead.', DeprecationWarning)
+            return self.ssl_version
+
+    def __init__(self, server_side, host, ssl_opts):
+        self._server_side = server_side
+        if TSSLBase.SSL_VERSION != self._default_protocol:
+            warnings.warn('SSL_VERSION is deprecated. Use ssl_version keyward argument instead.', DeprecationWarning)
+        self._context = ssl_opts.pop('ssl_context', None)
+        self._server_hostname = None
+        if not self._server_side:
+            self._server_hostname = ssl_opts.pop('server_hostname', host)
+        if self._context:
+            self._custom_context = True
+            if ssl_opts:
+                raise ValueError('Incompatible arguments: ssl_context and %s' % ' '.join(ssl_opts.keys()))
+            if not self._has_ssl_context:
+                raise ValueError('ssl_context is not available for this version of Python')
+        else:
+            self._custom_context = False
+            ssl_version = ssl_opts.pop('ssl_version', TSSLBase.SSL_VERSION)
+            self._init_context(ssl_version)
+            self.cert_reqs = ssl_opts.pop('cert_reqs', ssl.CERT_REQUIRED)
+            self.ca_certs = ssl_opts.pop('ca_certs', None)
+            self.keyfile = ssl_opts.pop('keyfile', None)
+            self.certfile = ssl_opts.pop('certfile', None)
+            self.ciphers = ssl_opts.pop('ciphers', None)
+
+            if ssl_opts:
+                raise ValueError('Unknown keyword arguments: ', ' '.join(ssl_opts.keys()))
+
+            if self.cert_reqs != ssl.CERT_NONE:
+                if not self.ca_certs:
+                    raise ValueError('ca_certs is needed when cert_reqs is not ssl.CERT_NONE')
+                if not os.access(self.ca_certs, os.R_OK):
+                    raise IOError('Certificate Authority ca_certs file "%s" '
+                                  'is not readable, cannot validate SSL '
+                                  'certificates.' % (self.ca_certs))
+
+    @property
+    def certfile(self):
+        return self._certfile
+
+    @certfile.setter
+    def certfile(self, certfile):
+        if self._server_side and not certfile:
+            raise ValueError('certfile is needed for server-side')
+        if certfile and not os.access(certfile, os.R_OK):
+            raise IOError('No such certfile found: %s' % (certfile))
+        self._certfile = certfile
+
+    def _wrap_socket(self, sock):
+        if self._has_ssl_context:
+            if not self._custom_context:
+                self.ssl_context.verify_mode = self.cert_reqs
+                if self.certfile:
+                    self.ssl_context.load_cert_chain(self.certfile, self.keyfile)
+                if self.ciphers:
+                    self.ssl_context.set_ciphers(self.ciphers)
+                if self.ca_certs:
+                    self.ssl_context.load_verify_locations(self.ca_certs)
+            return self.ssl_context.wrap_socket(sock, server_side=self._server_side,
+                                                server_hostname=self._server_hostname)
         else:
-          logger.warning('ciphers is specified but ignored due to old Python version')
-      return ssl.wrap_socket(sock, **ssl_opts)
+            ssl_opts = {
+                'ssl_version': self._ssl_version,
+                'server_side': self._server_side,
+                'ca_certs': self.ca_certs,
+                'keyfile': self.keyfile,
+                'certfile': self.certfile,
+                'cert_reqs': self.cert_reqs,
+            }
+            if self.ciphers:
+                if self._has_ciphers:
+                    ssl_opts['ciphers'] = self.ciphers
+                else:
+                    logger.warning('ciphers is specified but ignored due to old Python version')
+            return ssl.wrap_socket(sock, **ssl_opts)
 
 
 class TSSLSocket(TSocket.TSocket, TSSLBase):
-  """
-  SSL implementation of TSocket
-
-  This class creates outbound sockets wrapped using the
-  python standard ssl module for encrypted connections.
-  """
+    """
+    SSL implementation of TSocket
 
-  # New signature
-  # def __init__(self, host='localhost', port=9090, unix_socket=None, **ssl_args):
-  # Deprecated signature
-  # def __init__(self, host='localhost', port=9090, validate=True, ca_certs=None, keyfile=None, certfile=None, unix_socket=None, ciphers=None):
-  def __init__(self, host='localhost', port=9090, *args, **kwargs):
-    """Positional arguments: ``host``, ``port``, ``unix_socket``
-
-    Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``,
-                       ``ca_certs``, ``ciphers`` (Python 2.7.0 or later),
-                       ``server_hostname`` (Python 2.7.9 or later)
-    Passed to ssl.wrap_socket. See ssl.wrap_socket documentation.
-
-    Alternative keywoard arguments: (Python 2.7.9 or later)
-      ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket
-      ``server_hostname``: Passed to SSLContext.wrap_socket
+    This class creates outbound sockets wrapped using the
+    python standard ssl module for encrypted connections.
     """
-    self.is_valid = False
-    self.peercert = None
-
-    if args:
-      if len(args) > 6:
-        raise TypeError('Too many positional argument')
-      if not self._unix_socket_arg(host, port, args, kwargs):
-        self._deprecated_arg(args, kwargs, 0, 'validate')
-      self._deprecated_arg(args, kwargs, 1, 'ca_certs')
-      self._deprecated_arg(args, kwargs, 2, 'keyfile')
-      self._deprecated_arg(args, kwargs, 3, 'certfile')
-      self._deprecated_arg(args, kwargs, 4, 'unix_socket')
-      self._deprecated_arg(args, kwargs, 5, 'ciphers')
-
-    validate = kwargs.pop('validate', None)
-    if validate is not None:
-      cert_reqs_name = 'CERT_REQUIRED' if validate else 'CERT_NONE'
-      warnings.warn(
-          'validate is deprecated. Use cert_reqs=ssl.%s instead' % cert_reqs_name,
-          DeprecationWarning)
-      if 'cert_reqs' in kwargs:
-        raise TypeError('Cannot specify both validate and cert_reqs')
-      kwargs['cert_reqs'] = ssl.CERT_REQUIRED if validate else ssl.CERT_NONE
-
-    unix_socket = kwargs.pop('unix_socket', None)
-    TSSLBase.__init__(self, False, host, kwargs)
-    TSocket.TSocket.__init__(self, host, port, unix_socket)
-
-  @property
-  def validate(self):
-    warnings.warn('Use cert_reqs instead', DeprecationWarning)
-    return self.cert_reqs != ssl.CERT_NONE
-
-  @validate.setter
-  def validate(self, value):
-    warnings.warn('Use cert_reqs instead', DeprecationWarning)
-    self.cert_reqs = ssl.CERT_REQUIRED if value else ssl.CERT_NONE
-
-  def open(self):
-    try:
-      res0 = self._resolveAddr()
-      for res in res0:
-        sock_family, sock_type = res[0:2]
-        ip_port = res[4]
-        plain_sock = socket.socket(sock_family, sock_type)
-        self.handle = self._wrap_socket(plain_sock)
-        self.handle.settimeout(self._timeout)
+
+    # New signature
+    # def __init__(self, host='localhost', port=9090, unix_socket=None, **ssl_args):
+    # Deprecated signature
+    # def __init__(self, host='localhost', port=9090, validate=True, ca_certs=None, keyfile=None, certfile=None, unix_socket=None, ciphers=None):
+    def __init__(self, host='localhost', port=9090, *args, **kwargs):
+        """Positional arguments: ``host``, ``port``, ``unix_socket``
+
+        Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``,
+                           ``ca_certs``, ``ciphers`` (Python 2.7.0 or later),
+                           ``server_hostname`` (Python 2.7.9 or later)
+        Passed to ssl.wrap_socket. See ssl.wrap_socket documentation.
+
+        Alternative keywoard arguments: (Python 2.7.9 or later)
+          ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket
+          ``server_hostname``: Passed to SSLContext.wrap_socket
+        """
+        self.is_valid = False
+        self.peercert = None
+
+        if args:
+            if len(args) > 6:
+                raise TypeError('Too many positional argument')
+            if not self._unix_socket_arg(host, port, args, kwargs):
+                self._deprecated_arg(args, kwargs, 0, 'validate')
+            self._deprecated_arg(args, kwargs, 1, 'ca_certs')
+            self._deprecated_arg(args, kwargs, 2, 'keyfile')
+            self._deprecated_arg(args, kwargs, 3, 'certfile')
+            self._deprecated_arg(args, kwargs, 4, 'unix_socket')
+            self._deprecated_arg(args, kwargs, 5, 'ciphers')
+
+        validate = kwargs.pop('validate', None)
+        if validate is not None:
+            cert_reqs_name = 'CERT_REQUIRED' if validate else 'CERT_NONE'
+            warnings.warn(
+                'validate is deprecated. Use cert_reqs=ssl.%s instead' % cert_reqs_name,
+                DeprecationWarning)
+            if 'cert_reqs' in kwargs:
+                raise TypeError('Cannot specify both validate and cert_reqs')
+            kwargs['cert_reqs'] = ssl.CERT_REQUIRED if validate else ssl.CERT_NONE
+
+        unix_socket = kwargs.pop('unix_socket', None)
+        TSSLBase.__init__(self, False, host, kwargs)
+        TSocket.TSocket.__init__(self, host, port, unix_socket)
+
+    @property
+    def validate(self):
+        warnings.warn('Use cert_reqs instead', DeprecationWarning)
+        return self.cert_reqs != ssl.CERT_NONE
+
+    @validate.setter
+    def validate(self, value):
+        warnings.warn('Use cert_reqs instead', DeprecationWarning)
+        self.cert_reqs = ssl.CERT_REQUIRED if value else ssl.CERT_NONE
+
+    def open(self):
         try:
-          self.handle.connect(ip_port)
+            res0 = self._resolveAddr()
+            for res in res0:
+                sock_family, sock_type = res[0:2]
+                ip_port = res[4]
+                plain_sock = socket.socket(sock_family, sock_type)
+                self.handle = self._wrap_socket(plain_sock)
+                self.handle.settimeout(self._timeout)
+                try:
+                    self.handle.connect(ip_port)
+                except socket.error as e:
+                    if res is not res0[-1]:
+                        logger.warning('Error while connecting with %s. Trying next one.', ip_port, exc_info=True)
+                        continue
+                    else:
+                        raise
+                break
         except socket.error as e:
-          if res is not res0[-1]:
-            logger.warning('Error while connecting with %s. Trying next one.', ip_port, exc_info=True)
-            continue
-          else:
-            raise
-        break
-    except socket.error as e:
-      if self._unix_socket:
-        message = 'Could not connect to secure socket %s: %s' \
-                  % (self._unix_socket, e)
-      else:
-        message = 'Could not connect to %s:%d: %s' % (self.host, self.port, e)
-      logger.error('Error while connecting with %s.', ip_port, exc_info=True)
-      raise TTransportException(type=TTransportException.NOT_OPEN,
-                                message=message)
-    if self.validate:
-      self._validate_cert()
-
-  def _validate_cert(self):
-    """internal method to validate the peer's SSL certificate, and to check the
-    commonName of the certificate to ensure it matches the hostname we
-    used to make this connection.  Does not support subjectAltName records
-    in certificates.
-
-    raises TTransportException if the certificate fails validation.
-    """
-    cert = self.handle.getpeercert()
-    self.peercert = cert
-    if 'subject' not in cert:
-      raise TTransportException(
-        type=TTransportException.NOT_OPEN,
-        message='No SSL certificate found from %s:%s' % (self.host, self.port))
-    fields = cert['subject']
-    for field in fields:
-      # ensure structure we get back is what we expect
-      if not isinstance(field, tuple):
-        continue
-      cert_pair = field[0]
-      if len(cert_pair) < 2:
-        continue
-      cert_key, cert_value = cert_pair[0:2]
-      if cert_key != 'commonName':
-        continue
-      certhost = cert_value
-      # this check should be performed by some sort of Access Manager
-      if certhost == self.host:
-        # success, cert commonName matches desired hostname
-        self.is_valid = True
-        return
-      else:
+            if self._unix_socket:
+                message = 'Could not connect to secure socket %s: %s' \
+                          % (self._unix_socket, e)
+            else:
+                message = 'Could not connect to %s:%d: %s' % (self.host, self.port, e)
+            logger.error('Error while connecting with %s.', ip_port, exc_info=True)
+            raise TTransportException(type=TTransportException.NOT_OPEN,
+                                      message=message)
+        if self.validate:
+            self._validate_cert()
+
+    def _validate_cert(self):
+        """internal method to validate the peer's SSL certificate, and to check the
+        commonName of the certificate to ensure it matches the hostname we
+        used to make this connection.  Does not support subjectAltName records
+        in certificates.
+
+        raises TTransportException if the certificate fails validation.
+        """
+        cert = self.handle.getpeercert()
+        self.peercert = cert
+        if 'subject' not in cert:
+            raise TTransportException(
+                type=TTransportException.NOT_OPEN,
+                message='No SSL certificate found from %s:%s' % (self.host, self.port))
+        fields = cert['subject']
+        for field in fields:
+            # ensure structure we get back is what we expect
+            if not isinstance(field, tuple):
+                continue
+            cert_pair = field[0]
+            if len(cert_pair) < 2:
+                continue
+            cert_key, cert_value = cert_pair[0:2]
+            if cert_key != 'commonName':
+                continue
+            certhost = cert_value
+            # this check should be performed by some sort of Access Manager
+            if certhost == self.host:
+                # success, cert commonName matches desired hostname
+                self.is_valid = True
+                return
+            else:
+                raise TTransportException(
+                    type=TTransportException.UNKNOWN,
+                    message='Hostname we connected to "%s" doesn\'t match certificate '
+                    'provided commonName "%s"' % (self.host, certhost))
         raise TTransportException(
-          type=TTransportException.UNKNOWN,
-          message='Hostname we connected to "%s" doesn\'t match certificate '
-                  'provided commonName "%s"' % (self.host, certhost))
-    raise TTransportException(
-      type=TTransportException.UNKNOWN,
-      message='Could not validate SSL certificate from '
-              'host "%s".  Cert=%s' % (self.host, cert))
+            type=TTransportException.UNKNOWN,
+            message='Could not validate SSL certificate from '
+            'host "%s".  Cert=%s' % (self.host, cert))
 
 
 class TSSLServerSocket(TSocket.TServerSocket, TSSLBase):
-  """SSL implementation of TServerSocket
-
-  This uses the ssl module's wrap_socket() method to provide SSL
-  negotiated encryption.
-  """
+    """SSL implementation of TServerSocket
 
-  # New signature
-  # def __init__(self, host='localhost', port=9090, unix_socket=None, **ssl_args):
-  # Deprecated signature
-  # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None):
-  def __init__(self, host=None, port=9090, *args, **kwargs):
-    """Positional arguments: ``host``, ``port``, ``unix_socket``
-
-    Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``,
-                       ``ca_certs``, ``ciphers`` (Python 2.7.0 or later)
-    See ssl.wrap_socket documentation.
-
-    Alternative keywoard arguments: (Python 2.7.9 or later)
-      ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket
-      ``server_hostname``: Passed to SSLContext.wrap_socket
-    """
-    if args:
-      if len(args) > 3:
-        raise TypeError('Too many positional argument')
-      if not self._unix_socket_arg(host, port, args, kwargs):
-        self._deprecated_arg(args, kwargs, 0, 'certfile')
-      self._deprecated_arg(args, kwargs, 1, 'unix_socket')
-      self._deprecated_arg(args, kwargs, 2, 'ciphers')
-
-    if 'ssl_context' not in kwargs:
-      # Preserve existing behaviors for default values
-      if 'cert_reqs' not in kwargs:
-        kwargs['cert_reqs'] = ssl.CERT_NONE
-      if'certfile' not in kwargs:
-        kwargs['certfile'] = 'cert.pem'
-
-    unix_socket = kwargs.pop('unix_socket', None)
-    TSSLBase.__init__(self, True, None, kwargs)
-    TSocket.TServerSocket.__init__(self, host, port, unix_socket)
-
-  def setCertfile(self, certfile):
-    """Set or change the server certificate file used to wrap new connections.
-
-    @param certfile: The filename of the server certificate,
-                     i.e. '/etc/certs/server.pem'
-    @type certfile: str
-
-    Raises an IOError exception if the certfile is not present or unreadable.
+    This uses the ssl module's wrap_socket() method to provide SSL
+    negotiated encryption.
     """
-    warnings.warn('Use certfile property instead.', DeprecationWarning)
-    self.certfile = certfile
-
-  def accept(self):
-    plain_client, addr = self.handle.accept()
-    try:
-      client = self._wrap_socket(plain_client)
-    except ssl.SSLError:
-      logger.error('Error while accepting from %s', addr, exc_info=True)
-      # failed handshake/ssl wrap, close socket to client
-      plain_client.close()
-      # raise
-      # We can't raise the exception, because it kills most TServer derived
-      # serve() methods.
-      # Instead, return None, and let the TServer instance deal with it in
-      # other exception handling.  (but TSimpleServer dies anyway)
-      return None
-    result = TSocket.TSocket()
-    result.setHandle(client)
-    return result
+
+    # New signature
+    # def __init__(self, host='localhost', port=9090, unix_socket=None, **ssl_args):
+    # Deprecated signature
+    # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None):
+    def __init__(self, host=None, port=9090, *args, **kwargs):
+        """Positional arguments: ``host``, ``port``, ``unix_socket``
+
+        Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``,
+                           ``ca_certs``, ``ciphers`` (Python 2.7.0 or later)
+        See ssl.wrap_socket documentation.
+
+        Alternative keywoard arguments: (Python 2.7.9 or later)
+          ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket
+          ``server_hostname``: Passed to SSLContext.wrap_socket
+        """
+        if args:
+            if len(args) > 3:
+                raise TypeError('Too many positional argument')
+            if not self._unix_socket_arg(host, port, args, kwargs):
+                self._deprecated_arg(args, kwargs, 0, 'certfile')
+            self._deprecated_arg(args, kwargs, 1, 'unix_socket')
+            self._deprecated_arg(args, kwargs, 2, 'ciphers')
+
+        if 'ssl_context' not in kwargs:
+            # Preserve existing behaviors for default values
+            if 'cert_reqs' not in kwargs:
+                kwargs['cert_reqs'] = ssl.CERT_NONE
+            if'certfile' not in kwargs:
+                kwargs['certfile'] = 'cert.pem'
+
+        unix_socket = kwargs.pop('unix_socket', None)
+        TSSLBase.__init__(self, True, None, kwargs)
+        TSocket.TServerSocket.__init__(self, host, port, unix_socket)
+
+    def setCertfile(self, certfile):
+        """Set or change the server certificate file used to wrap new connections.
+
+        @param certfile: The filename of the server certificate,
+                         i.e. '/etc/certs/server.pem'
+        @type certfile: str
+
+        Raises an IOError exception if the certfile is not present or unreadable.
+        """
+        warnings.warn('Use certfile property instead.', DeprecationWarning)
+        self.certfile = certfile
+
+    def accept(self):
+        plain_client, addr = self.handle.accept()
+        try:
+            client = self._wrap_socket(plain_client)
+        except ssl.SSLError:
+            logger.error('Error while accepting from %s', addr, exc_info=True)
+            # failed handshake/ssl wrap, close socket to client
+            plain_client.close()
+            # raise
+            # We can't raise the exception, because it kills most TServer derived
+            # serve() methods.
+            # Instead, return None, and let the TServer instance deal with it in
+            # other exception handling.  (but TSimpleServer dies anyway)
+            return None
+        result = TSocket.TSocket()
+        result.setHandle(client)
+        return result

http://git-wip-us.apache.org/repos/asf/thrift/blob/10308cb9/lib/py/src/transport/TSocket.py
----------------------------------------------------------------------
diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py
index cb204a4..a8ed4b7 100644
--- a/lib/py/src/transport/TSocket.py
+++ b/lib/py/src/transport/TSocket.py
@@ -22,159 +22,159 @@ import os
 import socket
 import sys
 
-from .TTransport import *
+from .TTransport import TTransportBase, TTransportException, TServerTransportBase
 
 
 class TSocketBase(TTransportBase):
-  def _resolveAddr(self):
-    if self._unix_socket is not None:
-      return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None,
-               self._unix_socket)]
-    else:
-      return socket.getaddrinfo(self.host,
-                                self.port,
-                                self._socket_family,
-                                socket.SOCK_STREAM,
-                                0,
-                                socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
-
-  def close(self):
-    if self.handle:
-      self.handle.close()
-      self.handle = None
+    def _resolveAddr(self):
+        if self._unix_socket is not None:
+            return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None,
+                     self._unix_socket)]
+        else:
+            return socket.getaddrinfo(self.host,
+                                      self.port,
+                                      self._socket_family,
+                                      socket.SOCK_STREAM,
+                                      0,
+                                      socket.AI_PASSIVE | socket.AI_ADDRCONFIG)
+
+    def close(self):
+        if self.handle:
+            self.handle.close()
+            self.handle = None
 
 
 class TSocket(TSocketBase):
-  """Socket implementation of TTransport base."""
-
-  def __init__(self, host='localhost', port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC):
-    """Initialize a TSocket
-
-    @param host(str)  The host to connect to.
-    @param port(int)  The (TCP) port to connect to.
-    @param unix_socket(str)  The filename of a unix socket to connect to.
-                             (host and port will be ignored.)
-    @param socket_family(int)  The socket family to use with this socket.
-    """
-    self.host = host
-    self.port = port
-    self.handle = None
-    self._unix_socket = unix_socket
-    self._timeout = None
-    self._socket_family = socket_family
-
-  def setHandle(self, h):
-    self.handle = h
-
-  def isOpen(self):
-    return self.handle is not None
-
-  def setTimeout(self, ms):
-    if ms is None:
-      self._timeout = None
-    else:
-      self._timeout = ms / 1000.0
-
-    if self.handle is not None:
-      self.handle.settimeout(self._timeout)
-
-  def open(self):
-    try:
-      res0 = self._resolveAddr()
-      for res in res0:
-        self.handle = socket.socket(res[0], res[1])
-        self.handle.settimeout(self._timeout)
+    """Socket implementation of TTransport base."""
+
+    def __init__(self, host='localhost', port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC):
+        """Initialize a TSocket
+
+        @param host(str)  The host to connect to.
+        @param port(int)  The (TCP) port to connect to.
+        @param unix_socket(str)  The filename of a unix socket to connect to.
+                                 (host and port will be ignored.)
+        @param socket_family(int)  The socket family to use with this socket.
+        """
+        self.host = host
+        self.port = port
+        self.handle = None
+        self._unix_socket = unix_socket
+        self._timeout = None
+        self._socket_family = socket_family
+
+    def setHandle(self, h):
+        self.handle = h
+
+    def isOpen(self):
+        return self.handle is not None
+
+    def setTimeout(self, ms):
+        if ms is None:
+            self._timeout = None
+        else:
+            self._timeout = ms / 1000.0
+
+        if self.handle is not None:
+            self.handle.settimeout(self._timeout)
+
+    def open(self):
+        try:
+            res0 = self._resolveAddr()
+            for res in res0:
+                self.handle = socket.socket(res[0], res[1])
+                self.handle.settimeout(self._timeout)
+                try:
+                    self.handle.connect(res[4])
+                except socket.error as e:
+                    if res is not res0[-1]:
+                        continue
+                    else:
+                        raise e
+                break
+        except socket.error as e:
+            if self._unix_socket:
+                message = 'Could not connect to socket %s' % self._unix_socket
+            else:
+                message = 'Could not connect to %s:%d' % (self.host, self.port)
+            raise TTransportException(type=TTransportException.NOT_OPEN,
+                                      message=message)
+
+    def read(self, sz):
         try:
-          self.handle.connect(res[4])
+            buff = self.handle.recv(sz)
         except socket.error as e:
-          if res is not res0[-1]:
-            continue
-          else:
-            raise e
-        break
-    except socket.error as e:
-      if self._unix_socket:
-        message = 'Could not connect to socket %s' % self._unix_socket
-      else:
-        message = 'Could not connect to %s:%d' % (self.host, self.port)
-      raise TTransportException(type=TTransportException.NOT_OPEN,
-                                message=message)
-
-  def read(self, sz):
-    try:
-      buff = self.handle.recv(sz)
-    except socket.error as e:
-      if (e.args[0] == errno.ECONNRESET and
-          (sys.platform == 'darwin' or sys.platform.startswith('freebsd'))):
-        # freebsd and Mach don't follow POSIX semantic of recv
-        # and fail with ECONNRESET if peer performed shutdown.
-        # See corresponding comment and code in TSocket::read()
-        # in lib/cpp/src/transport/TSocket.cpp.
-        self.close()
-        # Trigger the check to raise the END_OF_FILE exception below.
-        buff = ''
-      else:
-        raise
-    if len(buff) == 0:
-      raise TTransportException(type=TTransportException.END_OF_FILE,
-                                message='TSocket read 0 bytes')
-    return buff
-
-  def write(self, buff):
-    if not self.handle:
-      raise TTransportException(type=TTransportException.NOT_OPEN,
-                                message='Transport not open')
-    sent = 0
-    have = len(buff)
-    while sent < have:
-      plus = self.handle.send(buff)
-      if plus == 0:
-        raise TTransportException(type=TTransportException.END_OF_FILE,
-                                  message='TSocket sent 0 bytes')
-      sent += plus
-      buff = buff[plus:]
-
-  def flush(self):
-    pass
+            if (e.args[0] == errno.ECONNRESET and
+                    (sys.platform == 'darwin' or sys.platform.startswith('freebsd'))):
+                # freebsd and Mach don't follow POSIX semantic of recv
+                # and fail with ECONNRESET if peer performed shutdown.
+                # See corresponding comment and code in TSocket::read()
+                # in lib/cpp/src/transport/TSocket.cpp.
+                self.close()
+                # Trigger the check to raise the END_OF_FILE exception below.
+                buff = ''
+            else:
+                raise
+        if len(buff) == 0:
+            raise TTransportException(type=TTransportException.END_OF_FILE,
+                                      message='TSocket read 0 bytes')
+        return buff
+
+    def write(self, buff):
+        if not self.handle:
+            raise TTransportException(type=TTransportException.NOT_OPEN,
+                                      message='Transport not open')
+        sent = 0
+        have = len(buff)
+        while sent < have:
+            plus = self.handle.send(buff)
+            if plus == 0:
+                raise TTransportException(type=TTransportException.END_OF_FILE,
+                                          message='TSocket sent 0 bytes')
+            sent += plus
+            buff = buff[plus:]
+
+    def flush(self):
+        pass
 
 
 class TServerSocket(TSocketBase, TServerTransportBase):
-  """Socket implementation of TServerTransport base."""
-
-  def __init__(self, host=None, port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC):
-    self.host = host
-    self.port = port
-    self._unix_socket = unix_socket
-    self._socket_family = socket_family
-    self.handle = None
-
-  def listen(self):
-    res0 = self._resolveAddr()
-    socket_family = self._socket_family == socket.AF_UNSPEC and socket.AF_INET6 or self._socket_family
-    for res in res0:
-      if res[0] is socket_family or res is res0[-1]:
-        break
-
-    # We need remove the old unix socket if the file exists and
-    # nobody is listening on it.
-    if self._unix_socket:
-      tmp = socket.socket(res[0], res[1])
-      try:
-        tmp.connect(res[4])
-      except socket.error as err:
-        eno, message = err.args
-        if eno == errno.ECONNREFUSED:
-          os.unlink(res[4])
-
-    self.handle = socket.socket(res[0], res[1])
-    self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-    if hasattr(self.handle, 'settimeout'):
-      self.handle.settimeout(None)
-    self.handle.bind(res[4])
-    self.handle.listen(128)
-
-  def accept(self):
-    client, addr = self.handle.accept()
-    result = TSocket()
-    result.setHandle(client)
-    return result
+    """Socket implementation of TServerTransport base."""
+
+    def __init__(self, host=None, port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC):
+        self.host = host
+        self.port = port
+        self._unix_socket = unix_socket
+        self._socket_family = socket_family
+        self.handle = None
+
+    def listen(self):
+        res0 = self._resolveAddr()
+        socket_family = self._socket_family == socket.AF_UNSPEC and socket.AF_INET6 or self._socket_family
+        for res in res0:
+            if res[0] is socket_family or res is res0[-1]:
+                break
+
+        # We need remove the old unix socket if the file exists and
+        # nobody is listening on it.
+        if self._unix_socket:
+            tmp = socket.socket(res[0], res[1])
+            try:
+                tmp.connect(res[4])
+            except socket.error as err:
+                eno, message = err.args
+                if eno == errno.ECONNREFUSED:
+                    os.unlink(res[4])
+
+        self.handle = socket.socket(res[0], res[1])
+        self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        if hasattr(self.handle, 'settimeout'):
+            self.handle.settimeout(None)
+        self.handle.bind(res[4])
+        self.handle.listen(128)
+
+    def accept(self):
+        client, addr = self.handle.accept()
+        result = TSocket()
+        result.setHandle(client)
+        return result