Review comments
- Update flag description to be more precise
- No implict enum generation (gen enum flag required)
- Use latest thrift test IDL for uuid coverage
- rebase on latest main
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index ddca9fe..90bfd05 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -17,21 +17,21 @@
* under the License.
*/
+#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
-#include <string>
#include <vector>
-#include "thrift/generate/t_generator.h"
-#include "thrift/platform.h"
-#include "thrift/version.h"
-#include <algorithm>
-#include <sstream>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sstream>
+#include <algorithm>
+#include "thrift/platform.h"
+#include "thrift/version.h"
+#include "thrift/generate/t_generator.h"
using std::map;
using std::ostream;
@@ -49,7 +49,7 @@
t_py_generator(t_program* program,
const std::map<std::string, std::string>& parsed_options,
const std::string& option_string)
- : t_generator(program) {
+ : t_generator (program) {
update_keywords_for_validation();
std::map<std::string, std::string>::const_iterator iter;
@@ -71,70 +71,66 @@
gen_dynbaseclass_frozen_ = "";
import_dynbase_ = "";
package_prefix_ = "";
- for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
- if (iter->first.compare("enum") == 0) {
+ for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
+ if( iter->first.compare("enum") == 0) {
gen_enum_ = true;
- } else if (iter->first.compare("new_style") == 0) {
- pwarning(
- 0,
- "new_style is enabled by default, so the option will be removed in the near future.\n");
- } else if (iter->first.compare("old_style") == 0) {
+ } else if( iter->first.compare("new_style") == 0) {
+ pwarning(0, "new_style is enabled by default, so the option will be removed in the near future.\n");
+ } else if( iter->first.compare("old_style") == 0) {
gen_newstyle_ = false;
pwarning(0, "old_style is deprecated and may be removed in the future.\n");
- } else if (iter->first.compare("utf8strings") == 0) {
- pwarning(0,
- "utf8strings is enabled by default, so the option will be removed in the near "
- "future.\n");
- } else if (iter->first.compare("no_utf8strings") == 0) {
+ } else if( iter->first.compare("utf8strings") == 0) {
+ pwarning(0, "utf8strings is enabled by default, so the option will be removed in the near future.\n");
+ } else if( iter->first.compare("no_utf8strings") == 0) {
gen_utf8strings_ = false;
- } else if (iter->first.compare("slots") == 0) {
+ } else if( iter->first.compare("slots") == 0) {
gen_slots_ = true;
- } else if (iter->first.compare("package_prefix") == 0) {
+ } else if( iter->first.compare("package_prefix") == 0) {
package_prefix_ = iter->second;
- } else if (iter->first.compare("dynamic") == 0) {
+ } else if( iter->first.compare("dynamic") == 0) {
gen_dynamic_ = true;
gen_newstyle_ = false; // dynamic is newstyle
- if (gen_dynbaseclass_.empty()) {
+ if( gen_dynbaseclass_.empty()) {
gen_dynbaseclass_ = "TBase";
}
- if (gen_dynbaseclass_frozen_.empty()) {
+ if( gen_dynbaseclass_frozen_.empty()) {
gen_dynbaseclass_frozen_ = "TFrozenBase";
}
- if (gen_dynbaseclass_exc_.empty()) {
+ if( gen_dynbaseclass_exc_.empty()) {
gen_dynbaseclass_exc_ = "TExceptionBase";
}
- if (gen_dynbaseclass_frozen_exc_.empty()) {
+ if( gen_dynbaseclass_frozen_exc_.empty()) {
gen_dynbaseclass_frozen_exc_ = "TFrozenExceptionBase";
}
- if (import_dynbase_.empty()) {
- import_dynbase_
- = "from thrift.protocol.TBase import TBase, TFrozenBase, TExceptionBase, "
- "TFrozenExceptionBase, TTransport\n";
+ if( import_dynbase_.empty()) {
+ import_dynbase_ = "from thrift.protocol.TBase import TBase, TFrozenBase, TExceptionBase, TFrozenExceptionBase, TTransport\n";
}
- } else if (iter->first.compare("dynbase") == 0) {
+ } else if( iter->first.compare("dynbase") == 0) {
gen_dynbase_ = true;
gen_dynbaseclass_ = (iter->second);
- } else if (iter->first.compare("dynfrozen") == 0) {
+ } else if( iter->first.compare("dynfrozen") == 0) {
gen_dynbaseclass_frozen_ = (iter->second);
- } else if (iter->first.compare("dynexc") == 0) {
+ } else if( iter->first.compare("dynexc") == 0) {
gen_dynbaseclass_exc_ = (iter->second);
- } else if (iter->first.compare("dynfrozenexc") == 0) {
+ } else if( iter->first.compare("dynfrozenexc") == 0) {
gen_dynbaseclass_frozen_exc_ = (iter->second);
- } else if (iter->first.compare("dynimport") == 0) {
+ } else if( iter->first.compare("dynimport") == 0) {
gen_dynbase_ = true;
import_dynbase_ = (iter->second);
- } else if (iter->first.compare("zope.interface") == 0) {
+ } else if( iter->first.compare("zope.interface") == 0) {
gen_zope_interface_ = true;
- } else if (iter->first.compare("twisted") == 0) {
+ } else if( iter->first.compare("twisted") == 0) {
gen_twisted_ = true;
gen_zope_interface_ = true;
- } else if (iter->first.compare("tornado") == 0) {
+ } else if( iter->first.compare("tornado") == 0) {
gen_tornado_ = true;
- } else if (iter->first.compare("coding") == 0) {
+ } else if( iter->first.compare("coding") == 0) {
coding_ = iter->second;
} else if (iter->first.compare("type_hints") == 0) {
+ if (!gen_enum_) {
+ throw "the type_hints py option requires the enum py option";
+ }
gen_type_hints_ = true;
- gen_enum_ = true;
} else {
throw "unknown option py:" + iter->first;
}
@@ -155,7 +151,9 @@
}
}
- std::string indent_str() const override { return " "; }
+ std::string indent_str() const override {
+ return " ";
+ }
/**
* Init and close methods
@@ -208,7 +206,9 @@
* Serialization constructs
*/
- void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
+ void generate_deserialize_field(std::ostream& out,
+ t_field* tfield,
+ std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
@@ -218,7 +218,9 @@
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
- void generate_deserialize_list_element(std::ostream& out, t_list* tlist, std::string prefix = "");
+ void generate_deserialize_list_element(std::ostream& out,
+ t_list* tlist,
+ std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
@@ -256,9 +258,7 @@
std::string declare_argument(t_field* tfield);
std::string render_field_default_value(t_field* tfield);
std::string type_name(t_type* ttype);
- std::string function_signature(t_function* tfunction,
- bool interface = false,
- bool send_part = false);
+ std::string function_signature(t_function* tfunction, bool interface = false, bool send_part = false);
std::string argument_list(t_struct* tstruct,
std::vector<std::string>* pre = nullptr,
std::vector<std::string>* post = nullptr);
@@ -273,9 +273,7 @@
return sub_namespace == "twisted";
}
- static std::string get_real_py_module(const t_program* program,
- bool gen_twisted,
- std::string package_dir = "") {
+ static std::string get_real_py_module(const t_program* program, bool gen_twisted, std::string package_dir="") {
if (gen_twisted) {
std::string twisted_module = program->get_namespace("py.twisted");
if (!twisted_module.empty()) {
@@ -291,8 +289,7 @@
}
static bool is_immutable(t_type* ttype) {
- std::map<std::string, std::vector<std::string>>::iterator it
- = ttype->annotations_.find("python.immutable");
+ std::map<std::string, std::vector<std::string>>::iterator it = ttype->annotations_.find("python.immutable");
if (it == ttype->annotations_.end()) {
// Exceptions are immutable by default.
@@ -305,6 +302,7 @@
}
private:
+
/**
* True if we should generate new-style classes.
*/
@@ -312,8 +310,8 @@
bool gen_enum_;
/**
- * True if we should generate dynamic style classes.
- */
+ * True if we should generate dynamic style classes.
+ */
bool gen_dynamic_;
bool gen_dynbase_;
@@ -327,8 +325,8 @@
bool gen_slots_;
/**
- * True if we should generate classes type hints and type checks in write methods.
- */
+ * True if we should generate classes type hints and type checks in write methods.
+ */
bool gen_type_hints_;
std::string copy_options_;
@@ -374,13 +372,11 @@
protected:
std::set<std::string> lang_keywords_for_validation() const override {
- std::string keywords[]
- = {"False", "None", "True", "and", "as", "assert", "break",
- "class", "continue", "def", "del", "elif", "else", "except",
- "exec", "finally", "for", "from", "global", "if", "import",
- "in", "is", "lambda", "nonlocal", "not", "or", "pass",
- "print", "raise", "return", "try", "while", "with", "yield"};
- return std::set<std::string>(keywords, keywords + sizeof(keywords) / sizeof(keywords[0]));
+ std::string keywords[] = { "False", "None", "True", "and", "as", "assert", "break", "class",
+ "continue", "def", "del", "elif", "else", "except", "exec", "finally", "for", "from",
+ "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "print",
+ "raise", "return", "try", "while", "with", "yield" };
+ return std::set<std::string>(keywords, keywords + sizeof(keywords)/sizeof(keywords[0]) );
}
};
@@ -443,9 +439,10 @@
f_types_ << "all_structs = []" << '\n';
- f_consts_ << py_autogen_comment() << '\n'
- << py_imports() << '\n'
- << "from .ttypes import *" << '\n';
+ f_consts_ <<
+ py_autogen_comment() << '\n' <<
+ py_imports() << '\n' <<
+ "from .ttypes import *" << '\n';
}
/**
@@ -466,11 +463,11 @@
string t_py_generator::py_autogen_comment() {
string coding;
if (!coding_.empty()) {
- coding = "# -*- coding: " + coding_ + " -*-\n";
+ coding = "# -*- coding: " + coding_ + " -*-\n";
}
- return coding + std::string("#\n") + "# Autogenerated by Thrift Compiler (" + THRIFT_VERSION
- + ")\n" + "#\n" + "# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"
- + "#\n" + "# options string: " + copy_options_ + "\n" + "#\n";
+ return coding + std::string("#\n") + "# Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
+ + "#\n" + "# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" + "#\n"
+ + "# options string: " + copy_options_ + "\n" + "#\n";
}
/**
@@ -485,9 +482,12 @@
ss << "from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, "
"TApplicationException"
<< '\n'
- << "from thrift.protocol.TProtocol import TProtocolException" << '\n'
- << "from thrift.TRecursive import fix_spec" << '\n'
- << "from uuid import UUID" << '\n';
+ << "from thrift.protocol.TProtocol import TProtocolException"
+ << '\n'
+ << "from thrift.TRecursive import fix_spec"
+ << '\n'
+ << "from uuid import UUID"
+ << '\n';
if (gen_enum_) {
ss << "from enum import IntEnum" << '\n';
}
@@ -540,8 +540,10 @@
f_types_ << '\n'
<< '\n'
- << "class " << tenum->get_name() << (base_class.empty() ? "" : "(" + base_class + ")")
- << ":" << '\n';
+ << "class " << tenum->get_name()
+ << (base_class.empty() ? "" : "(" + base_class + ")")
+ << ":"
+ << '\n';
indent_up();
generate_python_docstring(f_types_, tenum);
@@ -649,7 +651,7 @@
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
}
indent(out) << render_const_value(g_type_string, v_iter->first) << ": "
- << render_const_value(field_type, v_iter->second) << "," << '\n';
+ << render_const_value(field_type, v_iter->second) << "," << '\n';
}
indent_down();
indent(out) << "})";
@@ -665,7 +667,7 @@
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
indent(out) << render_const_value(ktype, v_iter->first) << ": "
- << render_const_value(vtype, v_iter->second) << "," << '\n';
+ << render_const_value(vtype, v_iter->second) << "," << '\n';
}
indent_down();
indent(out) << "}";
@@ -719,7 +721,7 @@
* definitions are grouped at the end of the file to enable co-recursive structs.
*/
void t_py_generator::generate_forward_declaration(t_struct* tstruct) {
- generate_py_struct(tstruct, tstruct->is_xception());
+ generate_py_struct(tstruct, tstruct->is_xception());
}
/**
@@ -746,6 +748,7 @@
generate_py_struct_definition(f_types_, tstruct, is_exception);
}
+
/**
* Generate the thrift_spec for a struct
* For example,
@@ -819,7 +822,7 @@
} else if (gen_dynamic_) {
if (is_immutable(tstruct)) {
out << "(" << gen_dynbaseclass_frozen_ << ")";
- } else {
+ } else {
out << "(" << gen_dynbaseclass_ << ")";
}
} else if (gen_newstyle_) {
@@ -892,9 +895,9 @@
if (is_immutable(tstruct)) {
if (gen_enum_ && type->is_enum()) {
indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('"
- << (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << " if hasattr("
- << (*m_iter)->get_name() << ", 'value') else " << type_name(type)
- << ".__members__.get(" << (*m_iter)->get_name() << "))" << '\n';
+ << (*m_iter)->get_name() << "', " << (*m_iter)->get_name()
+ << " if hasattr(" << (*m_iter)->get_name() << ", 'value') else "
+ << type_name(type) << ".__members__.get(" << (*m_iter)->get_name() << "))" << '\n';
} else if (gen_newstyle_ || gen_dynamic_) {
indent(out) << "super(" << tstruct->get_name() << ", self).__setattr__('"
<< (*m_iter)->get_name() << "', " << (*m_iter)->get_name() << ")" << '\n';
@@ -923,10 +926,11 @@
// trivial because we know which fields are user-provided, without slots we need to build a
// way to know which fields are user-provided.
if (gen_slots_ && !gen_dynamic_) {
- out << indent() << "if args[0] not in self.__slots__:" << '\n';
- indent_up();
- out << indent() << "super().__setattr__(*args)" << '\n' << indent() << "return" << '\n';
- indent_down();
+ out << indent() << "if args[0] not in self.__slots__:" << '\n';
+ indent_up();
+ out << indent() << "super().__setattr__(*args)" << '\n'
+ << indent() << "return" << '\n';
+ indent_down();
}
out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n';
indent_down();
@@ -940,10 +944,11 @@
// trivial because we know which fields are user-provided, without slots we need to build a
// way to know which fields are user-provided.
if (gen_slots_ && !gen_dynamic_) {
- out << indent() << "if args[0] not in self.__slots__:" << '\n';
- indent_up();
- out << indent() << "super().__delattr__(*args)" << '\n' << indent() << "return" << '\n';
- indent_down();
+ out << indent() << "if args[0] not in self.__slots__:" << '\n';
+ indent_up();
+ out << indent() << "super().__delattr__(*args)" << '\n'
+ << indent() << "return" << '\n';
+ indent_down();
}
out << indent() << "raise TypeError(\"can't modify immutable instance\")" << '\n';
indent_down();
@@ -977,8 +982,7 @@
t_type* type = (*m_iter)->get_type();
if (type->is_enum()) {
out << indent() << "if name == \"" << (*m_iter)->get_name() << "\":" << '\n'
- << indent() << indent_str()
- << "super().__setattr__(name, value if hasattr(value, 'value') else "
+ << indent() << indent_str() << "super().__setattr__(name, value if hasattr(value, 'value') else "
<< type_name(type) << ".__members__.get(value))" << '\n'
<< indent() << indent_str() << "return" << '\n';
}
@@ -1018,10 +1022,8 @@
// Equality and inequality methods that compare by value
out << indent() << "def __eq__(self, other):" << '\n';
indent_up();
- out << indent()
- << "return isinstance(other, self.__class__) and "
- "self.__dict__ == other.__dict__"
- << '\n';
+ out << indent() << "return isinstance(other, self.__class__) and "
+ "self.__dict__ == other.__dict__" << '\n';
indent_down();
out << '\n';
@@ -1105,7 +1107,7 @@
result << "None";
}
indent(out) << result.str() << '\n';
- }
+ }
}
// Loop over reading in fields
@@ -1181,8 +1183,9 @@
indent(out) << "if oprot._fast_encode is not None and self.thrift_spec is not None:" << '\n';
indent_up();
- indent(out) << "oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))"
- << '\n';
+ indent(out)
+ << "oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))"
+ << '\n';
indent(out) << "return" << '\n';
indent_down();
@@ -1206,8 +1209,8 @@
}
// Write the struct map
- out << indent() << "oprot.writeFieldStop()" << '\n'
- << indent() << "oprot.writeStructEnd()" << '\n';
+ out << indent() << "oprot.writeFieldStop()" << '\n' << indent() << "oprot.writeStructEnd()"
+ << '\n';
out << '\n';
@@ -1251,9 +1254,8 @@
if (tservice->get_extends() != nullptr) {
f_service_ << "import "
- << get_real_py_module(tservice->get_extends()->get_program(), gen_twisted_,
- package_prefix_)
- << "." << tservice->get_extends()->get_name() << '\n';
+ << get_real_py_module(tservice->get_extends()->get_program(), gen_twisted_, package_prefix_) << "."
+ << tservice->get_extends()->get_name() << '\n';
}
f_service_ << "import logging" << '\n'
@@ -1283,7 +1285,8 @@
generate_service_remote(tservice);
// Close service file
- f_service_ << "fix_spec(all_structs)" << '\n' << "del all_structs" << '\n';
+ f_service_ << "fix_spec(all_structs)" << '\n'
+ << "del all_structs" << '\n';
f_service_.close();
}
@@ -1442,8 +1445,8 @@
}
} else {
if (gen_twisted_) {
- f_service_ << indent() << extends << ".Client.__init__(self, transport, oprot_factory)"
- << '\n';
+ f_service_ << indent() << extends
+ << ".Client.__init__(self, transport, oprot_factory)" << '\n';
} else if (gen_tornado_) {
f_service_ << indent() << extends
<< ".Client.__init__(self, transport, iprot_factory, oprot_factory)" << '\n';
@@ -1454,9 +1457,9 @@
indent_down();
if (gen_tornado_ && extends.empty()) {
- f_service_ << '\n'
- << indent() << "@gen.engine" << '\n'
- << indent() << "def _start_receiving(self):" << '\n';
+ f_service_ << '\n' <<
+ indent() << "@gen.engine" << '\n' <<
+ indent() << "def _start_receiving(self):" << '\n';
indent_up();
indent(f_service_) << "while True:" << '\n';
indent_up();
@@ -1553,10 +1556,9 @@
indent(f_service_) << "d.addCallbacks(" << '\n';
indent_up();
- f_service_ << indent() << "callback=self.cb_send_" << funname << "," << '\n'
- << indent() << "callbackArgs=(seqid,)," << '\n'
- << indent() << "errback=self.eb_send_" << funname << "," << '\n'
- << indent() << "errbackArgs=(seqid,))" << '\n';
+ f_service_ << indent() << "callback=self.cb_send_" << funname << "," << '\n' << indent()
+ << "callbackArgs=(seqid,)," << '\n' << indent() << "errback=self.eb_send_"
+ << funname << "," << '\n' << indent() << "errbackArgs=(seqid,))" << '\n';
indent_down();
indent(f_service_) << "return d" << '\n';
@@ -1567,9 +1569,8 @@
indent_up();
if ((*f_iter)->is_oneway()) {
// if one-way, fire the deferred & remove it from _reqs
- f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n'
- << indent() << "d.callback(None)" << '\n'
- << indent() << "return d" << '\n';
+ f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent()
+ << "d.callback(None)" << '\n' << indent() << "return d" << '\n';
} else {
f_service_ << indent() << "return self._reqs[seqid]" << '\n';
}
@@ -1579,9 +1580,8 @@
// add an errback to fail the request if the call to send_<> raised an exception
indent(f_service_) << "def eb_send_" << funname << "(self, f, seqid):" << '\n';
indent_up();
- f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n'
- << indent() << "d.errback(f)" << '\n'
- << indent() << "return d" << '\n';
+ f_service_ << indent() << "d = self._reqs.pop(seqid)" << '\n' << indent() << "d.errback(f)"
+ << '\n' << indent() << "return d" << '\n';
indent_down();
}
@@ -1611,13 +1611,12 @@
// Write to the stream
if (gen_twisted_ || gen_tornado_) {
- f_service_ << indent() << "args.write(oprot)" << '\n'
- << indent() << "oprot.writeMessageEnd()" << '\n'
- << indent() << "oprot.trans.flush()" << '\n';
+ f_service_ << indent() << "args.write(oprot)" << '\n' << indent() << "oprot.writeMessageEnd()"
+ << '\n' << indent() << "oprot.trans.flush()" << '\n';
} else {
- f_service_ << indent() << "args.write(self._oprot)" << '\n'
- << indent() << "self._oprot.writeMessageEnd()" << '\n'
- << indent() << "self._oprot.trans.flush()" << '\n';
+ f_service_ << indent() << "args.write(self._oprot)" << '\n' << indent()
+ << "self._oprot.writeMessageEnd()" << '\n' << indent()
+ << "self._oprot.trans.flush()" << '\n';
}
indent_down();
@@ -1632,7 +1631,8 @@
} else {
t_struct noargs(program_);
t_function recv_function((*f_iter)->get_returntype(),
- string("recv_") + (*f_iter)->get_name(), &noargs);
+ string("recv_") + (*f_iter)->get_name(),
+ &noargs);
f_service_ << indent() << "def " << function_signature(&recv_function) << ":" << '\n';
}
indent_up();
@@ -1643,27 +1643,23 @@
f_service_ << indent() << "d = self._reqs.pop(rseqid)" << '\n';
} else if (gen_tornado_) {
} else {
- f_service_ << indent() << "iprot = self._iprot" << '\n'
- << indent() << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n';
+ f_service_ << indent() << "iprot = self._iprot" << '\n' << indent()
+ << "(fname, mtype, rseqid) = iprot.readMessageBegin()" << '\n';
}
f_service_ << indent() << "if mtype == TMessageType.EXCEPTION:" << '\n'
<< indent() << indent_str() << "x = TApplicationException()" << '\n';
if (gen_twisted_) {
- f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n'
- << indent() << indent_str() << "iprot.readMessageEnd()" << '\n'
- << indent() << indent_str() << "return d.errback(x)" << '\n'
- << indent() << "result = " << resultname << "()" << '\n'
- << indent() << "result.read(iprot)" << '\n'
- << indent() << "iprot.readMessageEnd()" << '\n';
+ f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent()
+ << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "return d.errback(x)"
+ << '\n' << indent() << "result = " << resultname << "()" << '\n' << indent()
+ << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n';
} else {
- f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n'
- << indent() << indent_str() << "iprot.readMessageEnd()" << '\n'
- << indent() << indent_str() << "raise x" << '\n'
- << indent() << "result = " << resultname << "()" << '\n'
- << indent() << "result.read(iprot)" << '\n'
- << indent() << "iprot.readMessageEnd()" << '\n';
+ f_service_ << indent() << indent_str() << "x.read(iprot)" << '\n' << indent()
+ << indent_str() << "iprot.readMessageEnd()" << '\n' << indent() << indent_str() << "raise x" << '\n'
+ << indent() << "result = " << resultname << "()" << '\n' << indent()
+ << "result.read(iprot)" << '\n' << indent() << "iprot.readMessageEnd()" << '\n';
}
// Careful, only return _result if not a void function
@@ -1738,31 +1734,28 @@
ofstream_with_content_based_conditional_update f_remote;
f_remote.open(f_remote_name.c_str());
- f_remote << "#!/usr/bin/env python" << '\n'
- << py_autogen_comment() << '\n'
- << "import sys" << '\n'
- << "import pprint" << '\n'
- << "if sys.version_info[0] > 2:" << '\n'
- << indent_str() << "from urllib.parse import urlparse" << '\n'
- << "else:" << '\n'
- << indent_str() << "from urlparse import urlparse" << '\n'
- << "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n'
- << "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n'
- << '\n';
+ f_remote <<
+ "#!/usr/bin/env python" << '\n' <<
+ py_autogen_comment() << '\n' <<
+ "import sys" << '\n' <<
+ "import pprint" << '\n' <<
+ "if sys.version_info[0] > 2:" << '\n' <<
+ indent_str() << "from urllib.parse import urlparse" << '\n' <<
+ "else:" << '\n' <<
+ indent_str() << "from urlparse import urlparse" << '\n' <<
+ "from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n' <<
+ "from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n' << '\n';
- f_remote << "from " << module_ << " import " << service_name_ << '\n'
- << "from " << module_ << ".ttypes import *" << '\n'
- << '\n';
+ f_remote <<
+ "from " << module_ << " import " << service_name_ << '\n' <<
+ "from " << module_ << ".ttypes import *" << '\n' << '\n';
- f_remote << "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n'
- << indent_str() << "print('')" << '\n'
- << indent_str()
- << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] "
- "[-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function "
- "[arg1 [arg2...]]')"
- << '\n'
- << indent_str() << "print('')" << '\n'
- << indent_str() << "print('Functions:')" << '\n';
+ f_remote <<
+ "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n' <<
+ indent_str() << "print('')" << '\n' <<
+ indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << '\n' <<
+ indent_str() << "print('')" << '\n' <<
+ indent_str() << "print('Functions:')" << '\n';
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
f_remote << indent_str() << "print(' " << (*f_iter)->get_returntype()->get_name() << " "
<< (*f_iter)->get_name() << "(";
@@ -1847,18 +1840,15 @@
<< indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << '\n'
<< "else:" << '\n'
<< indent_str() << "if ssl:" << '\n'
- << indent_str() << indent_str()
- << "socket = TSSLSocket.TSSLSocket(host, port, "
+ << indent_str() << indent_str() << "socket = TSSLSocket.TSSLSocket(host, port, "
"validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)"
<< '\n'
<< indent_str() << "else:" << '\n'
<< indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << '\n'
<< indent_str() << "if framed:" << '\n'
- << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)"
- << '\n'
+ << indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << '\n'
<< indent_str() << "else:" << '\n'
- << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)"
- << '\n'
+ << indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << '\n'
<< "protocol = TBinaryProtocol(transport)" << '\n'
<< "client = " << service_name_ << ".Client(protocol)" << '\n'
<< "transport.open()" << '\n'
@@ -1881,8 +1871,8 @@
f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << '\n';
indent_up();
f_remote << indent() << "if len(args) != " << num_args << ":" << '\n'
- << indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires "
- << num_args << " args')" << '\n'
+ << indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires " << num_args
+ << " args')" << '\n'
<< indent() << indent_str() << "sys.exit(1)" << '\n'
<< indent() << "pp.pprint(client." << (*f_iter)->get_name() << "(";
indent_down();
@@ -1918,11 +1908,12 @@
#ifndef _MSC_VER
// Make file executable, love that bitwise OR action
- chmod(f_remote_name.c_str(), S_IRUSR | S_IWUSR | S_IXUSR
+ chmod(f_remote_name.c_str(),
+ S_IRUSR | S_IWUSR | S_IXUSR
#ifndef _WIN32
- | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
+ | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
#endif
- );
+ );
#endif // _MSC_VER
}
@@ -1983,7 +1974,7 @@
f_service_ << indent() << "def on_message_begin(self, func):" << '\n';
indent_up();
- f_service_ << indent() << "self._on_message_begin = func" << '\n';
+ f_service_ << indent() << "self._on_message_begin = func" << '\n';
indent_down();
f_service_ << '\n';
@@ -1994,7 +1985,7 @@
f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << '\n';
f_service_ << indent() << "if self._on_message_begin:" << '\n';
indent_up();
- f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << '\n';
+ f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << '\n';
indent_down();
// TODO(mcslee): validate message
@@ -2053,9 +2044,8 @@
(void)tservice;
// Open function
if (gen_tornado_) {
- f_service_ << indent() << "@gen.coroutine" << '\n'
- << indent() << "def process_" << tfunction->get_name()
- << "(self, seqid, iprot, oprot):" << '\n';
+ f_service_ << indent() << "@gen.coroutine" << '\n' << indent() << "def process_"
+ << tfunction->get_name() << "(self, seqid, iprot, oprot):" << '\n';
} else {
f_service_ << indent() << "def process_" << tfunction->get_name()
<< "(self, seqid, iprot, oprot):" << '\n';
@@ -2066,9 +2056,8 @@
string argsname = tfunction->get_name() + "_args";
string resultname = tfunction->get_name() + "_result";
- f_service_ << indent() << "args = " << argsname << "()" << '\n'
- << indent() << "args.read(iprot)" << '\n'
- << indent() << "iprot.readMessageEnd()" << '\n';
+ f_service_ << indent() << "args = " << argsname << "()" << '\n' << indent() << "args.read(iprot)"
+ << '\n' << indent() << "iprot.readMessageEnd()" << '\n';
t_struct* xs = tfunction->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
@@ -2173,8 +2162,8 @@
<< indent() << "oprot.trans.flush()" << '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
- << indent() << indent_str() << "logging.exception('Exception in oneway handler')"
- << '\n';
+ << indent() << indent_str()
+ << "logging.exception('Exception in oneway handler')" << '\n';
}
indent_down();
@@ -2232,8 +2221,8 @@
<< '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
- << indent() << indent_str() << "logging.exception('Exception in oneway handler')"
- << '\n';
+ << indent() << indent_str()
+ << "logging.exception('Exception in oneway handler')" << '\n';
}
if (!tfunction->is_oneway()) {
@@ -2278,7 +2267,8 @@
}
indent_down();
- f_service_ << indent() << "except TTransport.TTransportException:" << '\n'
+ f_service_ << indent()
+ << "except TTransport.TTransportException:" << '\n'
<< indent() << indent_str() << "raise" << '\n';
if (!tfunction->is_oneway()) {
@@ -2312,8 +2302,7 @@
<< indent() << "oprot.trans.flush()" << '\n';
} else {
f_service_ << indent() << "except Exception:" << '\n'
- << indent() << indent_str() << "logging.exception('Exception in oneway handler')"
- << '\n';
+ << indent() << indent_str() << "logging.exception('Exception in oneway handler')" << '\n';
}
// Close function
@@ -2324,7 +2313,9 @@
/**
* Deserializes a field of any type.
*/
-void t_py_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
+void t_py_generator::generate_deserialize_field(ostream& out,
+ t_field* tfield,
+ string prefix) {
t_type* type = get_true_type(tfield->get_type());
if (type->is_void()) {
@@ -2348,11 +2339,10 @@
case t_base_type::TYPE_STRING:
if (type->is_binary()) {
out << "readBinary()";
- } else if (!gen_utf8strings_) {
+ } else if(!gen_utf8strings_) {
out << "readString()";
} else {
- out << "readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else "
- "iprot.readString()";
+ out << "readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()";
}
break;
case t_base_type::TYPE_BOOL:
@@ -2389,7 +2379,8 @@
}
out << '\n';
} else {
- printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(),
+ printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
+ tfield->get_name().c_str(),
type->get_name().c_str());
}
}
@@ -2423,20 +2414,20 @@
// Declare variables, read header
if (ttype->is_map()) {
- out << indent() << prefix << " = {}" << '\n'
- << indent() << "(" << ktype << ", " << vtype << ", " << size << ") = iprot.readMapBegin()"
- << '\n';
+ out << indent() << prefix << " = {}" << '\n' << indent() << "(" << ktype << ", " << vtype
+ << ", " << size << ") = iprot.readMapBegin()" << '\n';
} else if (ttype->is_set()) {
- out << indent() << prefix << " = set()" << '\n'
- << indent() << "(" << etype << ", " << size << ") = iprot.readSetBegin()" << '\n';
+ out << indent() << prefix << " = set()" << '\n' << indent() << "(" << etype << ", " << size
+ << ") = iprot.readSetBegin()" << '\n';
} else if (ttype->is_list()) {
- out << indent() << prefix << " = []" << '\n'
- << indent() << "(" << etype << ", " << size << ") = iprot.readListBegin()" << '\n';
+ out << indent() << prefix << " = []" << '\n' << indent() << "(" << etype << ", " << size
+ << ") = iprot.readListBegin()" << '\n';
}
// For loop iterates over elements
string i = tmp("_i");
- indent(out) << "for " << i << " in range(" << size << "):" << '\n';
+ indent(out) <<
+ "for " << i << " in range(" << size << "):" << '\n';
indent_up();
@@ -2499,7 +2490,9 @@
/**
* Write a list element
*/
-void t_py_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix) {
+void t_py_generator::generate_deserialize_list_element(ostream& out,
+ t_list* tlist,
+ string prefix) {
string elem = tmp("_elem");
t_field felem(tlist->get_elem_type(), elem);
@@ -2544,8 +2537,7 @@
} else if (!gen_utf8strings_) {
out << "writeString(" << name << ")";
} else {
- out << "writeString(" << name << ".encode('utf-8') if sys.version_info[0] == 2 else "
- << name << ")";
+ out << "writeString(" << name << ".encode('utf-8') if sys.version_info[0] == 2 else " << name << ")";
}
break;
case t_base_type::TYPE_BOOL:
@@ -2573,7 +2565,7 @@
throw "compiler error: no Python name for base type " + t_base_type::t_base_name(tbase);
}
} else if (type->is_enum()) {
- if (gen_enum_) {
+ if (gen_enum_){
out << "writeI32(" << name << ".value)";
} else {
out << "writeI32(" << name << ")";
@@ -2581,8 +2573,10 @@
}
out << '\n';
} else {
- printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n", prefix.c_str(),
- tfield->get_name().c_str(), type->get_name().c_str());
+ printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n",
+ prefix.c_str(),
+ tfield->get_name().c_str(),
+ type->get_name().c_str());
}
}
@@ -2749,7 +2743,6 @@
} else {
result << "None";
}
-
return result.str();
}
@@ -2842,8 +2835,7 @@
return get_real_py_module(program, gen_twisted_, package_prefix_) + "." + ttype->get_name();
}
if (program != nullptr && program != program_) {
- return get_real_py_module(program, gen_twisted_, package_prefix_) + ".ttypes."
- + ttype->get_name();
+ return get_real_py_module(program, gen_twisted_, package_prefix_) + ".ttypes." + ttype->get_name();
}
return ttype->get_name();
}
@@ -2970,12 +2962,12 @@
}
if (ttype->is_binary()) {
- return "'BINARY'";
+ return "'BINARY'";
} else if (gen_utf8strings_ && ttype->is_base_type()
&& reinterpret_cast<t_base_type*>(ttype)->is_string()) {
return "'UTF8'";
} else if (ttype->is_base_type() || ttype->is_enum()) {
- return "None";
+ return "None";
} else if (ttype->is_struct() || ttype->is_xception()) {
return "[" + type_name(ttype) + ", None]";
} else if (ttype->is_map()) {
@@ -3009,22 +3001,19 @@
" zope.interface: Generate code for use with zope.interface.\n"
" twisted: Generate Twisted-friendly RPC services.\n"
" tornado: Generate code for use with Tornado.\n"
- " no_utf8strings: Do not Encode/decode strings using utf8 in the generated code. Basically "
- "no effect for Python 3.\n"
+ " no_utf8strings: Do not Encode/decode strings using utf8 in the generated code. Basically no effect for Python 3.\n"
" coding=CODING: Add file encoding declare in generated file.\n"
" slots: Generate code using slots for instance members.\n"
" dynamic: Generate dynamic code, less code generated but slower.\n"
" dynbase=CLS Derive generated classes from class CLS instead of TBase.\n"
- " dynfrozen=CLS Derive generated immutable classes from class CLS instead of "
- "TFrozenBase.\n"
+ " dynfrozen=CLS Derive generated immutable classes from class CLS instead of TFrozenBase.\n"
" dynexc=CLS Derive generated exceptions from CLS instead of TExceptionBase.\n"
- " dynfrozenexc=CLS Derive generated immutable exceptions from CLS instead of "
- "TFrozenExceptionBase.\n"
+ " dynfrozenexc=CLS Derive generated immutable exceptions from CLS instead of TFrozenExceptionBase.\n"
" dynimport='from foo.bar import CLS'\n"
" Add an import line to generated code to find the dynbase class.\n"
" package_prefix='top.package.'\n"
" Package prefix for generated files.\n"
" old_style: Deprecated. Generate old-style classes.\n"
- " enum: Generates Python's IntEnum, connects thrift to python enums. Python 3.4 "
- "and higher.\n"
- " type_hints: Generate type hints in write method, including IntEnum generation.\n")
+ " enum: Generates Python's IntEnum, connects thrift to python enums. Python 3.4 and higher.\n"
+ " type_hints: Generate type hints and type checks in write method, including IntEnum generation.\n"
+)
diff --git a/test/py/Makefile.am b/test/py/Makefile.am
index b4be953..7e403d1 100644
--- a/test/py/Makefile.am
+++ b/test/py/Makefile.am
@@ -125,9 +125,9 @@
gen-py-type_hints/%/__init__.py: ../%.thrift $(THRIFT)
test -d gen-py-type_hints || $(MKDIR_P) gen-py-type_hints
- test ../v0.16/$(notdir $<) \
- && $(THRIFT) --gen py:type_hints -out gen-py-type_hints ../v0.16/$(notdir $<) \
- || $(THRIFT) --gen py:type_hints -out gen-py-type_hints $<
+ test ../$(notdir $<) \
+ && $(THRIFT) --gen py:type_hints,enum -out gen-py-type_hints ../$(notdir $<) \
+ || $(THRIFT) --gen py:type_hints,enum -out gen-py-type_hints $<
clean-local:
$(RM) -r build
diff --git a/test/py/generate.cmake b/test/py/generate.cmake
index a439c44..80e7f51 100644
--- a/test/py/generate.cmake
+++ b/test/py/generate.cmake
@@ -14,7 +14,7 @@
generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:enum gen-py-enum)
-generate(${MY_PROJECT_DIR}/test/v0.16/ThriftTest.thrift py:type_hints gen-py-type_hints)
+generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:type_hints,enum gen-py-type_hints)
generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py gen-py-default)
generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:slots gen-py-slots)
@@ -23,7 +23,7 @@
generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:enum gen-py-enum)
-generate(${MY_PROJECT_DIR}/test/v0.16/DebugProtoTest.thrift py:type_hints gen-py-type_hints)
+generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:type_hints,enum gen-py-type_hints)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py gen-py-default)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:slots gen-py-slots)
@@ -32,7 +32,7 @@
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:enum gen-py-enum)
-generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:type_hints gen-py-type_hints)
+generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:type_hints,enum gen-py-type_hints)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py gen-py-default)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:slots gen-py-slots)
@@ -41,4 +41,4 @@
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:enum gen-py-enum)
-generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:type_hints gen-py-type_hints)
+generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:type_hints,enum gen-py-type_hints)