redirect stdcout to a stringstream so Python __str__() can properly return a string after calling the c++ print function

This is to avoid a printing issue in some Python's IDE when __str__() is called to update objects' values in Debug mode.
release/4.3a0
Duy-Nguyen Ta 2017-07-25 16:32:26 -04:00
parent deb7815a88
commit b1071b08a0
4 changed files with 47 additions and 4 deletions

View File

@ -762,4 +762,11 @@ namespace utilities {
gtsam::Values localToWorld(const gtsam::Values& local, const gtsam::Pose2& base, const gtsam::KeyVector& keys); gtsam::Values localToWorld(const gtsam::Values& local, const gtsam::Pose2& base, const gtsam::KeyVector& keys);
} //\namespace utilities } //\namespace utilities
#include <gtsam/nonlinear/utilities.h>
class RedirectCout {
RedirectCout();
string str();
};
} //\namespace gtsam } //\namespace gtsam

View File

@ -2664,4 +2664,10 @@ namespace utilities {
} //\namespace utilities } //\namespace utilities
#include <gtsam/nonlinear/utilities.h>
class RedirectCout {
RedirectCout();
string str();
};
} }

View File

@ -250,6 +250,32 @@ Values localToWorld(const Values& local, const Pose2& base,
return world; return world;
} }
} } // namespace utilities
/**
* For Python __str__().
* Redirect std cout to a string stream so we can return a string representation
* of an object when it prints to cout.
* https://stackoverflow.com/questions/5419356/redirect-stdout-stderr-to-a-string
*/
struct RedirectCout {
/// constructor -- redirect stdout buffer to a stringstream buffer
RedirectCout() : ssBuffer_(), coutBuffer_(std::cout.rdbuf(ssBuffer_.rdbuf())) {}
/// return the string
std::string str() const {
return ssBuffer_.str();
}
/// destructor -- redirect stdout buffer to its original buffer
~RedirectCout() {
std::cout.rdbuf(coutBuffer_);
}
private:
std::stringstream ssBuffer_;
std::streambuf* coutBuffer_;
};
} }

View File

@ -100,9 +100,13 @@ void Method::emit_cython_pyx_no_overload(FileWriter& file,
const Class& cls) const { const Class& cls) const {
string funcName = pyRename(name_); string funcName = pyRename(name_);
// leverage python's special treatment for print // leverage python's special treatment for print
if (funcName == "print_") if (funcName == "print_") {
file.oss << " def __str__(self):\n self.print_('')\n return ''\n"; //file.oss << " def __str__(self):\n self.print_('')\n return ''\n";
file.oss << " def __str__(self):\n";
file.oss << " strBuf = RedirectCout()\n";
file.oss << " self.print_('')\n";
file.oss << " return strBuf.str()\n";
}
// Function definition // Function definition
file.oss << " def " << funcName; file.oss << " def " << funcName;
// modify name of function instantiation as python doesn't allow overloads // modify name of function instantiation as python doesn't allow overloads