[pygobject: 1/2] gio overrides: emit a warning when creating various dbus types without a constructor. Fixes #15



commit 27293ec8f7e9c11ed609afc1bf3e87cc602739cb
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Fri Jan 18 11:22:26 2019 +0100

    gio overrides: emit a warning when creating various dbus types without a constructor. Fixes #15
    
    We zero slice allocate them and the boxed copy/free functions don't handle that.
    They just use ref counting which leads to double free because we start with a zero
    refcount and the free funcs use g_free() while we allocate it with g_slice_alloc().

 gi/overrides/Gio.py         | 77 +++++++++++++++++++++++++++++++++++++++------
 tests/test_overrides_gio.py | 15 +++++++++
 2 files changed, 83 insertions(+), 9 deletions(-)
---
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py
index 5c19ef27..eafbae52 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -48,22 +48,81 @@ Application = override(Application)
 __all__.append('Application')
 
 
-class VolumeMonitor(Gio.VolumeMonitor):
+def _warn_init(cls, instead=None):
+
+    def new_init(self, *args, **kwargs):
+        super(cls, self).__init__(*args, **kwargs)
+        name = cls.__module__.rsplit(".", 1)[-1] + "." + cls.__name__
+        if instead:
+            warnings.warn(
+                ("%s shouldn't be instantiated directly, "
+                 "use %s instead." % (name, instead)),
+                PyGIWarning, stacklevel=2)
+        else:
+            warnings.warn(
+                "%s shouldn't be instantiated directly." % (name,),
+                PyGIWarning, stacklevel=2)
 
-    def __init__(self, *args, **kwargs):
-        super(VolumeMonitor, self).__init__(*args, **kwargs)
+    return new_init
 
-        # https://bugzilla.gnome.org/show_bug.cgi?id=744690
-        warnings.warn(
-            "Gio.VolumeMonitor shouldn't be instantiated directly, "
-            "use Gio.VolumeMonitor.get() instead.",
-            PyGIWarning, stacklevel=2)
+
+@override
+class VolumeMonitor(Gio.VolumeMonitor):
+    # https://bugzilla.gnome.org/show_bug.cgi?id=744690
+    __init__ = _warn_init(Gio.VolumeMonitor, "Gio.VolumeMonitor.get()")
 
 
-VolumeMonitor = override(VolumeMonitor)
 __all__.append('VolumeMonitor')
 
 
+@override
+class DBusAnnotationInfo(Gio.DBusAnnotationInfo):
+    __init__ = _warn_init(Gio.DBusAnnotationInfo)
+
+
+__all__.append('DBusAnnotationInfo')
+
+
+@override
+class DBusArgInfo(Gio.DBusArgInfo):
+    __init__ = _warn_init(Gio.DBusArgInfo)
+
+
+__all__.append('DBusArgInfo')
+
+
+@override
+class DBusMethodInfo(Gio.DBusMethodInfo):
+    __init__ = _warn_init(Gio.DBusMethodInfo)
+
+
+__all__.append('DBusMethodInfo')
+
+
+@override
+class DBusSignalInfo(Gio.DBusSignalInfo):
+    __init__ = _warn_init(Gio.DBusSignalInfo)
+
+
+__all__.append('DBusSignalInfo')
+
+
+@override
+class DBusInterfaceInfo(Gio.DBusInterfaceInfo):
+    __init__ = _warn_init(Gio.DBusInterfaceInfo)
+
+
+__all__.append('DBusInterfaceInfo')
+
+
+@override
+class DBusNodeInfo(Gio.DBusNodeInfo):
+    __init__ = _warn_init(Gio.DBusNodeInfo)
+
+
+__all__.append('DBusNodeInfo')
+
+
 class ActionMap(Gio.ActionMap):
     def add_action_entries(self, entries, user_data=None):
         """
diff --git a/tests/test_overrides_gio.py b/tests/test_overrides_gio.py
index b6516f9b..8612d51e 100644
--- a/tests/test_overrides_gio.py
+++ b/tests/test_overrides_gio.py
@@ -2,10 +2,12 @@ from __future__ import absolute_import
 
 import random
 import platform
+import warnings
 
 import pytest
 
 from gi.repository import Gio, GObject
+from gi import PyGIWarning
 from gi._compat import cmp
 
 
@@ -344,3 +346,16 @@ def test_action_map_add_action_entries():
 
     actionmap.activate_action("simple")
     assert test_data[0] == 'test back'
+
+
+def test_types_init_warn():
+    types = [
+        Gio.DBusAnnotationInfo, Gio.DBusArgInfo, Gio.DBusMethodInfo,
+        Gio.DBusSignalInfo, Gio.DBusInterfaceInfo, Gio.DBusNodeInfo,
+    ]
+
+    for t in types:
+        with warnings.catch_warnings(record=True) as warn:
+            warnings.simplefilter('always')
+            t()
+            assert issubclass(warn[0].category, PyGIWarning)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]