[pygobject] _pygi_argument_from_object(): Check for compatible data type
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] _pygi_argument_from_object(): Check for compatible data type
- Date: Mon, 7 May 2012 01:05:57 +0000 (UTC)
commit 168a08753cec1ff77ccca5d81b9a5fd2af5d3720
Author: Martin Pitt <martinpitt gnome org>
Date: Sun May 6 18:02:04 2012 -0700
_pygi_argument_from_object(): Check for compatible data type
Verify that the passed PyObject actually matches the expected type of the
argument. With this, trying to assign a wrong type to a property will now raise
a proper TypeError.
gi/pygi-argument.c | 39 +++++++++++++++++++++++++++++++++++++++
gi/pygi-property.c | 3 +++
tests/test_gi.py | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 0 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 64602f2..ca88911 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -728,6 +728,12 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *int_;
+ if (!PyObject_TypeCheck (object, &PyInt_Type) &&
+ !PyObject_TypeCheck (object, &PyLong_Type)) {
+ PyErr_SetString (PyExc_TypeError, "expected int or long argument");
+ break;
+ }
+
int_ = PYGLIB_PyNumber_Long (object);
if (int_ == NULL) {
break;
@@ -752,6 +758,12 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
guint64 value;
+ if (!PyObject_TypeCheck (object, &PyInt_Type) &&
+ !PyObject_TypeCheck (object, &PyLong_Type)) {
+ PyErr_SetString (PyExc_TypeError, "expected int or long argument");
+ break;
+ }
+
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
@@ -782,6 +794,12 @@ _pygi_argument_from_object (PyObject *object,
PyObject *number;
gint64 value;
+ if (!PyObject_TypeCheck (object, &PyInt_Type) &&
+ !PyObject_TypeCheck (object, &PyLong_Type)) {
+ PyErr_SetString (PyExc_TypeError, "expected int or long argument");
+ break;
+ }
+
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
break;
@@ -804,6 +822,13 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *float_;
+ if (!PyObject_TypeCheck (object, &PyFloat_Type) &&
+ !PyObject_TypeCheck (object, &PyInt_Type) &&
+ !PyObject_TypeCheck (object, &PyLong_Type)) {
+ PyErr_SetString (PyExc_TypeError, "expected float or int argument");
+ break;
+ }
+
float_ = PyNumber_Float (object);
if (float_ == NULL) {
break;
@@ -818,6 +843,13 @@ _pygi_argument_from_object (PyObject *object,
{
PyObject *float_;
+ if (!PyObject_TypeCheck (object, &PyFloat_Type) &&
+ !PyObject_TypeCheck (object, &PyInt_Type) &&
+ !PyObject_TypeCheck (object, &PyLong_Type)) {
+ PyErr_SetString (PyExc_TypeError, "expected float or int argument");
+ break;
+ }
+
float_ = PyNumber_Float (object);
if (float_ == NULL) {
break;
@@ -951,6 +983,13 @@ _pygi_argument_from_object (PyObject *object,
break;
}
+ /* Note, strings are sequences, but we cannot accept them here */
+ if (!PySequence_Check (object) ||
+ PyString_Check (object) || PyUnicode_Check (object)) {
+ PyErr_SetString (PyExc_TypeError, "expected sequence");
+ break;
+ }
+
length = PySequence_Length (object);
if (length < 0) {
break;
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
index 06f7b02..56a9745 100644
--- a/gi/pygi-property.c
+++ b/gi/pygi-property.c
@@ -287,6 +287,9 @@ pygi_set_property_value_real (PyGObject *instance,
transfer = g_property_info_get_ownership_transfer (property_info);
arg = _pygi_argument_from_object (py_value, type_info, transfer);
+ if (PyErr_Occurred())
+ goto out;
+
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
// FIXME: Lots of types still unhandled
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 0c67623..572d438 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -2021,6 +2021,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_int=-42)
self.assertEqual(obj.props.some_int, -42)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_int', None)
+
+ self.assertEqual(obj.props.some_int, -42)
+
def test_uint(self):
self.assertEqual(self.obj.props.some_uint, 0)
self.obj.props.some_uint = GObject.G_MAXUINT
@@ -2029,6 +2034,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_uint=42)
self.assertEqual(obj.props.some_uint, 42)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_uint', None)
+
+ self.assertEqual(obj.props.some_uint, 42)
+
def test_long(self):
self.assertEqual(self.obj.props.some_long, 0)
self.obj.props.some_long = GObject.G_MAXLONG
@@ -2037,6 +2047,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_long=-42)
self.assertEqual(obj.props.some_long, -42)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_long', None)
+
+ self.assertEqual(obj.props.some_long, -42)
+
def test_ulong(self):
self.assertEqual(self.obj.props.some_ulong, 0)
self.obj.props.some_ulong = GObject.G_MAXULONG
@@ -2045,6 +2060,11 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
self.assertEqual(obj.props.some_ulong, 42)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_ulong', None)
+
+ self.assertEqual(obj.props.some_ulong, 42)
+
def test_int64(self):
self.assertEqual(self.obj.props.some_int64, 0)
self.obj.props.some_int64 = GObject.G_MAXINT64
@@ -2069,6 +2089,14 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
self.assertAlmostEqual(obj.props.some_float, 42.42, 4)
+ obj = GIMarshallingTests.PropertiesObject(some_float=42)
+ self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_float', None)
+
+ self.assertAlmostEqual(obj.props.some_float, 42.0, 4)
+
def test_double(self):
self.assertEqual(self.obj.props.some_double, 0)
self.obj.props.some_double = GObject.G_MAXDOUBLE
@@ -2077,13 +2105,25 @@ class TestPropertiesObject(unittest.TestCase):
obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
self.assertAlmostEqual(obj.props.some_double, 42.42)
+ obj = GIMarshallingTests.PropertiesObject(some_double=42)
+ self.assertAlmostEqual(obj.props.some_double, 42.0)
+
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', 'foo')
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_double', None)
+
+ self.assertAlmostEqual(obj.props.some_double, 42.0)
+
def test_strv(self):
self.assertEqual(self.obj.props.some_strv, [])
self.obj.props.some_strv = ['hello', 'world']
self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 1)
+ self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', 'foo')
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', [1, 2])
self.assertRaises(TypeError, setattr, self.obj.props, 'some_strv', ['foo', 1])
+ self.assertEqual(self.obj.props.some_strv, ['hello', 'world'])
+
obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
self.assertEqual(obj.props.some_strv, ['hello', 'world'])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]