THRIFT-4548: python binary accelerated protocol with multiplexing via decoration (#1547)

* Fix binary accelerated protocol with multiplexing

TMultiplexedProtocol objects did not inherit from TProtocol, so the
decorated protocol object passed into the binary accelerated C extension
was not really a TProtocol object, which caused errors. This
implementation decorates the protocol object by dynamically creating a
new class that extends both the class of the protocol being decorated
and TMultiplexedProtocol.

* THRIFT-4548: remove known failures for py multiplexed client cross tests

* Call super with args for python2 & pep8 fixes

* THRIFT-3877: disable known failures for http cpp tests

This closes #1535 
diff --git a/lib/py/src/TMultiplexedProcessor.py b/lib/py/src/TMultiplexedProcessor.py
index 7d60347..3ac5af0 100644
--- a/lib/py/src/TMultiplexedProcessor.py
+++ b/lib/py/src/TMultiplexedProcessor.py
@@ -48,7 +48,6 @@
 
 class StoredMessageProtocol(TProtocolDecorator.TProtocolDecorator):
     def __init__(self, protocol, messageBegin):
-        TProtocolDecorator.TProtocolDecorator.__init__(self, protocol)
         self.messageBegin = messageBegin
 
     def readMessageBegin(self):
diff --git a/lib/py/src/protocol/TMultiplexedProtocol.py b/lib/py/src/protocol/TMultiplexedProtocol.py
index 309f896..0f8390f 100644
--- a/lib/py/src/protocol/TMultiplexedProtocol.py
+++ b/lib/py/src/protocol/TMultiplexedProtocol.py
@@ -25,16 +25,15 @@
 
 class TMultiplexedProtocol(TProtocolDecorator.TProtocolDecorator):
     def __init__(self, protocol, serviceName):
-        TProtocolDecorator.TProtocolDecorator.__init__(self, protocol)
         self.serviceName = serviceName
 
     def writeMessageBegin(self, name, type, seqid):
         if (type == TMessageType.CALL or
                 type == TMessageType.ONEWAY):
-            self.protocol.writeMessageBegin(
+            super(TMultiplexedProtocol, self).writeMessageBegin(
                 self.serviceName + SEPARATOR + name,
                 type,
                 seqid
             )
         else:
-            self.protocol.writeMessageBegin(name, type, seqid)
+            super(TMultiplexedProtocol, self).writeMessageBegin(name, type, seqid)
diff --git a/lib/py/src/protocol/TProtocolDecorator.py b/lib/py/src/protocol/TProtocolDecorator.py
index 8b270a4..f5546c7 100644
--- a/lib/py/src/protocol/TProtocolDecorator.py
+++ b/lib/py/src/protocol/TProtocolDecorator.py
@@ -17,34 +17,10 @@
 # under the License.
 #
 
-import types
 
-from thrift.protocol.TProtocol import TProtocolBase
-
-
-class TProtocolDecorator():
-    def __init__(self, protocol):
-        TProtocolBase(protocol)
-        self.protocol = protocol
-
-    def __getattr__(self, name):
-        if hasattr(self.protocol, name):
-            member = getattr(self.protocol, name)
-            if type(member) in [
-                types.MethodType,
-                types.FunctionType,
-                types.LambdaType,
-                types.BuiltinFunctionType,
-                types.BuiltinMethodType,
-            ]:
-                return lambda *args, **kwargs: self._wrap(member, args, kwargs)
-            else:
-                return member
-        raise AttributeError(name)
-
-    def _wrap(self, func, args, kwargs):
-        if isinstance(func, types.MethodType):
-            result = func(*args, **kwargs)
-        else:
-            result = func(self.protocol, *args, **kwargs)
-        return result
+class TProtocolDecorator(object):
+    def __new__(cls, protocol, *args, **kwargs):
+        decorated_cls = type(''.join(['Decorated', protocol.__class__.__name__]),
+                             (cls, protocol.__class__),
+                             protocol.__dict__)
+        return object.__new__(decorated_cls)
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index 3212f7e..cd83bd5 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -1,12 +1,4 @@
 [
-  "c_glib-py3_multi-multia_buffered-ip",
-  "c_glib-py3_multi-multia_framed-ip",
-  "c_glib-py3_multic-multiac_buffered-ip",
-  "c_glib-py3_multic-multiac_framed-ip",
-  "c_glib-py_multi-multia_buffered-ip",
-  "c_glib-py_multi-multia_framed-ip",
-  "c_glib-py_multic-multiac_buffered-ip",
-  "c_glib-py_multic-multiac_framed-ip",
   "c_glib-rs_multi_buffered-ip",
   "c_glib-rs_multi_framed-ip",
   "c_glib-rs_multic_buffered-ip",
@@ -19,10 +11,6 @@
   "cl-c_glib_multi_framed-ip",
   "cl-go_binary_buffered-ip",
   "cl-go_binary_framed-ip",
-  "cl-py3_multi-multia_buffered-ip",
-  "cl-py3_multi-multia_framed-ip",
-  "cl-py_multi-multia_buffered-ip",
-  "cl-py_multi-multia_framed-ip",
   "cl-rb_binary-accel_buffered-ip",
   "cl-rb_binary-accel_framed-ip",
   "cl-rb_binary_buffered-ip",
@@ -101,10 +89,6 @@
   "cpp-py3_multi-accel_http-ip-ssl",
   "cpp-py3_multi-binary_http-ip",
   "cpp-py3_multi-binary_http-ip-ssl",
-  "cpp-py3_multi-multia_buffered-ip",
-  "cpp-py3_multi-multia_buffered-ip-ssl",
-  "cpp-py3_multi-multia_framed-ip",
-  "cpp-py3_multi-multia_framed-ip-ssl",
   "cpp-py3_multi-multia_http-ip",
   "cpp-py3_multi-multia_http-ip-ssl",
   "cpp-py3_multi_http-ip",
@@ -113,10 +97,6 @@
   "cpp-py3_multic-accelc_http-ip-ssl",
   "cpp-py3_multic-compact_http-ip",
   "cpp-py3_multic-compact_http-ip-ssl",
-  "cpp-py3_multic-multiac_buffered-ip",
-  "cpp-py3_multic-multiac_buffered-ip-ssl",
-  "cpp-py3_multic-multiac_framed-ip",
-  "cpp-py3_multic-multiac_framed-ip-ssl",
   "cpp-py3_multic-multiac_http-ip",
   "cpp-py3_multic-multiac_http-ip-ssl",
   "cpp-py3_multic_http-ip",
@@ -139,10 +119,6 @@
   "cpp-py_multi-accel_http-ip-ssl",
   "cpp-py_multi-binary_http-ip",
   "cpp-py_multi-binary_http-ip-ssl",
-  "cpp-py_multi-multia_buffered-ip",
-  "cpp-py_multi-multia_buffered-ip-ssl",
-  "cpp-py_multi-multia_framed-ip",
-  "cpp-py_multi-multia_framed-ip-ssl",
   "cpp-py_multi-multia_http-ip",
   "cpp-py_multi-multia_http-ip-ssl",
   "cpp-py_multi_http-ip",
@@ -151,10 +127,6 @@
   "cpp-py_multic-accelc_http-ip-ssl",
   "cpp-py_multic-compact_http-ip",
   "cpp-py_multic-compact_http-ip-ssl",
-  "cpp-py_multic-multiac_buffered-ip",
-  "cpp-py_multic-multiac_buffered-ip-ssl",
-  "cpp-py_multic-multiac_framed-ip",
-  "cpp-py_multic-multiac_framed-ip-ssl",
   "cpp-py_multic-multiac_http-ip",
   "cpp-py_multic-multiac_http-ip-ssl",
   "cpp-py_multic_http-ip",
@@ -335,30 +307,6 @@
   "hs-csharp_binary_framed-ip",
   "hs-csharp_compact_buffered-ip",
   "hs-csharp_compact_framed-ip",
-  "java-py3_multi-multia_buffered-ip",
-  "java-py3_multi-multia_buffered-ip-ssl",
-  "java-py3_multi-multia_fastframed-framed-ip",
-  "java-py3_multi-multia_fastframed-framed-ip-ssl",
-  "java-py3_multi-multia_framed-ip",
-  "java-py3_multi-multia_framed-ip-ssl",
-  "java-py3_multic-multiac_buffered-ip",
-  "java-py3_multic-multiac_buffered-ip-ssl",
-  "java-py3_multic-multiac_fastframed-framed-ip",
-  "java-py3_multic-multiac_fastframed-framed-ip-ssl",
-  "java-py3_multic-multiac_framed-ip",
-  "java-py3_multic-multiac_framed-ip-ssl",
-  "java-py_multi-multia_buffered-ip",
-  "java-py_multi-multia_buffered-ip-ssl",
-  "java-py_multi-multia_fastframed-framed-ip",
-  "java-py_multi-multia_fastframed-framed-ip-ssl",
-  "java-py_multi-multia_framed-ip",
-  "java-py_multi-multia_framed-ip-ssl",
-  "java-py_multic-multiac_buffered-ip",
-  "java-py_multic-multiac_buffered-ip-ssl",
-  "java-py_multic-multiac_fastframed-framed-ip",
-  "java-py_multic-multiac_fastframed-framed-ip-ssl",
-  "java-py_multic-multiac_framed-ip",
-  "java-py_multic-multiac_framed-ip-ssl",
   "nodejs-cpp_binary_http-domain",
   "nodejs-cpp_binary_http-ip",
   "nodejs-cpp_binary_http-ip-ssl",
@@ -416,14 +364,6 @@
   "nodejs-py_compact_http-ip-ssl",
   "nodejs-py_json_http-ip",
   "nodejs-py_json_http-ip-ssl",
-  "perl-py3_multi-multia_buffered-ip",
-  "perl-py3_multi-multia_buffered-ip-ssl",
-  "perl-py3_multi-multia_framed-ip",
-  "perl-py3_multi-multia_framed-ip-ssl",
-  "perl-py_multi-multia_buffered-ip",
-  "perl-py_multi-multia_buffered-ip-ssl",
-  "perl-py_multi-multia_framed-ip",
-  "perl-py_multi-multia_framed-ip-ssl",
   "perl-rs_multi_buffered-ip",
   "perl-rs_multi_framed-ip",
   "py-cpp_accel-binary_http-ip",
@@ -521,13 +461,5 @@
   "rb-cpp_json_buffered-ip-ssl",
   "rb-cpp_json_framed-domain",
   "rb-cpp_json_framed-ip",
-  "rb-cpp_json_framed-ip-ssl",
-  "rs-py3_multi-multia_buffered-ip",
-  "rs-py3_multi-multia_framed-ip",
-  "rs-py3_multic-multiac_buffered-ip",
-  "rs-py3_multic-multiac_framed-ip",
-  "rs-py_multi-multia_buffered-ip",
-  "rs-py_multi-multia_framed-ip",
-  "rs-py_multic-multiac_buffered-ip",
-  "rs-py_multic-multiac_framed-ip"
+  "rb-cpp_json_framed-ip-ssl"
 ]