[glom/boostpythonretry: 6/6] More
- From: Murray Cumming <murrayc src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glom/boostpythonretry: 6/6] More
- Date: Tue, 2 Feb 2010 20:50:23 +0000 (UTC)
commit 552952c01e09407c1b1b344acc2c418abd38c37b
Author: Murray Cumming <murrayc murrayc com>
Date: Tue Feb 2 19:49:24 2010 +0100
More
glom/libglom/python_embed/py_glom_record.cc | 10 ++-
glom/libglom/python_embed/py_glom_record.h | 3 -
glom/libglom/python_embed/py_glom_relatedrecord.h | 3 -
.../libglom/python_embed/pygdavalue_conversions.cc | 85 ++++++++++++--------
glom/libglom/python_embed/pygdavalue_conversions.h | 4 +-
glom/python_embed/glom_python.cc | 29 +++++--
glom/python_embed/python_module/py_glom_module.cc | 2 +-
glom/python_embed/python_module/py_glom_module.h | 1 -
tests/test_python_execute_func.cc | 23 +++++-
9 files changed, 103 insertions(+), 57 deletions(-)
---
diff --git a/glom/libglom/python_embed/py_glom_record.cc b/glom/libglom/python_embed/py_glom_record.cc
index f329516..5d8b7e2 100644
--- a/glom/libglom/python_embed/py_glom_record.cc
+++ b/glom/libglom/python_embed/py_glom_record.cc
@@ -24,6 +24,9 @@
#include <eval.h> /* for PyEval_EvalCode */
#include <objimpl.h> /* for PyObject_New() */
+//#define NO_IMPORT_PYGOBJECT //To avoid a multiple definition in pygtk.
+//#include <pygobject.h> //For the PyGObject and PyGBoxed struct definitions.
+
#include <libglom/python_embed/py_glom_record.h>
#include <libglom/python_embed/py_glom_related.h>
#include <libglom/python_embed/pygdavalue_conversions.h> //For pygda_value_as_pyobject().
@@ -44,13 +47,18 @@ PyGlomRecord::~PyGlomRecord()
{
}
+std::string PyGlomRecord::get_table_name() const
+{
+ return m_table_name;
+}
+
boost::python::object PyGlomRecord::get_connection()
{
boost::python::object result;
if(m_connection)
{
- PyObject* cobject = pygobject_new( G_OBJECT(m_connection->gobj()) ); //Creates a pygda Connection object.
+ PyObject* cobject = 0; //TODO: pygobject_new( G_OBJECT(m_connection->gobj()) ); //Creates a pygda Connection object.
result = boost::python::object( boost::python::borrowed(cobject) );
}
diff --git a/glom/libglom/python_embed/py_glom_record.h b/glom/libglom/python_embed/py_glom_record.h
index a82953b..f541768 100644
--- a/glom/libglom/python_embed/py_glom_record.h
+++ b/glom/libglom/python_embed/py_glom_record.h
@@ -21,9 +21,6 @@
#ifndef GLOM_PYTHON_GLOM_RECORD_H
#define GLOM_PYTHON_GLOM_RECORD_H
-#define NO_IMPORT_PYGOBJECT //To avoid a multiple definition in pygtk.
-#include <pygobject.h> //For the PyGObject and PyGBoxed struct definitions.
-
#include <boost/python.hpp>
#include <libglom/document/document.h>
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.h b/glom/libglom/python_embed/py_glom_relatedrecord.h
index 855aba1..caee847 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.h
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.h
@@ -21,9 +21,6 @@
#ifndef GLOM_PYTHON_GLOM_RELATEDRECORD_H
#define GLOM_PYTHON_GLOM_RELATEDRECORD_H
-#define NO_IMPORT_PYGOBJECT //To avoid a multiple definition in pygtk.
-#include <pygobject.h> //For the PyGObject and PyGBoxed struct definitions.
-
#include <boost/python.hpp>
#include <libglom/document/document.h>
diff --git a/glom/libglom/python_embed/pygdavalue_conversions.cc b/glom/libglom/python_embed/pygdavalue_conversions.cc
index 0428ade..50eaf4c 100644
--- a/glom/libglom/python_embed/pygdavalue_conversions.cc
+++ b/glom/libglom/python_embed/pygdavalue_conversions.cc
@@ -1,9 +1,6 @@
-#include <Python.h>
-#if PY_VERSION_HEX >= 0x02040000
-# include <datetime.h> /* From Python */
-#endif
-#include "pygdavalue_conversions.h"
+#include <boost/python.hpp>
+#include "pygdavalue_conversions.h"
#include <iostream>
@@ -16,41 +13,63 @@
* GValue. If the Python object can't be converted to the
* type of the GValue, then an error is returned.
*
- * Returns: 0 on success, -1 on error.
+ * Returns: true for success.
*/
-int
-glom_pygda_value_from_pyobject(GValue *boxed, PyObject *input)
+bool
+glom_pygda_value_from_pyobject(GValue *boxed, const boost::python::object& input)
{
- // We shouldn't need to call PyDateTime_IMPORT again,
- // after already doing it in libglom_init(),
- // but PyDate_Check crashes (with valgrind warnings) if we don't.
- //TODO: PyDateTime_IMPORT; //A macro, needed to use PyDate_Check(), PyDateTime_Check(), etc.
- //g_assert(PyDateTimeAPI); //This should have been set by the PyDateTime_IMPORT macro.
-
/* Use an appropriate gda_value_set_*() function.
We can not know what GValue type is actually wanted, so
we must still have the get_*() functions in the python API.
*/
- if (G_IS_VALUE (boxed)) g_value_unset(boxed);
- if (input == Py_None) {
- /* Leave value uninitialized to represent NULL value */
- } else if (PyString_Check (input)) {
- const char* text = PyString_AsString (input);
- g_value_init (boxed, G_TYPE_STRING);
- g_value_set_string (boxed, text);
- } else if (PyInt_Check (input)) {
+ if (G_IS_VALUE (boxed))
+ g_value_unset(boxed);
+
+ boost::python::extract<std::string> extractor_string(input);
+ if(extractor_string.check())
+ {
+ const std::string str = extractor_string;
+ g_value_init(boxed, G_TYPE_STRING);
+ g_value_set_string(boxed, str.c_str());
+ return true;
+ }
+
+ boost::python::extract<int> extractor_int(input);
+ if(extractor_int.check())
+ {
+ const int val = extractor_int;
g_value_init (boxed, G_TYPE_INT);
- g_value_set_int (boxed, PyInt_AsLong (input));
- } else if (PyLong_Check (input)) {
+ g_value_set_int (boxed, val);
+ return true;
+ }
+
+ boost::python::extract<long> extractor_long(input);
+ if(extractor_long.check())
+ {
+ const long val = extractor_long;
g_value_init (boxed, G_TYPE_INT);
- g_value_set_int (boxed, PyInt_AsLong (input));
- } else if (PyFloat_Check (input)) {
+ g_value_set_int (boxed, val);
+ return true;
+ }
+
+ boost::python::extract<double> extractor_double(input);
+ if(extractor_double.check())
+ {
+ const double val = extractor_double;
g_value_init (boxed, G_TYPE_DOUBLE);
- g_value_set_double (boxed, PyFloat_AsDouble (input));
- } else if (PyBool_Check (input)) {
+ g_value_set_double (boxed, val);
+ return true;
+ }
+
+ boost::python::extract<bool> extractor_bool(input);
+ if(extractor_bool.check())
+ {
+ const bool val = extractor_bool;
g_value_init (boxed, G_TYPE_BOOLEAN);
- g_value_set_boolean (boxed, (input == Py_True));
+ g_value_set_boolean (boxed, val);
+ }
+/*
#if PY_VERSION_HEX >= 0x02040000
} else if (PyDateTime_Check (input)) {
GdaTimestamp gda;
@@ -78,12 +97,10 @@ glom_pygda_value_from_pyobject(GValue *boxed, PyObject *input)
gda.timezone = 0;
gda_value_set_time (boxed, &gda);
#endif
- } else {
- g_warning("Unhandled python type.");
- return -1; /* failed. */
- }
+*/
- return 0; /* success. */
+ g_warning("Unhandled python type.");
+ return false; /* failed. */
}
boost::python::object glom_pygda_value_as_boost_pyobject(const Glib::ValueBase& value)
diff --git a/glom/libglom/python_embed/pygdavalue_conversions.h b/glom/libglom/python_embed/pygdavalue_conversions.h
index b9af87f..e2e2780 100644
--- a/glom/libglom/python_embed/pygdavalue_conversions.h
+++ b/glom/libglom/python_embed/pygdavalue_conversions.h
@@ -8,8 +8,8 @@
#include <libgda/libgda.h>
#include <boost/python.hpp>
-int
-glom_pygda_value_from_pyobject(GValue *boxed, PyObject *input);
+bool
+glom_pygda_value_from_pyobject(GValue *boxed, const boost::python::object& input);
//PyObject *
//glom_pygda_value_as_pyobject(const GValue *value, gboolean copy_boxed);
diff --git a/glom/python_embed/glom_python.cc b/glom/python_embed/glom_python.cc
index 4568333..1492d65 100644
--- a/glom/python_embed/glom_python.cc
+++ b/glom/python_embed/glom_python.cc
@@ -25,8 +25,8 @@
#include <boost/python.hpp>
-#define NO_IMPORT_PYGOBJECT //To avoid a multiple definition in pygtk.
-#include <pygobject.h> //For the PyGObject and PyGBoxed struct definitions.
+//#define NO_IMPORT_PYGOBJECT //To avoid a multiple definition in pygtk.
+//#include <pygobject.h> //For the PyGObject and PyGBoxed struct definitions.
#include "glom_python.h"
#include <libglom/data_structure/glomconversions.h>
@@ -213,14 +213,14 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
{
//TODO: Is there a boost::python equivalent for Py_CompileString()?
PyObject* cObject = Py_CompileString(script.c_str(), name.c_str() /* "filename", for debugging info */, Py_file_input /* "start token" for multiple lines of code. */); //Returns a reference.
- boost::python::handle<> objectCompiled(cObject);
+ boost::python::handle<> objectCompiled(cObject); //Takes the reference.
if(!objectCompiled)
HandlePythonError();
cObject = PyImport_ExecCodeModule(const_cast<char*>(name.c_str()), cObject); //Returns a reference. //This should make it importable.
- boost::python::handle<> object(cObject);
+ boost::python::handle<> object(cObject); //Takes the reference.
if(!object)
HandlePythonError();
@@ -242,7 +242,7 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
//PyObject* module_glom_dict = PyModule_GetDict(module_glom);
//This seems to be different to PyGlomRecord_GetPyType() - we can PyObject_Call() this one to instantiate it.
- PyObject* module_glom_dictC = boost::python::extract<PyObject*>(module_glom_dict);
+ PyObject* module_glom_dictC = boost::python::get_managed_object(module_glom_dict, boost::python::tag);
PyObject* pyTypeGlomRecordC = PyDict_GetItemString(module_glom_dictC, (char*)"Record"); //TODO: Unref this?
if(!pyTypeGlomRecordC || !PyType_Check(pyTypeGlomRecordC))
{
@@ -250,7 +250,7 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
return valueResult; // don't crash
}
- boost::python::handle<> ref(pyTypeGlomRecordC);
+ boost::python::handle<> ref(pyTypeGlomRecordC); //To unref it later.
boost::python::object pyTypeGlomRecord(ref);
boost::python::object module_gda = boost::python::import("gda");
@@ -262,7 +262,16 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
//Create the function definition:
//PyObject* pyValue = PyRun_String(func_def.c_str(), Py_file_input, pDict.ptr(), pDict.ptr());
- boost::python::object pyValue = boost::python::eval(func_def.c_str(), pDict, pDict);
+ boost::python::object pyValue;
+ try
+ {
+ pyValue = boost::python::eval(func_def.c_str(), pDict, pDict); //TODO: This throws.
+ }
+ catch(const boost::python::error_already_set& ex)
+ {
+ ShowTrace();
+ }
+
if(!pyValue)
{
ShowTrace();
@@ -318,9 +327,11 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
bool object_is_gda_value = false;
GValue value = {0, {{0}}};
- const int test = glom_pygda_value_from_pyobject(&value, pyResult);
+ boost::python::handle<> handle(boost::python::borrowed(pyResult));
+ boost::python::object pyResultCpp(handle);
+ const bool test = glom_pygda_value_from_pyobject(&value, pyResultCpp);
- if(test == 0) //-1 means error.
+ if(test)
object_is_gda_value = true;
if(object_is_gda_value && G_IS_VALUE(&value))
diff --git a/glom/python_embed/python_module/py_glom_module.cc b/glom/python_embed/python_module/py_glom_module.cc
index 4ad0472..1dd7c02 100644
--- a/glom/python_embed/python_module/py_glom_module.cc
+++ b/glom/python_embed/python_module/py_glom_module.cc
@@ -31,7 +31,7 @@
using namespace Glom;
-BOOST_PYTHON_MODULE(glom)
+BOOST_PYTHON_MODULE(glom_1_14)
{
boost::python::class_<PyGlomRecord>("Record")
.add_property("table_name", &PyGlomRecord::get_table_name)
diff --git a/glom/python_embed/python_module/py_glom_module.h b/glom/python_embed/python_module/py_glom_module.h
index 1faa97e..aca23aa 100644
--- a/glom/python_embed/python_module/py_glom_module.h
+++ b/glom/python_embed/python_module/py_glom_module.h
@@ -37,7 +37,6 @@
* - field values: for instance, name = record.related["contacts"]["name_first"];
* - Summary functions: for instance, total = record.related["invoice_lines"].sum("price");
*/
-PyMODINIT_FUNC initglom_1_14(void);
diff --git a/tests/test_python_execute_func.cc b/tests/test_python_execute_func.cc
index 1cb8269..e4a4437 100644
--- a/tests/test_python_execute_func.cc
+++ b/tests/test_python_execute_func.cc
@@ -2,6 +2,8 @@
#include <glom/python_embed/glom_python.h>
#include <libglom/data_structure/glomconversions.h>
+#include <boost/python.hpp>
+
int main()
{
Glom::libglom_init(); //Also initializes python.
@@ -11,9 +13,24 @@ int main()
Glib::RefPtr<Gnome::Gda::Connection> connection;
//Execute a python function:
- const Gnome::Gda::Value value = Glom::glom_evaluate_python_function_implementation(
- Glom::Field::TYPE_TEXT, calculation, field_values,
- 0 /* document */, "" /* table name */, connection);
+ Gnome::Gda::Value value;
+ try
+ {
+ value = Glom::glom_evaluate_python_function_implementation(
+ Glom::Field::TYPE_TEXT, calculation, field_values,
+ 0 /* document */, "" /* table name */, connection);
+ }
+ catch(const std::exception& ex)
+ {
+ std::cerr << "Exception: " << ex.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+ catch(const boost::python::error_already_set& ex)
+ {
+ std::cerr << "Exception: boost::python::error_already_set" << std::endl;
+ return EXIT_FAILURE;
+ }
+
//std::cout << "type=" << g_type_name(value.get_value_type()) << std::endl;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]