32 #if PY_MAJOR_VERSION >= 3
33 extern PyTypeObject PyIOBase_Type;
46 DECLARE_EXPORT PyThreadState* PythonInterpreter::mainThreadState = NULL;
49 #if PY_MAJOR_VERSION >= 3
50 PyObject* PythonInterpreter::createModule()
52 static PyMethodDef freppleMethods[] = {
55 static struct PyModuleDef frepplemodule = {
56 PyModuleDef_HEAD_INIT,
58 "Access to the frePPLe library",
60 NULL, NULL, NULL, NULL
62 module = PyModule_Create(&frepplemodule);
71 if(!Py_IsInitialized())
73 #if PY_MAJOR_VERSION >= 3
75 PyImport_AppendInittab(
"frepple", &PythonInterpreter::createModule);
82 mainThreadState = PyEval_SaveThread();
86 PyGILState_STATE state = PyGILState_Ensure();
88 #if PY_MAJOR_VERSION < 3
90 module = Py_InitModule3(
"frepple", NULL,
"Access to the frePPLe library");
96 "import frepple, sys\n"
98 "\tdef write(self,str):\n"
99 "\t\tfrepple.log(str)\n"
100 "sys.stdout = redirect()\n"
101 "sys.stderr = redirect()"
106 PyGILState_Release(state);
130 "Prints a string to the frePPLe log file.",
false);
133 PyGILState_Release(state);
143 if (!mainThreadState)
return;
146 PyEval_AcquireLock();
147 PyEval_RestoreThread(mainThreadState);
155 PyThreadState * myThreadState = PyGILState_GetThisThreadState();
156 if (myThreadState)
return;
159 PyThreadState *tcur = PyThreadState_New(PyInterpreterState_Head());
163 PyEval_RestoreThread(tcur);
164 PyEval_ReleaseLock();
171 PyThreadState * tcur = PyGILState_GetThisThreadState();
175 PyEval_RestoreThread(tcur);
176 PyThreadState_Clear(tcur);
177 PyThreadState_DeleteCurrent();
184 PyGILState_STATE state = PyGILState_Ensure();
187 PyObject *m = PyImport_AddModule(
"__main__");
191 PyGILState_Release(state);
194 PyObject *d = PyModule_GetDict(m);
198 PyGILState_Release(state);
204 PyObject *v = PyRun_String(cmd, Py_file_input, d, d);
210 PyGILState_Release(state);
214 #if PY_MAJOR_VERSION >= 3
217 if (Py_FlushLine()) PyErr_Clear();
220 PyGILState_Release(state);
232 for (string::size_type pos = filename.find_first_of(
"'", 0);
234 pos = filename.find_first_of(
"'", pos))
236 filename.replace(pos,1,
"\\'",2);
239 #if PY_MAJOR_VERSION >= 3
240 string cmd =
"exec(compile(open(r'" + filename +
"').read(), r'" + filename +
"', 'exec'))";
242 string cmd =
"execfile(r'" + filename +
"')\n";
249 const char* name, PyCFunction method,
int flags,
const char* doc,
bool lock
255 string *leakingName =
new string(name);
256 string *leakingDoc =
new string(doc);
257 PyMethodDef *newMethod =
new PyMethodDef;
258 newMethod->ml_name = leakingName->c_str();
259 newMethod->ml_meth = method;
260 newMethod->ml_flags = flags;
261 newMethod->ml_doc = leakingDoc->c_str();
264 PyGILState_STATE state;
265 if (lock) state = PyGILState_Ensure();
268 PyObject* mod = PyUnicode_FromString(
"frepple");
271 if (lock) PyGILState_Release(state);;
274 PyObject* func = PyCFunction_NewEx(newMethod, NULL, mod);
278 if (lock) PyGILState_Release(state);
283 PyObject* moduledict = PyModule_GetDict(module);
287 if (lock) PyGILState_Release(state);
290 if (PyDict_SetItemString(moduledict ,leakingName->c_str(), func) < 0)
293 if (lock) PyGILState_Release(state);
299 if (lock) PyGILState_Release(state);
304 (
const char* c, PyCFunctionWithKeywords f,
int i,
const char* d,
bool b)
306 registerGlobalMethod(c, reinterpret_cast<PyCFunction>(f), i | METH_KEYWORDS, d, b);
311 (
const char* name, PyObject *obj,
bool lock)
313 PyGILState_STATE state;
314 if (lock) state = PyGILState_Ensure();
315 PyModule_AddObject(module, name, obj);
316 if (lock) PyGILState_Release(state);
320 PyObject* PythonInterpreter::python_log(PyObject *
self, PyObject *args)
324 int ok = PyArg_ParseTuple(args,
"s:log", &data);
325 if (!ok)
return NULL;
332 return Py_BuildValue(
"");
337 const PyTypeObject PythonType::PyTypeObjectTemplate =
339 PyVarObject_HEAD_INIT(NULL, 0)
340 "frepple.unspecified",
352 reinterpret_cast<hashfunc
>(_Py_HashPointer),
358 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
378 #
if PY_MAJOR_VERSION > 3
402 #ifdef HAVE_LOCALTIME_R
404 localtime_r(&ticks, &t);
406 struct tm t = *localtime(&ticks);
408 obj = PyDateTime_FromDateAndTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday,
409 t.tm_hour, t.tm_min, t.tm_sec, 0);
416 if (PyDateTime_Check(obj))
418 PyDateTime_GET_YEAR(obj),
419 PyDateTime_GET_MONTH(obj),
420 PyDateTime_GET_DAY(obj),
421 PyDateTime_DATE_GET_HOUR(obj),
422 PyDateTime_DATE_GET_MINUTE(obj),
423 PyDateTime_DATE_GET_SECOND(obj)
425 else if (PyDate_Check(obj))
427 PyDateTime_GET_YEAR(obj),
428 PyDateTime_GET_MONTH(obj),
429 PyDateTime_GET_DAY(obj)
431 #if PY_MAJOR_VERSION >= 3
432 else if (!PyUnicode_Check(obj))
434 else if (PyString_Check(obj))
437 if (PyUnicode_Check(obj))
440 const_cast<PyObject*&
>(obj) =
441 PyUnicode_AsEncodedString(obj,
"UTF-8",
"ignore");
443 #if PY_MAJOR_VERSION >= 3
444 return Date(PyBytes_AsString(PyObject_Str(obj)));
446 return Date(PyString_AsString(PyObject_Str(obj)));
451 "Invalid data type. Expecting datetime.date, datetime.datetime or string"
458 obj = p ?
static_cast<PyObject*
>(p) : Py_None;
468 table =
new PyTypeObject(PyTypeObjectTemplate);
469 table->tp_basicsize = base_size;
476 for (vector<PythonType*>::const_iterator i =
table.begin(); i !=
table.end(); ++i)
477 if (**i==*t)
return *i;
481 table.push_back(cachedTypePtr);
482 return cachedTypePtr;
491 PyObject *filearg = NULL;
493 if (!PyArg_ParseTuple(args,
"|sO:toXML", &mode, &filearg))
500 if (!mode || mode[0] ==
'S')
502 else if (mode[0] ==
'P')
504 else if (mode[0] ==
'D')
517 #if PY_MAJOR_VERSION >= 3
518 if (PyObject_IsInstance(filearg, (PyObject*)&PyIOBase_Type))
520 if (PyFile_Check(filearg))
524 return PyFile_WriteString(ch.str().c_str(), filearg) ?
546 (
const char* method_name, PyCFunction f,
int flags,
const char* doc )
548 unsigned short i = 0;
551 if (!table->tp_methods)
553 table->tp_methods =
new PyMethodDef[methodArraySize];
557 while (table->tp_methods[i].ml_name) i++;
558 if (i % methodArraySize == methodArraySize - 1)
561 PyMethodDef* tmp =
new PyMethodDef[i + 1 + methodArraySize];
562 for(
unsigned short j = 0; j < i; j++)
563 tmp[j] = table->tp_methods[j];
564 delete [] table->tp_methods;
565 table->tp_methods = tmp;
570 table->tp_methods[i].ml_name = method_name;
571 table->tp_methods[i].ml_meth = f;
572 table->tp_methods[i].ml_flags = flags;
573 table->tp_methods[i].ml_doc = doc;
576 table->tp_methods[++i].ml_name = NULL;
577 table->tp_methods[i].ml_meth = NULL;
578 table->tp_methods[i].ml_flags = 0;
579 table->tp_methods[i].ml_doc = NULL;
584 (
const char* c, PyCFunctionWithKeywords f,
int i,
const char* d)
586 addMethod(c, reinterpret_cast<PyCFunction>(f), i | METH_KEYWORDS, d);
593 PyGILState_STATE state = PyGILState_Ensure();
594 if (PyType_Ready(table) < 0)
596 PyGILState_Release(state);
597 throw RuntimeException(
string(
"Can't register python type ") + table->tp_name);
600 int result = PyModule_AddObject(
603 reinterpret_cast<PyObject*>(table)
605 PyGILState_Release(state);
620 catch (
const exception& e)
621 {PyErr_SetString(PyExc_Exception, e.what());}
623 {PyErr_SetString(PyExc_Exception,
"Unidentified exception");}
637 PyGILState_STATE pythonstate = PyGILState_Ensure();
638 func = PyRun_String(n.c_str(), Py_eval_input,
639 PyEval_GetGlobals(), PyEval_GetLocals() );
642 PyGILState_Release(pythonstate);
643 throw DataException(
"Python function '" + n +
"' not defined");
645 if (!PyCallable_Check(func))
647 PyGILState_Release(pythonstate);
648 throw DataException(
"Python object '" + n +
"' is not a function");
653 PyGILState_Release(pythonstate);
659 if (!p || p == Py_None)
666 if (!PyCallable_Check(p))
670 PyGILState_STATE pythonstate = PyGILState_Ensure();
672 p = PyRun_String(n.c_str(), Py_eval_input,
673 PyEval_GetGlobals(), PyEval_GetLocals() );
676 PyGILState_Release(pythonstate);
677 throw DataException(
"Python function '" + n +
"' not defined");
679 if (!PyCallable_Check(p))
681 PyGILState_Release(pythonstate);
682 throw DataException(
"Python object '" + n +
"' is not a function");
684 PyGILState_Release(pythonstate);
696 PyGILState_STATE pythonstate = PyGILState_Ensure();
697 PyObject* result = PyEval_CallFunction(func,
"()");
700 logger <<
"Error: Exception caught when calling Python function '"
701 << (func ? PyEval_GetFuncName(func) :
"NULL") <<
"'" << endl;
702 if (PyErr_Occurred()) PyErr_PrintEx(0);
704 PyGILState_Release(pythonstate);
712 PyGILState_STATE pythonstate = PyGILState_Ensure();
713 PyObject* result = PyEval_CallFunction(func,
"(O)", p);
716 logger <<
"Error: Exception caught when calling Python function '"
717 << (func ? PyEval_GetFuncName(func) :
"NULL") <<
"'" << endl;
718 if (PyErr_Occurred()) PyErr_PrintEx(0);
720 PyGILState_Release(pythonstate);
728 PyGILState_STATE pythonstate = PyGILState_Ensure();
729 PyObject* result = PyEval_CallFunction(func,
"(OO)", p, q);
732 logger <<
"Error: Exception caught when calling Python function '"
733 << (func ? PyEval_GetFuncName(func) :
"NULL") <<
"'" << endl;
734 if (PyErr_Occurred()) PyErr_PrintEx(0);
736 PyGILState_Release(pythonstate);
745 #if PY_MAJOR_VERSION >= 3
746 if (!PyUnicode_Check(name))
748 if (!PyString_Check(name))
751 PyErr_Format(PyExc_TypeError,
752 #
if PY_MAJOR_VERSION >= 3
753 "attribute name must be string, not '%S'",
754 Py_TYPE(name)->tp_name);
756 "attribute name must be string, not '%s'",
757 PyString_AsString(name));
761 #if PY_MAJOR_VERSION >= 3
762 PyObject* name_utf8 = PyUnicode_AsUTF8String(name);
764 Py_DECREF(name_utf8);
769 if (result)
return result;
771 if (PyErr_Occurred())
return NULL;
777 return PyObject_GenericGetAttr(
self,name);
792 #if PY_MAJOR_VERSION >= 3
793 if (!PyUnicode_Check(name))
795 if (!PyString_Check(name))
798 PyErr_Format(PyExc_TypeError,
799 #
if PY_MAJOR_VERSION >= 3
800 "attribute name must be string, not '%S'",
801 Py_TYPE(name)->tp_name);
803 "attribute name must be string, not '%s'",
804 PyString_AsString(name));
811 #if PY_MAJOR_VERSION >= 3
812 PyObject* name_utf8 = PyUnicode_AsUTF8String(name);
814 Py_DECREF(name_utf8);
819 if (!result)
return 0;
822 if (!PyErr_Occurred())
823 PyErr_Format(PyExc_AttributeError,
824 #
if PY_MAJOR_VERSION >= 3
825 "attribute '%S' on '%s' can't be updated",
826 name, Py_TYPE(
self)->tp_name);
828 "attribute '%s' on '%s' can't be updated",
829 PyString_AsString(name), Py_TYPE(
self)->tp_name);
845 if (Py_TYPE(
self) != Py_TYPE(other)
846 && Py_TYPE(
self)->tp_base != Py_TYPE(other)->tp_base)
849 Py_INCREF(Py_NotImplemented);
850 return Py_NotImplemented;