2
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; version 2 of the
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23
#include "python_context.h"
25
#include "grtpp_util.h"
26
#include "base/string_utilities.h"
27
#include "base/file_functions.h"
29
#ifdef ENABLE_PYTHON_MODULES
33
#include <Python/node.h>
34
#include <Python/grammar.h>
35
#include <Python/parsetok.h>
36
#include <Python/errcode.h>
37
#include <Python/token.h>
47
#include "python_grtobject.h"
48
#include "python_grtlist.h"
49
#include "python_grtdict.h"
52
DEFAULT_LOG_DOMAIN("python context")
57
const std::string grt::LanguagePython= "python";
60
// used to identify a proper GRT context object as a PyCObject
61
static const char *GRTTypeSignature= "GRTCONTEXT";
62
// used to identify a GRT value as a PyCObject
63
static const char *GRTValueSignature= "GRTVALUE";
66
static std::string flatten_class_name(std::string name)
68
std::string::size_type p;
69
while ((p= name.find('.')) != std::string::npos)
74
PythonContext::PythonContext(GRT *grt, const std::string &module_path)
78
static const char *argv[2]= { "/dev/null" , NULL };
80
if (getenv("PYTHON_DEBUG"))
84
// Hack needed in Windows because Python lib uses C:\Python26 as default pythonhome
85
// That will cause conflicts if there is some other Python installed in there (bug #52949)
87
// Program.cs also does this, but somehow, they don't seem to get reflected here
88
char *path = getenv("PATH");
91
// strip away everything with Python in it
92
std::vector<std::string> parts = base::split(path, ";");
94
for (std::vector<std::string>::const_iterator p = parts.begin(); p != parts.end(); ++p)
96
if (!strstr(base::tolower(*p).c_str(), "python"))
103
putenv(g_strdup_printf("PATH=%s", npath.c_str()));
106
putenv(g_strdup_printf("PYTHONHOME=%s\\Python", module_path.c_str()));
107
putenv(g_strdup_printf("PYTHONPATH=%s\\Python;%s\\Python\\DLLs;%s\\Python\\Lib",
108
module_path.c_str(), module_path.c_str(), module_path.c_str()));
109
//putenv("PYTHONHOME=C:\\nowhere");
111
Py_InitializeEx(0); // skips signal handler init
113
// Stores the main thread state
114
_main_thread_state = PyThreadState_Get();
116
PySys_SetArgv(1, (char**)argv);
118
PyEval_InitThreads();
122
_grt_object_class= 0;
123
_grt_method_class= 0;
125
register_grt_module();
127
main= PyImport_AddModule("__main__");
128
PyDict_SetItemString(PyModule_GetDict(main),
129
"grt", PyImport_ImportModule("grt"));
131
// make sys.stdout and sys.stderr send stuff to GRT
132
PySys_SetObject((char*)"stdout", get_grt_module());
133
PySys_SetObject((char*)"stderr", get_grt_module());
135
// set stdin to the GRT shell console
136
PySys_SetObject((char*)"stdin", get_grt_module());
138
run_post_init_script();
141
PyObject *path = from_grt(grt::StringRef(base::Logger::log_filename()));
142
PyDict_SetItemString(PyModule_GetDict(PyImport_AddModule("grt")), "logpath", path);
150
PythonContext::~PythonContext()
152
PyEval_RestoreThread(_main_thread_state);
153
_main_thread_state = NULL;
159
void PythonContext::add_module_path(const std::string &modpath, bool prepend)
161
// add the path to the search path so that it can be imported
163
PyObject *path= PyString_FromString(modpath.c_str());
165
WillEnterPython lock;
167
path_list= PySys_GetObject((char *) "path"); // cast to (char *) required for gcc 4.3 to avoid warning about deprecated conversion
168
// from string constant to 'char*'.
171
// check if the path is already in it
172
for (i= PyList_Size(path_list)-1; i >= 0; --i)
174
if (PyObject_Compare(PyList_GetItem(path_list, i), path) == 0)
178
if (i < 0) // not found
181
PyList_Insert(path_list, 0, path);
183
PyList_Append(path_list, path);
189
void PythonContext::set_python_error(const grt::type_error &exc, const std::string &location)
191
PyErr_SetString(PyExc_TypeError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
195
void PythonContext::set_python_error(const grt::bad_item &exc, const std::string &location)
197
PyErr_SetString(PyExc_IndexError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
201
void PythonContext::set_python_error(const std::exception &exc, const std::string &location)
203
PyErr_SetString(PyExc_SystemError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
208
/** Gets the PythonContext from the Python interpreter.
210
PythonContext *PythonContext::get()
216
module= PyDict_GetItemString(PyImport_GetModuleDict(), "grt");
218
throw std::runtime_error("GRT module not found in Python runtime");
220
dict= PyModule_GetDict(module);
222
throw std::runtime_error("GRT module is invalid in Python runtime");
224
ctx= PyDict_GetItemString(dict, "__GRT__");
226
throw std::runtime_error("GRT context not found in Python runtime");
228
if (PyCObject_GetDesc(ctx) == &GRTTypeSignature)
229
return static_cast<PythonContext*>(PyCObject_AsVoidPtr(ctx));
231
throw std::runtime_error("Invalid GRT context in Python runtime");
235
PythonContext *PythonContext::get_and_check()
239
return PythonContext::get();
241
catch (std::exception &exc)
243
PyErr_SetString(PyExc_SystemError, strfmt("Could not get GRT context: %s", exc.what()).c_str());
249
static PyObject *grt_print(PyObject *self, PyObject *args)
254
if (!(ctx= PythonContext::get_and_check()))
258
if (!PyArg_ParseTuple(args, "O", &o))
260
if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
269
if (!ctx->pystring_to_string(o, text))
273
OutputDebugStringA(text.c_str());
275
g_print("%s", text.c_str()); // g_print is not routed to g_log
277
ctx->get_grt()->send_output(text);
283
static PyObject *pylog(base::Logger::LogLevel level, PyObject *args)
288
if (!(ctx= PythonContext::get_and_check()))
293
if (!PyArg_ParseTuple(args, "sO", &domain, &o))
296
if (!ctx->pystring_to_string(o, text))
299
base::Logger::log(level, domain, "%s", text.c_str());
306
static PyObject *grt_log_error(PyObject *self, PyObject *args)
308
return pylog(base::Logger::LogError, args);
311
static PyObject *grt_log_warning(PyObject *self, PyObject *args)
313
return pylog(base::Logger::LogWarning, args);
316
static PyObject *grt_log_info(PyObject *self, PyObject *args)
318
return pylog(base::Logger::LogInfo, args);
321
static PyObject *grt_log_debug(PyObject *self, PyObject *args)
323
return pylog(base::Logger::LogDebug, args);
326
static PyObject *grt_log_debug2(PyObject *self, PyObject *args)
328
return pylog(base::Logger::LogDebug2, args);
331
static PyObject *grt_log_debug3(PyObject *self, PyObject *args)
333
return pylog(base::Logger::LogDebug3, args);
336
static PyObject *grt_send_output(PyObject *self, PyObject *args)
341
if (!(ctx= PythonContext::get_and_check()))
345
if (!PyArg_ParseTuple(args, "O", &o))
347
if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
356
if (!ctx->pystring_to_string(o, text))
359
ctx->get_grt()->send_output(text);
366
static PyObject *grt_send_warning(PyObject *self, PyObject *args)
370
if (!(ctx= PythonContext::get_and_check()))
374
if (!PyArg_ParseTuple(args, "O", &o))
376
if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
385
if (!ctx->pystring_to_string(o, text))
388
ctx->get_grt()->send_warning(text);
394
static PyObject *grt_send_info(PyObject *self, PyObject *args)
398
if (!(ctx= PythonContext::get_and_check()))
402
if (!PyArg_ParseTuple(args, "O", &o))
404
if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
413
if (!ctx->pystring_to_string(o, text))
416
ctx->get_grt()->send_info(text);
417
log_debug2("grt.python", text.c_str());
423
static PyObject *grt_send_error(PyObject *self, PyObject *args)
427
if (!(ctx= PythonContext::get_and_check()))
431
if (!PyArg_ParseTuple(args, "O", &o))
433
if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
442
if (!ctx->pystring_to_string(o, text))
445
ctx->get_grt()->send_error(text);
452
static PyObject *grt_send_progress(PyObject *self, PyObject *args)
455
if (!(ctx= PythonContext::get_and_check()))
459
char *text, *detail= NULL;
460
if (!PyArg_ParseTuple(args, "fs|s", &pct, &text, &detail))
463
ctx->get_grt()->send_progress(pct, text ? text : "", detail ? detail : "", NULL);
469
static PyObject *grt_get_by_path(PyObject *self, PyObject *args)
472
const char *path= "";
476
if (!(ctx= PythonContext::get_and_check()))
479
if (!PyArg_ParseTuple(args, "s|O", &path, &object))
486
value= ctx->from_pyobject(object);
488
catch (grt::type_error &exc)
490
PyErr_SetString(PyExc_TypeError, exc.what());
493
catch (std::exception &exc)
495
PythonContext::set_python_error(exc);
500
value= ctx->get_grt()->root();
507
value= get_value_by_path(value, path);
509
catch (std::exception &exc)
511
PythonContext::set_python_error(exc);
515
return ctx->from_grt(value);
519
static PyObject *grt_readline(PyObject *self, PyObject *args)
523
if (!(ctx= PythonContext::get_and_check()))
526
if (!PyArg_ParseTuple(args, ""))
529
std::string line = ctx->stdin_readline_slot();
530
return Py_BuildValue("s", line.c_str());
534
static bool call_handle_output(const std::string &text, PyObject *callable)
536
WillEnterPython lock;
539
if (!(ret = PyObject_Call(callable, Py_BuildValue("s", text.c_str()), NULL)))
541
PythonContext::log_python_error("Error calling Python output handler:");
546
if (ret == Py_None || ret == Py_False || PyInt_AsLong(ret) == 0)
556
static PyObject *grt_push_output_handler(PyObject *self, PyObject *args)
559
if (!(ctx= PythonContext::get_and_check()))
563
if (!PyArg_ParseTuple(args, "O", &o))
566
if (!PyCallable_Check(o))
569
ctx->push_output_handler(boost::bind(&call_handle_output,_1, AutoPyObject(o)));
574
static PyObject *grt_pop_output_handler(PyObject *self, PyObject *args)
577
if (!(ctx= PythonContext::get_and_check()))
580
ctx->pop_output_handler();
586
static PyObject *grt_serialize(PyObject *self, PyObject *args)
589
if (!(ctx= PythonContext::get_and_check()))
595
if (!PyArg_ParseTuple(args, "Os", &object, &path))
598
grt::ValueRef value(ctx->from_pyobject(object));
599
if (!value.is_valid())
601
PyErr_SetString(PyExc_TypeError, "First argument must be a GRT object");
607
PyErr_SetString(PyExc_ValueError, "File path expected for argument #2");
613
ctx->get_grt()->serialize(value, path);
615
catch (const std::exception &exc)
617
PythonContext::set_python_error(exc, "serializing object");
626
static PyObject *grt_unserialize(PyObject *self, PyObject *args)
629
if (!(ctx= PythonContext::get_and_check()))
633
if (!PyArg_ParseTuple(args, "s", &path))
637
PyErr_SetString(PyExc_ValueError, "File path expected");
643
grt::ValueRef value = ctx->get_grt()->unserialize(path);
644
return ctx->from_grt(value);
646
catch (const std::exception &exc)
648
PythonContext::set_python_error(exc, base::strfmt("unserializing file %s", path));
656
/** Register grt related functionality as a module
658
Stuff made available in the module include:
659
<li>__GRT__ variable holding a CObject pointer back to PythonContext
660
<li>GRTList, GRTDict and GRTObject types
661
<li>send_output, send_error, send_info etc
664
static PyMethodDef GrtModuleMethods[] = {
665
{"send_output", grt_send_output, METH_VARARGS,
666
"Write a string in the GRT shell."},
667
{"write", grt_print, METH_VARARGS,
668
"Write a string in the GRT shell (alias to send_output)."},
669
{"send_error", grt_send_error, METH_VARARGS,
670
"Write an error message to the GRT shell."},
671
{"send_warning", grt_send_warning, METH_VARARGS,
672
"Write a warning message to the GRT shell."},
673
{"send_info", grt_send_info, METH_VARARGS,
674
"Write a info message to the GRT shell."},
675
{"send_progress", grt_send_progress, METH_VARARGS,
676
"Write a progress message."},
678
{"log_error", grt_log_error, METH_VARARGS,
679
"Logs an error to the log file, in the specified context ex: log_error('myplugin', 'cannot open file')"},
680
{"log_warning", grt_log_warning, METH_VARARGS,
681
"Logs a warning to the log file, in the specified context ex: log_warning('myplugin', 'cannot open file very well')"},
682
{"log_debug", grt_log_debug, METH_VARARGS,
683
"Logs a debug message to the log file, in the specified context ex: log_debug('myplugin', 'trying to open file with ')"},
684
{"log_debug2", grt_log_debug2, METH_VARARGS,
685
"Logs a verbose debug message to the log file, in the specified context ex: log_debug2('myplugin', 'reading from file')"},
686
{"log_debug3", grt_log_debug3, METH_VARARGS,
687
"Logs a very verbose debug message to the log file, in the specified context ex: log_debug3('myplugin', 'processing file')"},
688
{"log_info", grt_log_info, METH_VARARGS,
689
"Logs an informational message to the log file, in the specified context ex: log_info('myplugin', 'file opened')"},
691
{"push_output_handler", grt_push_output_handler, METH_VARARGS,
692
"Pushes a callback of the form function(text) to be called when a plugin outputs text."},
693
{"pop_output_handler", grt_push_output_handler, METH_NOARGS,
694
"Pops previously pushed handler."},
696
{"readline", grt_readline, METH_VARARGS,
697
"Waits for a line of text to be input to the scripting shell prompt."},
699
{"get", grt_get_by_path, METH_VARARGS,
700
"Gets a value from a GRT dict or object (or from the global tree) by path."},
702
{"serialize", grt_serialize, METH_VARARGS,
703
"Serializes a GRT object into a XML file. serialize(object, path)"},
704
{"unserialize", grt_unserialize, METH_VARARGS,
705
"Unserializes a GRT object from a XML file created by serialize. unserialize(path) -> object"},
708
{NULL, NULL, 0, NULL} /* Sentinel */
712
void PythonContext::register_grt_module()
714
PyObject *module = Py_InitModule("grt", GrtModuleMethods);
716
throw std::runtime_error("Error initializing GRT module in Python support");
720
// add the context ptr
721
PyObject* context_object= PyCObject_FromVoidPtrAndDesc(this, &GRTTypeSignature, NULL);
722
if (context_object != NULL)
723
PyModule_AddObject(module, "__GRT__", context_object);
725
PyModule_AddStringConstant(module, "INT", (char*)type_to_str(IntegerType).c_str());
726
PyModule_AddStringConstant(module, "DOUBLE", (char*)type_to_str(DoubleType).c_str());
727
PyModule_AddStringConstant(module, "STRING", (char*)type_to_str(StringType).c_str());
728
PyModule_AddStringConstant(module, "LIST", (char*)type_to_str(ListType).c_str());
729
PyModule_AddStringConstant(module, "DICT", (char*)type_to_str(DictType).c_str());
730
PyModule_AddStringConstant(module, "OBJECT", (char*)type_to_str(ObjectType).c_str());
732
init_grt_module_type();
733
init_grt_list_type();
734
init_grt_dict_type();
735
init_grt_object_type();
737
_grt_modules_module = Py_InitModule("grt.modules", NULL);
738
if (!_grt_modules_module)
739
throw std::runtime_error("Error initializing grt.modules module in Python support");
741
// AutoPyObject need to keep a reference but PyModule_AddObject steals it
742
// so it is needed to increase it to avoid problems on destruction
743
Py_INCREF(_grt_modules_module);
744
PyModule_AddObject(_grt_module, "modules", _grt_modules_module);
746
_grt_classes_module = Py_InitModule("grt.classes", NULL);
747
if (!_grt_classes_module)
748
throw std::runtime_error("Error initializing grt.classes module in Python support");
750
Py_INCREF(_grt_classes_module);
751
PyModule_AddObject(_grt_module, "classes", _grt_classes_module);
753
PyModule_AddObject(_grt_classes_module, "grt", _grt_module);
759
PyObject *PythonContext::get_grt_module()
765
bool PythonContext::import_module(const std::string &name)
767
PyObject *main= PyImport_AddModule("__main__");
768
PyObject *module = PyImport_ImportModule((char*)name.c_str());
769
if (!main || !module)
771
PythonContext::log_python_error(base::strfmt("Error importing %s", name.c_str()).c_str());
774
PyDict_SetItemString(PyModule_GetDict(main), name.c_str(), module);
780
PyObject *PythonContext::eval_string(const std::string &expression)
782
// LockPython lock(this);
784
PyObject *mainmod= PyImport_AddModule("__main__");
790
PyObject *globals= PyModule_GetDict(mainmod);
793
PyObject *result= PyRun_String(expression.c_str(), Py_eval_input, globals, globals);
795
PythonContext::log_python_error(base::strfmt("Error running expr: %s", expression.c_str()).c_str());
803
PyObject *PythonContext::get_global(const std::string &value)
806
PyObject *mainmod= PyImport_AddModule("__main__");
812
PyObject *globals= PyModule_GetDict(mainmod);
814
return PyDict_GetItemString(globals, value.c_str());
816
return eval_string(value);
820
bool PythonContext::set_global(const std::string &name, PyObject *value)
822
PyObject *mainmod= PyImport_AddModule("__main__");
825
PythonContext::log_python_error("Error getting __main__");
829
PyObject *globals= PyModule_GetDict(mainmod);
832
PythonContext::log_python_error("Error getting __main__ dict");
837
PyDict_SetItemString(globals, name.c_str(), value);
842
static void release_value(void *value, void *desc)
844
internal::Value *v= reinterpret_cast<internal::Value*>(value);
849
/** Wraps a grt value in a PyCObject.
851
PyCObjects are used internally to initialize a grt.List/Dict or Object from an existing grt value.
853
PyObject *PythonContext::internal_cobject_from_value(const ValueRef &value)
855
internal::Value *v= value.valueptr();
857
return PyCObject_FromVoidPtrAndDesc(v, &GRTValueSignature, release_value);
861
ValueRef PythonContext::value_from_internal_cobject(PyObject *value)
863
if (PyCObject_GetDesc(value) == &GRTValueSignature)
864
return ValueRef(reinterpret_cast<internal::Value*>(PyCObject_AsVoidPtr(value)));
866
throw std::runtime_error("attempt to extract GRT value from invalid Python object");
870
/** Convert a GRT value to a Python object/value.
872
* For objects, it will also wrap in the appropriate object subclass from grt.classes
874
PyObject *PythonContext::from_grt(const ValueRef &value)
876
if (value.is_valid())
878
switch (value.type())
882
long l = *IntegerRef::cast_from(value);
883
if ((long)(int)l == l)
884
return PyInt_FromLong(l);
886
return PyLong_FromLong(l);
890
return PyFloat_FromDouble(*DoubleRef::cast_from(value));
894
// maybe this should start returning unicode data, but before that all python code
895
// should be tested if it can handle the unicode type. For now we just return utf8 strings.
896
//return PyUnicode_EncodeUTF8();
897
std::string data= *StringRef::cast_from(value);
898
return PyString_FromStringAndSize(data.data(), data.size());
902
PyObject *content= PythonContext::internal_cobject_from_value(value);
903
PyObject *r= PyObject_Call(_grt_list_class, Py_BuildValue("(ssO)", "", "", content), NULL);
909
PyObject *content= PythonContext::internal_cobject_from_value(value);
910
PyObject *r= PyObject_Call(_grt_dict_class, Py_BuildValue("(ssO)", "", "", content), NULL);
916
std::string class_name= grt::ObjectRef::cast_from(value).class_name();
917
PyObject *content= PythonContext::internal_cobject_from_value(value);
918
PyObject *theclass= _grt_class_wrappers[class_name];
919
PyObject *r= PyObject_Call(theclass ? theclass : (PyObject*)_grt_object_class, Py_BuildValue("(sO)", "", content), NULL);
932
bool PythonContext::pystring_to_string(PyObject *strobject, std::string &ret_string)
934
if (PyUnicode_Check(strobject))
936
PyObject *ref = PyUnicode_AsUTF8String(strobject);
941
PyString_AsStringAndSize(ref, &s, &len);
943
ret_string= std::string(s, len);
952
if (PyString_Check(strobject))
956
PyString_AsStringAndSize(strobject, &s, &len);
958
ret_string = std::string(s, len);
966
ValueRef PythonContext::from_pyobject(PyObject *object)
968
if (!object || object == Py_None)
971
if (PyInt_Check(object))
972
return IntegerRef(PyInt_AsLong(object));
974
if (PyLong_Check(object))
975
return IntegerRef(PyLong_AsLong(object));
977
if (PyFloat_Check(object))
978
return DoubleRef(PyFloat_AsDouble(object));
980
if (PyUnicode_Check(object) || PyString_Check(object))
983
if (pystring_to_string(object, tmp))
984
return StringRef(tmp);
988
if (PyTuple_Check(object))
990
grt::BaseListRef list(_grt);
992
for (Py_ssize_t c= PyTuple_Size(object), i= 0; i < c; i++)
994
PyObject *item= PyTuple_GetItem(object, i);
995
list.ginsert(from_pyobject(item));
1000
if (PyList_Check(object))
1002
grt::BaseListRef list(_grt);
1004
for (Py_ssize_t c= PyList_Size(object), i= 0; i < c; i++)
1006
PyObject *item= PyList_GetItem(object, i);
1007
list.ginsert(from_pyobject(item));
1011
else if (PyObject_IsInstance(object, _grt_list_class))
1012
return *((PyGRTListObject*)object)->list;
1014
if (PyDict_Check(object))
1016
grt::DictRef dict(_grt);
1017
PyObject *key, *value;
1020
while (PyDict_Next(object, &pos, &key, &value))
1022
dict.set(PyString_AsString(key), from_pyobject(value));
1027
else if (PyObject_IsInstance(object, _grt_dict_class))
1028
return *((PyGRTDictObject*)object)->dict;
1030
if (PyObject_IsInstance(object, _grt_object_class))
1031
return *((PyGRTObjectObject*)object)->object;
1037
ValueRef PythonContext::simple_type_from_pyobject(PyObject *object, const grt::SimpleTypeSpec &type)
1043
if (PyFloat_Check(object))
1044
return IntegerRef((long)PyFloat_AsDouble(object));
1048
if (PyInt_Check(object))
1049
return IntegerRef(PyInt_AsLong(object));
1053
if (!PyLong_Check(object))
1054
return IntegerRef(PyLong_AsLong(object));
1058
throw grt::type_error("expected integer type x");
1062
if (PyInt_Check(object))
1063
return DoubleRef(PyInt_AsLong(object));
1066
if (!PyFloat_Check(object))
1067
throw grt::type_error("expected double type");
1068
return DoubleRef(PyFloat_AsDouble(object));
1073
if (pystring_to_string(object, tmp))
1074
return StringRef(tmp);
1076
throw grt::type_error("expected string type");
1080
if (!PyObject_IsInstance(object, _grt_object_class))
1081
throw grt::type_error("expected GRT object");
1083
grt::ObjectRef grtobject(*((PyGRTObjectObject*)object)->object);
1085
if (!type.object_class.empty() && !grtobject->is_instance(type.object_class))
1086
throw grt::type_error(strfmt("expected GRT object of class %s", type.object_class.c_str()));
1096
ValueRef PythonContext::from_pyobject(PyObject *object, const grt::TypeSpec &expected_type)
1098
if (object == Py_None)
1101
switch (expected_type.base.type)
1107
return simple_type_from_pyobject(object, expected_type.base);
1111
if (PyList_Check(object))
1113
grt::BaseListRef list(_grt);
1115
for (Py_ssize_t c= PyList_Size(object), i= 0; i < c; i++)
1117
PyObject *item= PyList_GetItem(object, i);
1118
switch (expected_type.content.type)
1124
list.ginsert(simple_type_from_pyobject(item, expected_type.content));
1127
list.ginsert(from_pyobject(item));
1130
g_warning("invalid type spec requested");
1136
else if (PyObject_IsInstance(object, _grt_list_class))
1138
return *((PyGRTListObject*)object)->list;
1141
throw grt::type_error("expected list");
1145
if (PyDict_Check(object))
1147
grt::DictRef dict(_grt);
1148
PyObject *key, *value;
1151
while (PyDict_Next(object, &pos, &key, &value))
1153
switch (expected_type.content.type)
1159
dict.set(PyString_AsString(key), simple_type_from_pyobject(value, expected_type.content));
1162
dict.set(PyString_AsString(key), from_pyobject(value));
1165
g_warning("invalid type spec requested");
1172
else if (PyObject_IsInstance(object, _grt_dict_class))
1174
return *((PyGRTDictObject*)object)->dict;
1177
throw grt::type_error("expected dict");
1180
return from_pyobject(object);
1187
int PythonContext::run_file(const std::string &file, bool interactive)
1189
PyObject *f = PyFile_FromString((char*)base::string_to_path_for_open(file).c_str(), (char*)"r");
1192
PythonContext::log_python_error(base::strfmt("Could not open file %s\n", file.c_str()).c_str());
1196
log_debug2("About to pyrun '%s'\n", file.c_str());
1197
if (PyRun_SimpleFile(PyFile_AsFile(f), file.c_str()) != 0)
1200
PythonContext::log_python_error(base::strfmt("Error running file %s\n", file.c_str()).c_str());
1209
/** Execute a string as Python code.
1211
If line_buffer is not null, it will be used as a buffer for multiple-line statements.
1212
It is used by interactive shell, to construct these from single-line components.
1214
If line_buffer is null, the passed buffer will be expected to contain complete code.
1216
int PythonContext::run_buffer(const std::string &buffer, std::string *line_buffer)
1224
line_buffer->append(buffer);
1226
WillEnterPython lock;
1228
n= PyParser_SimpleParseStringFlags(line_buffer ? line_buffer->c_str() : buffer.c_str(),
1229
line_buffer ? Py_single_input : Py_file_input,
1232
if (n && (!buffer.empty() && (buffer[0] ==' ' || buffer[0] == '\t')) && line_buffer)
1234
return 0; // continued line
1237
if (!n && PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SyntaxError))
1243
PyErr_Fetch(&excep, &value, &trace);
1244
message= PyTuple_GetItem(value, 0);
1245
if (strstr(PyString_AsString(message), "unexpected EOF") ||
1246
strncmp(PyString_AsString(message), "EOF", 3)==0)
1253
return 0; // continued line
1255
PyErr_Restore(excep, value, trace);
1260
PythonContext::log_python_error("Error running buffer");
1263
line_buffer->clear();
1271
// command is supposedly complete, try to execute it
1273
mainmod= PyImport_AddModule("__main__");
1278
globals= PyModule_GetDict(mainmod);
1282
result= PyRun_String(line_buffer->c_str(), Py_single_input, globals, globals);
1284
line_buffer->clear();
1287
result= PyRun_String(buffer.c_str(), Py_file_input, globals, globals);
1291
if (PyErr_Occurred())
1292
PythonContext::log_python_error("Error running buffer");
1305
// template of a python function to create a wrapper class for a GRT class
1306
static const char *create_class_template=
1307
"class %s(grt.Object):\n"
1308
" def __init__(self, classname = None, wrapobj = None):\n"
1309
" grt.Object.__init__(self, classname, wrapobj)";
1311
static const char *create_class_template_sub=
1313
" def __init__(self, classname = '%s', wrapobj = None):\n"
1314
" %s.__init__(self, classname, wrapobj)";
1318
/** Create a Python subclass of our grt.Object class, that will wrap around the given GRT class
1320
static void create_class_wrapper(grt::MetaClass *meta, PyObject *locals)
1323
grt::MetaClass *parent;
1325
if ((parent= meta->parent()) && parent->parent() != 0)
1327
std::string parname= flatten_class_name(parent->name());
1328
script= strfmt(create_class_template_sub,
1329
flatten_class_name(meta->name()).c_str(), parname.c_str(),
1330
meta->name().c_str(),
1335
script= strfmt(create_class_template,
1336
flatten_class_name(meta->name()).c_str());
1339
if (!PyRun_String(script.c_str(), Py_single_input, locals, locals))
1340
PythonContext::log_python_error(NULL);
1343
/** Refresh Python environment with GRT information.
1345
int PythonContext::refresh()
1347
WillEnterPython lock;
1349
PyModule_AddObject(get_grt_module(), "root", from_grt(_grt->root()));
1351
PyObject *classes_dict= PyModule_GetDict(_grt_classes_module);
1353
Py_INCREF(classes_dict);
1355
// Generate Python class hierarchy to wrap GRT classes
1356
const std::list<grt::MetaClass*> &classes(_grt->get_metaclasses());
1357
for (std::list<grt::MetaClass*>::const_iterator iter= classes.begin(); iter != classes.end(); ++iter)
1359
create_class_wrapper(*iter, classes_dict);
1361
_grt_class_wrappers[(*iter)->name()]= PyDict_GetItemString(classes_dict, flatten_class_name((*iter)->name()).c_str());
1364
Py_DECREF(classes_dict);
1366
// Generate module wrappers
1367
const std::vector<grt::Module*> &modules(_grt->get_modules());
1368
for (std::vector<grt::Module*>::const_iterator iter= modules.begin(); iter != modules.end(); ++iter)
1370
PyObject *r= PyObject_Call(_grt_module_class, Py_BuildValue("(s)", (*iter)->name().c_str()), NULL);
1373
PythonContext::log_python_error("Error refreshing grt modules");
1375
if (PyModule_AddObject(_grt_modules_module, (char*)(*iter)->name().c_str(), r) < 0)
1376
PythonContext::log_python_error("Error refreshing grt modules");
1383
void PythonContext::log_python_error(const char *message)
1385
PythonContext *ctx = PythonContext::get();
1389
base::Logger::log(base::Logger::LogError, "python", "%s", message);
1390
PyObject *grt_dict = PyModule_GetDict(ctx->get_grt_module());
1391
PyObject *_stderr = PyDict_GetItemString(grt_dict, "_log_stderr");
1392
PyObject *old_stderr = PySys_GetObject((char*)"stderr");
1393
Py_INCREF(old_stderr);
1395
PySys_SetObject((char*)"stderr", _stderr);
1399
PySys_SetObject((char*)"stderr", old_stderr);
1400
Py_DECREF(old_stderr);
1406
// script to be executed once GRT is initialized
1407
// executed in the grt module namespace
1408
static const char *post_init_script =
1410
"class _grtFileRedirector:\n"
1411
" def __init__(self, logger):\n"
1412
" self.logger = logger\n"
1413
" def write(self, text):\n"
1414
" if type(text) not in (str, unicode):\n"
1415
" text = str(text)\n"
1416
" grt.send_output(text)\n"
1417
" self.logger(grt._log_domain, text)\n"
1418
"grt._log_domain = 'python'\n"
1419
"grt._log_stdout = _grtFileRedirector(grt.log_info)\n"
1420
"grt._log_stderr = _grtFileRedirector(grt.log_error)\n";
1422
void PythonContext::run_post_init_script()
1424
WillEnterPython lock;
1426
if (PyRun_SimpleString((char*)post_init_script) < 0)
1427
PythonContext::log_python_error("Error running post-init script:");
1430
#endif // ENABLE_PYTHON_MODULES