Python generator to make __str__ and __repr__ methods for generated structs
Summary: Also generate a nice command line -remote utility like pillar
Reviewed By: ccheever
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664816 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc
index 86c2bd0..dec0265 100644
--- a/compiler/cpp/src/generate/t_py_generator.cc
+++ b/compiler/cpp/src/generate/t_py_generator.cc
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <sstream>
#include "t_py_generator.h"
using namespace std;
@@ -165,6 +166,14 @@
generate_py_struct_writer(out, tstruct);
}
+ out <<
+ indent() << "def __str__(self): " << endl <<
+ indent() << " return str(self.__dict__)" << endl <<
+ endl <<
+ indent() << "def __repr__(self): " << endl <<
+ indent() << " return repr(self.__dict__)" << endl <<
+ endl;
+
indent_down();
}
@@ -340,7 +349,8 @@
generate_service_client(tservice);
generate_service_helpers(tservice);
generate_service_server(tservice);
-
+ generate_service_remote(tservice);
+
// Close service file
f_service_ << endl;
f_service_.close();
@@ -560,6 +570,143 @@
}
/**
+ * Generates a command line tool for making remote requests
+ *
+ * @param tservice The service to generate a remote for.
+ */
+void t_py_generator::generate_service_remote(t_service* tservice) {
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ string f_remote_name = string(T_PY_DIR)+"/"+service_name_+"-remote";
+ ofstream f_remote;
+ f_remote.open(f_remote_name.c_str());
+
+ f_remote <<
+ "#!/usr/bin/python" << endl <<
+ py_autogen_comment() << endl <<
+ "import sys" << endl <<
+ "import pprint" << endl <<
+ "from thrift.transport import TTransport" << endl <<
+ "from thrift.transport import TSocket" << endl <<
+ "from thrift.protocol import TBinaryProtocol" << endl <<
+ endl;
+
+ f_remote <<
+ "import " << service_name_ << endl <<
+ "from " << program_name_ << "_types import *" << endl <<
+ endl;
+
+ f_remote <<
+ "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << endl <<
+ " print ''" << endl <<
+ " print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-f[ramed]] function [arg1,[arg2...]]'" << endl <<
+ " print ''" << endl <<
+ " print 'Functions:'" << endl;
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ f_remote <<
+ " print ' " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "(";
+ t_struct* arg_struct = (*f_iter)->get_arglist();
+ const std::vector<t_field*>& args = arg_struct->get_members();
+ vector<t_field*>::const_iterator a_iter;
+ int num_args = args.size();
+ bool first = true;
+ for (int i = 0; i < num_args; ++i) {
+ if (first) {
+ first = false;
+ } else {
+ f_remote << ", ";
+ }
+ f_remote <<
+ args[i]->get_type()->get_name() << " " << args[i]->get_name();
+ }
+ f_remote << ")'" << endl;
+ }
+ f_remote <<
+ " print ''" << endl <<
+ " sys.exit(0)" << endl <<
+ endl;
+
+ f_remote <<
+ "pp = pprint.PrettyPrinter(indent = 2)" << endl <<
+ "host = 'localhost'" << endl <<
+ "port = 9190" << endl <<
+ "framed = False" << endl <<
+ "argi = 1" << endl <<
+ endl <<
+ "if sys.argv[1] == '-h':" << endl <<
+ " parts = sys.argv[2].split(':') " << endl <<
+ " host = parts[0]" << endl <<
+ " port = int(parts[1])" << endl <<
+ " argi = 3" << endl <<
+ endl <<
+ "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << endl <<
+ " framed = True" << endl <<
+ " argi += 1" << endl <<
+ endl <<
+ "cmd = sys.argv[argi]" << endl <<
+ "args = sys.argv[argi+1:]" << endl <<
+ endl <<
+ "socket = TSocket.TSocket(host, port)" << endl <<
+ "if framed:" << endl <<
+ " transport = TTransport.TFramedTransport(socket)" << endl <<
+ "else:" << endl <<
+ " transport = TTransport.TBufferedTransport(socket)" << endl <<
+ "protocol = TBinaryProtocol.TBinaryProtocol()" << endl <<
+ "client = " << service_name_ << ".Client(transport, protocol)" << endl <<
+ "transport.open()" << endl <<
+ endl;
+
+ // Generate the dispatch methods
+ bool first = true;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ if (first) {
+ first = false;
+ } else {
+ f_remote << "el";
+ }
+
+ t_struct* arg_struct = (*f_iter)->get_arglist();
+ const std::vector<t_field*>& args = arg_struct->get_members();
+ vector<t_field*>::const_iterator a_iter;
+ int num_args = args.size();
+
+ f_remote <<
+ "if cmd == '" << (*f_iter)->get_name() << "':" << endl <<
+ " if len(args) != " << num_args << ":" << endl <<
+ " print '" << (*f_iter)->get_name() << " requires " << num_args << " args'" << endl <<
+ " sys.exit(1)" << endl <<
+ " pp.pprint(client." << (*f_iter)->get_name() << "(";
+ for (int i = 0; i < num_args; ++i) {
+ if (args[i]->get_type()->is_struct()) {
+ f_remote << "eval(args[" << i << "]),";
+ } else {
+ f_remote << "args[" << i << "],";
+ }
+ }
+ f_remote << "))" << endl;
+
+ f_remote << endl;
+ }
+
+ f_remote << "transport.close()" << endl;
+
+ // Close service file
+ f_remote.close();
+
+ // Make file executable
+ chmod(f_remote_name.c_str(),
+ S_IRUSR |
+ S_IWUSR |
+ S_IXUSR |
+ S_IRGRP |
+ S_IXGRP |
+ S_IROTH |
+ S_IXOTH);
+}
+
+/**
* Generates a service server definition.
*
* @param tservice The service to generate a server for.
@@ -1146,18 +1293,18 @@
if (ttype->is_base_type()) {
return base_type_name(((t_base_type*)ttype)->get_base());
} else if (ttype->is_enum()) {
- return "Int32";
+ return "int";
} else if (ttype->is_map()) {
t_map* tmap = (t_map*) ttype;
- return "HashMap<" +
+ return "map<" +
type_name(tmap->get_key_type()) + "," +
type_name(tmap->get_val_type()) + ">";
} else if (ttype->is_set()) {
t_set* tset = (t_set*) ttype;
- return "HashSet<" + type_name(tset->get_elem_type()) + ">";
+ return "set<" + type_name(tset->get_elem_type()) + ">";
} else if (ttype->is_list()) {
t_list* tlist = (t_list*) ttype;
- return "ArrayList<" + type_name(tlist->get_elem_type()) + ">";
+ return "list<" + type_name(tlist->get_elem_type()) + ">";
} else {
return ttype->get_name();
}
diff --git a/compiler/cpp/src/generate/t_py_generator.h b/compiler/cpp/src/generate/t_py_generator.h
index f68a121..2f6c6ce 100644
--- a/compiler/cpp/src/generate/t_py_generator.h
+++ b/compiler/cpp/src/generate/t_py_generator.h
@@ -45,8 +45,10 @@
/** Service-level generation functions */
void generate_service_helpers(t_service* tservice);
- void generate_service_interface (t_service* tservice);
- void generate_service_client (t_service* tservice);
+ void generate_service_interface(t_service* tservice);
+ void generate_service_client(t_service* tservice);
+ void generate_service_remote(t_service* tservice);
+
void generate_service_server (t_service* tservice);
void generate_process_function (t_service* tservice, t_function* tfunction);