Thrift: Handle absence of fastbinary.so

Summary:
- Wrap import of fastbinary in a try/catch, setting it to None if it fails.
- Don't try to fastbinary.encode/decode if fastbinary is None.
- Always generate thrift_spec, even if it is None.
- Don't try to fastbinary.encode/decode if thrift_spec is None.

Reviewed By: mcslee

Test Plan:
test/py/Test{Client,Server}.py
Manually delete my fastbinary.so, they worked fine.
Changed them to use Accelerated protocol.  They still worked fine because
the test falls through to the normal generated code.
Installed fastbinary.so, everything worked fine (eventually).

Revert Plan: ok


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665236 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
David Reiss 2007-08-30 23:07:45 +00:00
parent 792df0bf78
commit 5db3e92671
4 changed files with 48 additions and 23 deletions

View File

@ -67,9 +67,8 @@ void t_py_generator::init_generator() {
py_autogen_comment() << endl <<
py_imports() << endl <<
render_includes() << endl <<
"from thrift.transport import TTransport" << endl <<
"from thrift.protocol import fastbinary" << endl <<
"from thrift.protocol import TBinaryProtocol" << endl << endl << endl;
render_fastbinary_includes() <<
endl << endl;
f_consts_ <<
py_autogen_comment() << endl <<
@ -93,6 +92,19 @@ string t_py_generator::render_includes() {
return result;
}
/**
* Renders all the imports necessary to use the accelerated TBinaryProtocol
*/
string t_py_generator::render_fastbinary_includes() {
return
"from thrift.transport import TTransport\n"
"from thrift.protocol import TBinaryProtocol\n"
"try:\n"
" from thrift.protocol import fastbinary\n"
"except:\n"
" fastbinary = None\n";
}
/**
* Autogen'd comment
*/
@ -361,6 +373,10 @@ void t_py_generator::generate_py_struct_definition(ofstream& out,
TODO(dreiss): Consider making this work for structs with negative tags.
*/
// TODO(dreiss): Look into generating an empty tuple instead of None
// for structures with no members.
// TODO(dreiss): Test encoding of structs where some inner structs
// don't have thrift_spec.
if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) {
indent(out) << "thrift_spec = (" << endl;
indent_up();
@ -386,8 +402,11 @@ void t_py_generator::generate_py_struct_definition(ofstream& out,
indent_down();
indent(out) << ")" << endl << endl;
} else {
indent(out) << "thrift_spec = None" << endl;
}
out <<
indent() << "def __init__(self, d=None):" << endl;
indent_up();
@ -466,7 +485,9 @@ void t_py_generator::generate_py_struct_reader(ofstream& out,
indent(out) <<
"if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated "
"and isinstance(iprot.trans, TTransport.CReadableTransport):" << endl;
"and isinstance(iprot.trans, TTransport.CReadableTransport) "
"and self.thrift_spec is not None "
"and fastbinary is not None:" << endl;
indent_up();
indent(out) <<
@ -549,7 +570,9 @@ void t_py_generator::generate_py_struct_writer(ofstream& out,
indent_up();
indent(out) <<
"if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:" << endl;
"if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated "
"and self.thrift_spec is not None "
"and fastbinary is not None:" << endl;
indent_up();
indent(out) <<
@ -614,10 +637,8 @@ void t_py_generator::generate_service(t_service* tservice) {
f_service_ <<
"from ttypes import *" << endl <<
"from thrift.Thrift import TProcessor" << endl <<
"from thrift.transport import TTransport" << endl <<
"from thrift.protocol import fastbinary" << endl <<
"from thrift.protocol import TBinaryProtocol" << endl <<
endl;
render_fastbinary_includes() <<
endl << endl;
// Generate the three main parts of the service (well, two for now in PHP)
generate_service_interface(tservice);

View File

@ -128,6 +128,7 @@ class t_py_generator : public t_generator {
std::string py_autogen_comment();
std::string py_imports();
std::string render_includes();
std::string render_fastbinary_includes();
std::string declare_field(t_field* tfield);
std::string type_name(t_type* ttype);
std::string function_signature(t_function* tfunction, std::string prefix="");

View File

@ -219,7 +219,7 @@ class TBinaryProtocolAccelerated(TBinaryProtocol):
our C module to do the encoding, bypassing this object entirely.
We inherit from TBinaryProtocol so that the normal TBinaryProtocol
encoding can happen if the fastbinary module doesn't work for some
reason. (TODO(dreiss): Make this happen sanely.)
reason. (TODO(dreiss): Make this happen sanely in more cases.)
In order to take advantage of the C module, just use
TBinaryProtocolAccelerated instead of TBinaryProtocol.

View File

@ -7,8 +7,11 @@
from thrift.Thrift import *
from thrift.transport import TTransport
from thrift.protocol import fastbinary
from thrift.protocol import TBinaryProtocol
try:
from thrift.protocol import fastbinary
except:
fastbinary = None
class TTypeTag:
@ -45,7 +48,7 @@ class SimpleType:
self.name = d['name']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -69,7 +72,7 @@ class SimpleType:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('SimpleType')
@ -118,7 +121,7 @@ class ContainerType:
self.subtype2 = d['subtype2']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -149,7 +152,7 @@ class ContainerType:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('ContainerType')
@ -202,7 +205,7 @@ class ThriftType:
self.container_type = d['container_type']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -233,7 +236,7 @@ class ThriftType:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('ThriftType')
@ -286,7 +289,7 @@ class Argument:
self.type = d['type']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -316,7 +319,7 @@ class Argument:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('Argument')
@ -369,7 +372,7 @@ class Method:
self.arguments = d['arguments']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -405,7 +408,7 @@ class Method:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('Method')
@ -461,7 +464,7 @@ class Service:
self.fully_reflected = d['fully_reflected']
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
@ -496,7 +499,7 @@ class Service:
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated:
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('Service')