[pygobject] Add type checking to positional Gtk.Box and Gtk.Window ctor arguments
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Add type checking to positional Gtk.Box and Gtk.Window ctor arguments
- Date: Tue, 5 Nov 2013 14:30:28 +0000 (UTC)
commit 7193f0509a0ed7da7c810daa6733e34a22db3180
Author: Martin Pitt <martinpitt gnome org>
Date: Tue Nov 5 15:28:12 2013 +0100
Add type checking to positional Gtk.Box and Gtk.Window ctor arguments
Gtk.Box and Gtk.Window are base classes of a lot of widgets. Avoid confusion
when trying to create a subclass of them through the GObject constructor with
positional arguments by at least verifying that their type is right. Otherwise
you can do things like
chooser = Gtk.FileChooserWidget(Gtk.FileChooserAction.SELECT_FOLDER)
which succeeds, but does not have the desired effect (it sets the "homogenous"
property of the Gtk.Box superclass instead).
https://bugzilla.gnome.org/show_bug.cgi?id=711487
gi/overrides/Gtk.py | 7 +++++++
tests/test_overrides_gtk.py | 18 ++++++++++++++++++
tests/test_properties.py | 9 +++++++++
3 files changed, 34 insertions(+), 0 deletions(-)
---
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index e774c0c..9f08492 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -330,6 +330,10 @@ __all__.append('ComboBox')
class Box(Gtk.Box):
def __init__(self, homogeneous=False, spacing=0, **kwds):
+ if not isinstance(homogeneous, bool):
+ raise TypeError('homogeneous argument must be of type bool')
+ if not isinstance(spacing, int):
+ raise TypeError('spacing argument must be of type int')
super(Box, self).__init__(**kwds)
self.set_homogeneous(homogeneous)
self.set_spacing(spacing)
@@ -436,6 +440,9 @@ class Window(Gtk.Window):
if not initialized:
raise RuntimeError("Gtk couldn't be initialized")
+ if not isinstance(type, Gtk.WindowType):
+ raise TypeError('type argument must be of type Gtk.WindowType')
+
# type is a construct-only property; if it is already set (e. g. by
# GtkBuilder), do not try to set it again and just ignore it
try:
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index fefc9a8..145f0f9 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -590,6 +590,24 @@ class TestGtk(unittest.TestCase):
GLib.timeout_add(100, Gtk.main_quit, 'hello')
Gtk.main()
+ def test_gobject_ctor_positional_args(self):
+ # GObject constructor must only allow keyword args, except for the ones
+ # which have overrides
+
+ # overridden, but no custom constructor
+ self.assertRaises(TypeError, Gtk.Widget, 1)
+ self.assertRaises(TypeError, Gtk.Container, 1)
+
+ # no overrides at all
+ self.assertRaises(TypeError, Gtk.FileChooserWidget,
+ Gtk.FileChooserAction.SELECT_FOLDER)
+ self.assertRaises(TypeError, Gtk.Assistant, 1)
+
+ def test_gobject_ctor_unknown_property(self):
+ # GObject constructor must refuse unknown properties
+ self.assertRaises(TypeError, Gtk.Widget, unknown_prop=1)
+ self.assertRaises(TypeError, Gtk.Button, unknown_prop='a')
+
@unittest.skipUnless(Gtk, 'Gtk not available')
class TestSignals(unittest.TestCase):
diff --git a/tests/test_properties.py b/tests/test_properties.py
index ef6b867..ec9ddf1 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -481,6 +481,15 @@ class TestPropertyObject(unittest.TestCase):
self.assertEqual(normal, "foo")
self.assertEqual(uint64, 7)
+ def test_positional_args(self):
+ # GObject constructor must only allow keyword args
+ self.assertRaises(TypeError, new, PropertyObject, None)
+ self.assertRaises(TypeError, new, PropertyObject, "hello", 2)
+
+ def test_unknown_constructor_property(self):
+ # GObject constructor must refuse unknown properties
+ self.assertRaises(TypeError, new, PropertyObject, unknown_prop=1)
+
class TestProperty(unittest.TestCase):
def test_simple(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]