25
#include "PreCompiled.h"
29
#include <boost/regex.hpp>
32
#include "Interpreter.h"
34
#include "ExceptionFactory.h"
36
#include "PyObjectBase.h"
42
unsigned int format2_len = 1024;
46
PyException::PyException(const Py::Object& obj)
48
_sErrMsg = obj.as_string();
53
_exceptionType = reinterpret_cast<PyObject*>(obj.ptr()->ob_type);
54
_errorType = obj.ptr()->ob_type->tp_name;
58
PyException::PyException()
60
PP_Fetch_Error_Text();
62
setPyObject(PP_PyDict_Object);
64
std::string prefix = PP_last_error_type;
65
std::string error = PP_last_error_info;
71
_exceptionType = PP_last_exception_type;
73
if (PP_last_exception_type) {
77
Py_DECREF(PP_last_exception_type);
78
PP_last_exception_type = nullptr;
81
_stackTrace = PP_last_error_trace;
86
PyGILStateLocker locker;
90
PyException::~PyException() noexcept = default;
92
void PyException::ThrowException()
95
myexcp.ReportException();
96
myexcp.raiseException();
99
void PyException::raiseException()
101
PyGILStateLocker locker;
102
if (PP_PyDict_Object) {
104
Py::Dict edict(PP_PyDict_Object, true);
105
PP_PyDict_Object = nullptr;
107
std::string exceptionname;
108
if (_exceptionType == Base::PyExc_FC_FreeCADAbort) {
109
edict.setItem("sclassname", Py::String(typeid(Base::AbortException).name()));
112
edict.setItem("breported", Py::True());
114
Base::ExceptionFactory::Instance().raiseException(edict.ptr());
117
if (_exceptionType == Base::PyExc_FC_FreeCADAbort) {
118
Base::AbortException exc(_sErrMsg.c_str());
119
exc.setReported(_isReported);
126
void PyException::ReportException() const
131
PyGILStateLocker locker;
132
PySys_SetObject("last_traceback", PP_last_traceback);
133
Base::Console().DeveloperError("pyException",
141
void PyException::setPyException() const
143
std::stringstream str;
144
str << getStackTrace() << getErrorType() << ": " << what();
145
PyErr_SetString(getPyExceptionType(), str.str().c_str());
150
SystemExitException::SystemExitException()
161
long int errCode = 1;
162
std::string errMsg = "System exit";
165
PyObject* traceback {};
168
PyGILStateLocker locker;
169
PyErr_Fetch(&type, &value, &traceback);
170
PyErr_NormalizeException(&type, &value, &traceback);
173
code = PyObject_GetAttrString(value, "code");
174
if (code && value != Py_None) {
179
if (PyLong_Check(value)) {
180
errCode = PyLong_AsLong(value);
183
const char* str = PyUnicode_AsUTF8(value);
185
errMsg = errMsg + ": " + str;
198
class PythonStdOutput: public Py::PythonExtension<PythonStdOutput>
201
static void init_type()
203
behaviors().name("PythonStdOutput");
204
behaviors().doc("Python standard output");
205
add_varargs_method("write", &PythonStdOutput::write, "write()");
206
add_varargs_method("flush", &PythonStdOutput::flush, "flush()");
209
PythonStdOutput() = default;
210
~PythonStdOutput() override = default;
212
Py::Object write(const Py::Tuple&)
216
Py::Object flush(const Py::Tuple&)
224
InterpreterSingleton::InterpreterSingleton()
226
this->_global = nullptr;
229
InterpreterSingleton::~InterpreterSingleton() = default;
232
std::string InterpreterSingleton::runString(const char* sCmd)
236
PyObject* presult {};
238
PyGILStateLocker locker;
239
module = PP_Load_Module("__main__");
243
dict = PyModule_GetDict(module);
249
presult = PyRun_String(sCmd, Py_file_input, dict, dict);
251
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
252
throw SystemExitException();
255
PyException::ThrowException();
259
PyObject* repr = PyObject_Repr(presult);
262
std::string ret(PyUnicode_AsUTF8(repr));
281
std::string InterpreterSingleton::runStringWithKey(const char* psCmd,
283
const char* key_initial_value)
285
PyGILStateLocker locker;
286
Py::Module module("__main__");
287
Py::Dict globalDictionary = module.getDict();
288
Py::Dict localDictionary;
289
Py::String initial_value(key_initial_value);
290
localDictionary.setItem(key, initial_value);
293
PyRun_String(psCmd, Py_file_input, globalDictionary.ptr(), localDictionary.ptr());
295
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
296
throw SystemExitException();
299
PyException::ThrowException();
304
Py::Object key_return_value = localDictionary.getItem(key);
305
if (!key_return_value.isString()) {
306
key_return_value = key_return_value.str();
309
Py::Bytes str = Py::String(key_return_value).encode("utf-8", "~E~");
310
std::string result = static_cast<std::string>(str);
314
Py::Object InterpreterSingleton::runStringObject(const char* sCmd)
318
PyObject* presult {};
320
PyGILStateLocker locker;
321
module = PP_Load_Module("__main__");
325
dict = PyModule_GetDict(module);
331
presult = PyRun_String(sCmd, Py_eval_input, dict, dict);
333
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
334
throw SystemExitException();
340
return Py::asObject(presult);
343
void InterpreterSingleton::systemExit()
346
PyObject* exception {};
351
PyErr_Fetch(&exception, &value, &tb);
353
if (!value || value == Py_None) {
356
if (PyExceptionInstance_Check(value)) {
358
PyObject* code = PyObject_GetAttrString(value, "code");
362
if (value == Py_None) {
369
if (PyLong_Check(value)) {
370
exitcode = (int)PyLong_AsLong(value);
373
PyObject_Print(value, stderr, Py_PRINT_RAW);
374
PySys_WriteStderr("\n");
383
PyErr_Restore(exception, value, tb);
389
void InterpreterSingleton::runInteractiveString(const char* sCmd)
393
PyObject* presult {};
395
PyGILStateLocker locker;
396
module = PP_Load_Module("__main__");
400
dict = PyModule_GetDict(module);
405
presult = PyRun_String(sCmd, Py_single_input, dict, dict);
407
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
408
throw SystemExitException();
413
PyObject* errdata {};
414
PyObject* errtraceback {};
415
PyErr_Fetch(&errobj, &errdata, &errtraceback);
417
RuntimeError exc("");
419
if (PyUnicode_Check(errdata)) {
420
exc.setMessage(PyUnicode_AsUTF8(errdata));
423
PyErr_Restore(errobj, errdata, errtraceback);
424
if (PyErr_Occurred()) {
433
void InterpreterSingleton::runFile(const char* pxFileName, bool local)
436
FileInfo fi(pxFileName);
437
FILE* fp = _wfopen(fi.toStdWString().c_str(), L"r");
439
FILE* fp = fopen(pxFileName, "r");
442
throw FileException("Unknown file", pxFileName);
445
PyGILStateLocker locker;
448
module = PyImport_AddModule("__main__");
449
dict = PyModule_GetDict(module);
451
dict = PyDict_Copy(dict);
457
if (!PyDict_GetItemString(dict, "__file__")) {
458
PyObject* pyObj = PyUnicode_FromString(pxFileName);
464
if (PyDict_SetItemString(dict, "__file__", pyObj) < 0) {
473
PyObject* result = PyRun_File(fp, pxFileName, Py_file_input, dict, dict);
478
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
479
throw SystemExitException();
486
bool InterpreterSingleton::loadModule(const char* psModName)
492
PyGILStateLocker locker;
493
module = PP_Load_Module(psModName);
496
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
497
throw SystemExitException();
506
PyObject* InterpreterSingleton::addModule(Py::ExtensionModuleBase* mod)
508
_modules.push_back(mod);
509
return mod->module().ptr();
512
void InterpreterSingleton::cleanupModules()
515
#if defined(__has_feature)
516
#if __has_feature(address_sanitizer)
517
for (auto it : _modules) {
525
void InterpreterSingleton::addType(PyTypeObject* Type, PyObject* Module, const char* Name)
530
if (PyType_Ready(Type) < 0) {
533
PyModule_AddObject(Module, Name, Base::getTypeAsObject(Type));
536
void InterpreterSingleton::addPythonPath(const char* Path)
538
PyGILStateLocker locker;
539
Py::List list(PySys_GetObject("path"));
540
list.append(Py::String(Path));
543
#if PY_VERSION_HEX < 0x030b0000
544
const char* InterpreterSingleton::init(int argc, char* argv[])
546
if (!Py_IsInitialized()) {
547
Py_SetProgramName(Py_DecodeLocale(argv[0], nullptr));
555
const char* virtualenv = getenv("VIRTUAL_ENV");
558
"# Check for virtualenv, and activate if present.\n"
560
"https://virtualenv.pypa.io/en/latest/userguide/"
561
"#using-virtualenv-without-bin-python\n"
564
"base_path = os.getenv(\"VIRTUAL_ENV\")\n"
565
"if not base_path is None:\n"
566
" activate_this = os.path.join(base_path, \"bin\", \"activate_this.py\")\n"
567
" exec(open(activate_this).read(), {'__file__':activate_this})\n");
570
#if PY_VERSION_HEX < 0x03090000
571
PyEval_InitThreads();
575
static std::vector<wchar_t*> _argv(size);
576
for (int i = 0; i < argc; i++) {
577
_argv[i] = Py_DecodeLocale(argv[i], nullptr);
579
PySys_SetArgv(argc, _argv.data());
580
PythonStdOutput::init_type();
581
this->_global = PyEval_SaveThread();
584
PyGILStateLocker lock;
585
return Py_EncodeLocale(Py_GetPath(), nullptr);
590
void initInterpreter(int argc, char* argv[])
594
PyConfig_InitIsolatedConfig(&config);
596
config.user_site_directory = 1;
598
status = PyConfig_SetBytesArgv(&config, argc, argv);
599
if (PyStatus_Exception(status)) {
600
throw Base::RuntimeError("Failed to set config");
603
status = Py_InitializeFromConfig(&config);
604
if (PyStatus_Exception(status)) {
605
throw Base::RuntimeError("Failed to init from config");
610
const char* virtualenv = getenv("VIRTUAL_ENV");
612
std::wstringstream ss;
613
PyConfig_Read(&config);
614
ss << virtualenv << L"/lib/python" << PY_MAJOR_VERSION << "." << PY_MINOR_VERSION
616
PyObject* venvLocation = PyUnicode_FromWideChar(ss.str().c_str(), ss.str().size());
617
PyObject* path = PySys_GetObject("path");
618
PyList_Append(path, venvLocation);
621
PyConfig_Clear(&config);
626
const char* InterpreterSingleton::init(int argc, char* argv[])
629
if (!Py_IsInitialized()) {
630
initInterpreter(argc, argv);
632
PythonStdOutput::init_type();
633
this->_global = PyEval_SaveThread();
636
PyGILStateLocker lock;
637
return Py_EncodeLocale(Py_GetPath(), nullptr);
639
catch (const Base::Exception& e) {
646
void InterpreterSingleton::replaceStdOutput()
648
PyGILStateLocker locker;
649
PythonStdOutput* out = new PythonStdOutput();
650
PySys_SetObject("stdout", out);
651
PySys_SetObject("stderr", out);
654
int InterpreterSingleton::cleanup(void (*func)())
656
return Py_AtExit(func);
659
void InterpreterSingleton::finalize()
662
PyEval_RestoreThread(this->_global);
670
void InterpreterSingleton::runStringArg(const char* psCom, ...)
673
va_list namelessVars;
674
va_start(namelessVars, psCom);
675
int len = vsnprintf(format2, format2_len, psCom, namelessVars);
676
va_end(namelessVars);
688
InterpreterSingleton* InterpreterSingleton::_pcSingleton = nullptr;
690
InterpreterSingleton& InterpreterSingleton::Instance()
694
_pcSingleton = new InterpreterSingleton();
696
return *_pcSingleton;
699
void InterpreterSingleton::Destruct()
702
assert(_pcSingleton);
704
_pcSingleton = nullptr;
707
int InterpreterSingleton::runCommandLine(const char* prompt)
709
PyGILStateLocker locker;
710
return PP_Run_Command_Line(prompt);
717
void InterpreterSingleton::runMethodVoid(PyObject* pobject, const char* method)
719
PyGILStateLocker locker;
720
if (PP_Run_Method(pobject,
730
PyObject* InterpreterSingleton::runMethodObject(PyObject* pobject, const char* method)
734
PyGILStateLocker locker;
735
if (PP_Run_Method(pobject,
747
void InterpreterSingleton::runMethod(PyObject* pobject,
756
PyObject* presult {};
758
va_start(argslist, argfmt);
760
PyGILStateLocker locker;
761
pmeth = PyObject_GetAttrString(pobject, method);
764
throw AttributeError(
765
"Error running InterpreterSingleton::RunMethod() method not defined");
769
pargs = Py_VaBuildValue(argfmt, argslist);
774
throw TypeError("InterpreterSingleton::RunMethod() wrong arguments");
777
#if PY_VERSION_HEX < 0x03090000
778
presult = PyEval_CallObject(pmeth, pargs);
780
presult = PyObject_CallObject(pmeth, pargs);
785
if (PP_Convert_Result(presult, resfmt, cresult) != 0) {
786
if (PyErr_Occurred()) {
790
"Error running InterpreterSingleton::RunMethod() exception in called method");
794
PyObject* InterpreterSingleton::getValue(const char* key, const char* result_var)
798
PyObject* presult {};
800
PyGILStateLocker locker;
801
module = PP_Load_Module("__main__");
805
dict = PyModule_GetDict(module);
811
presult = PyRun_String(key, Py_file_input, dict, dict);
817
return PyObject_GetAttrString(module, result_var);
820
void InterpreterSingleton::dbgObserveFile(const char* sFileName)
823
_cDebugFileName = sFileName;
826
_cDebugFileName = "";
830
void InterpreterSingleton::dbgSetBreakPoint(unsigned int )
833
void InterpreterSingleton::dbgUnsetBreakPoint(unsigned int )
836
void InterpreterSingleton::dbgStep()
839
std::string InterpreterSingleton::strToPython(const char* Str)
842
const char* It = Str;
844
while (*It != '\0') {
866
int getSWIGVersionFromModule(const std::string& module)
868
static std::map<std::string, int> moduleMap;
869
std::map<std::string, int>::iterator it = moduleMap.find(module);
870
if (it != moduleMap.end()) {
875
Py::Dict dict(PyImport_GetModuleDict());
876
if (!dict.hasKey(module)) {
879
Py::Module mod(module);
880
Py::String file(mod.getAttr("__file__"));
881
std::string filename = (std::string)file;
883
filename = filename.substr(0, filename.rfind('.'));
885
boost::regex rx("^# Version ([1-9])\\.([0-9])\\.([0-9]+)");
889
Base::FileInfo fi(filename);
891
Base::ifstream str(fi, std::ios::in);
892
while (str && std::getline(str, line)) {
893
if (boost::regex_match(line.c_str(), what, rx)) {
894
int major = std::atoi(what[1].first);
895
int minor = std::atoi(what[2].first);
896
int micro = std::atoi(what[3].first);
897
int version = (major << 16) + (minor << 8) + micro;
898
moduleMap[module] = version;
903
catch (Py::Exception& e) {
907
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
908
moduleMap[module] = 0;
913
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
916
extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own);
917
extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags);
918
extern void cleanupSWIG_T(const char* TypeName);
919
extern int getSWIGPointerTypeObj_T(const char* TypeName, PyTypeObject** ptr);
923
PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module,
924
const char* TypeName,
929
PyObject* proxy = nullptr;
930
PyGILStateLocker locker;
932
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
933
result = Swig_python::createSWIGPointerObj_T(TypeName, Pointer, &proxy, own);
946
throw Base::RuntimeError("No SWIG wrapped library loaded");
949
bool InterpreterSingleton::convertSWIGPointerObj(const char* Module,
950
const char* TypeName,
956
PyGILStateLocker locker;
958
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
959
result = Swig_python::convertSWIGPointerObj_T(TypeName, obj, ptr, flags);
973
throw Base::RuntimeError("No SWIG wrapped library loaded");
976
void InterpreterSingleton::cleanupSWIG(const char* TypeName)
978
PyGILStateLocker locker;
979
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
980
Swig_python::cleanupSWIG_T(TypeName);
986
PyTypeObject* InterpreterSingleton::getSWIGPointerTypeObj(const char* Module, const char* TypeName)
989
PyTypeObject* proxy = nullptr;
990
PyGILStateLocker locker;
992
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
993
result = Swig_python::getSWIGPointerTypeObj_T(TypeName, &proxy);
1004
throw Base::RuntimeError("No SWIG wrapped library loaded");