From 27293ec8f7e9c11ed609afc1bf3e87cc602739cb Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 18 Jan 2019 11:22:26 +0100 Subject: 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) -- cgit v1.2.1