[glom] Fix use of bool python return types.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Fix use of bool python return types.
- Date: Fri, 8 Apr 2011 15:33:19 +0000 (UTC)
commit 3e67959eec75498e0a405d611211a2afaa887985
Author: Murray Cumming <murrayc murrayc com>
Date: Fri Apr 8 17:33:02 2011 +0200
Fix use of bool python return types.
* glom/libglom/python_embed/pygdavalue_conversions.cc:
glom_pygda_value_from_pyobject(): Use the C Py*_Check() functions because
boost::python::extract<>::check() does not really check for the exact type
and has no way to do that. Previously we were interpreting bools as ints.
Note also that the order fo the Py*_Check() checks is important, because
python considers bool to be derived from int.
* tests/python/test_python_execute_func_with_record.cc: Uncomment the checks
for the return type and value now that it works.
ChangeLog | 13 +++
.../libglom/python_embed/pygdavalue_conversions.cc | 102 ++++++++++++--------
.../python/test_python_execute_func_with_record.cc | 8 +-
3 files changed, 78 insertions(+), 45 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d070b2f..2b05a87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-04-08 Murray Cumming <murrayc murrayc com>
+
+ Fix use of bool python return types.
+
+ * glom/libglom/python_embed/pygdavalue_conversions.cc:
+ glom_pygda_value_from_pyobject(): Use the C Py*_Check() functions because
+ boost::python::extract<>::check() does not really check for the exact type
+ and has no way to do that. Previously we were interpreting bools as ints.
+ Note also that the order fo the Py*_Check() checks is important, because
+ python considers bool to be derived from int.
+ * tests/python/test_python_execute_func_with_record.cc: Uncomment the checks
+ for the return type and value now that it works.
+
2011-04-07 Murray Cumming <murrayc murrayc com>
Initialize pygobject, to fix the use of the PyRecord API.
diff --git a/glom/libglom/python_embed/pygdavalue_conversions.cc b/glom/libglom/python_embed/pygdavalue_conversions.cc
index 93b1730..80ffc1b 100644
--- a/glom/libglom/python_embed/pygdavalue_conversions.cc
+++ b/glom/libglom/python_embed/pygdavalue_conversions.cc
@@ -31,54 +31,72 @@ glom_pygda_value_from_pyobject(GValue* boxed, const boost::python::object& input
if (G_IS_VALUE (boxed))
g_value_unset(boxed);
-
- boost::python::extract<std::string> extractor_string(input);
- if(extractor_string.check())
+
+ PyObject* input_c = input.ptr();
+
+ //We check for bool first,
+ //because bool is derived from int in Python,
+ //so PyInt_Check() would also succeed on a bool object.
+ if(PyBool_Check(input_c))
{
- 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<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, val);
+ return true;
+ }
}
-
- //TODO: This also succeeds if the Python type is a bool,
- //but we don't want to do that.
- boost::python::extract<int> extractor_int(input);
- if(extractor_int.check())
+
+ if(PyInt_Check(input_c))
{
- const int val = extractor_int;
- g_value_init (boxed, G_TYPE_INT);
- g_value_set_int (boxed, val);
- 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, val);
+ return true;
+ }
}
- boost::python::extract<long> extractor_long(input);
- if(extractor_long.check())
+ if(PyLong_Check(input_c))
{
- const long val = extractor_long;
- g_value_init (boxed, G_TYPE_INT);
- 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, val);
+ return true;
+ }
}
-
- boost::python::extract<double> extractor_double(input);
- if(extractor_double.check())
+
+ if(PyFloat_Check(input_c))
{
- const double val = extractor_double;
- g_value_init (boxed, G_TYPE_DOUBLE);
- g_value_set_double (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, val);
+ return true;
+ }
}
-
- boost::python::extract<bool> extractor_bool(input);
- if(extractor_bool.check())
+
+ if(PyString_Check(input_c))
{
- const bool val = extractor_bool;
- g_value_init (boxed, G_TYPE_BOOLEAN);
- g_value_set_boolean (boxed, val);
- return true;
+ 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;
+ }
}
-
+
#if PY_VERSION_HEX >= 0x02040000
//TODO: Remove this redefine when Python fixes the compiler error in their macro:
// http://bugs.python.org/issue7463
@@ -91,8 +109,8 @@ glom_pygda_value_from_pyobject(GValue* boxed, const boost::python::object& input
if(PyDateTimeAPI) //This should have been set but it can fail: https://bugzilla.gnome.org/show_bug.cgi?id=644702
{
//TODO: Find some way to do this with boost::python
- PyObject* input_c = input.ptr();
- if (PyDateTime_Check (input_c)) {
+ if(PyDateTime_Check (input_c))
+ {
GdaTimestamp gda;
gda.year = PyDateTime_GET_YEAR(input_c);
gda.month = PyDateTime_GET_MONTH(input_c);
@@ -103,7 +121,8 @@ glom_pygda_value_from_pyobject(GValue* boxed, const boost::python::object& input
gda.timezone = 0;
gda_value_set_timestamp (boxed, &gda);
return true;
- } else if (PyDate_Check (input_c)) {
+ } else if(PyDate_Check (input_c))
+ {
GDate *gda = g_date_new_dmy(
PyDateTime_GET_DAY(input_c),
(GDateMonth)PyDateTime_GET_MONTH(input_c),
@@ -112,7 +131,8 @@ glom_pygda_value_from_pyobject(GValue* boxed, const boost::python::object& input
g_value_set_boxed(boxed, gda);
g_date_free(gda);
return true;
- } else if (PyTime_Check (input_c)) {
+ } else if(PyTime_Check (input_c))
+ {
GdaTime gda;
gda.hour = PyDateTime_TIME_GET_HOUR(input_c);
gda.minute = PyDateTime_TIME_GET_MINUTE(input_c);
diff --git a/tests/python/test_python_execute_func_with_record.cc b/tests/python/test_python_execute_func_with_record.cc
index 5be1448..c2b96c3 100644
--- a/tests/python/test_python_execute_func_with_record.cc
+++ b/tests/python/test_python_execute_func_with_record.cc
@@ -122,13 +122,13 @@ int main()
}
//Check that the return value is of the expected type:
- //g_assert(value.get_value_type() == G_TYPE_BOOLEAN);
+ g_assert(value.get_value_type() == G_TYPE_BOOLEAN);
//Check that the return value is of the expected value:
- //const double boolval = value.get_boolean();
- //g_assert(boolval == true);
+ const double boolval = value.get_boolean();
+ g_assert(boolval == true);
- std::cout << "value=" << value.to_string() << std::endl;
+ //std::cout << "value=" << value.to_string() << std::endl;
cleanup();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]