1# -*- Mode: Python; py-indent-offset: 4 -*-
2# vim: tabstop=4 shiftwidth=4 expandtab
3#
4# Copyright (C) 2012 Canonical Ltd.
5# Author: Martin Pitt <martin.pitt@ubuntu.com>
6# Copyright (C) 2012-2013 Simon Feltman <sfeltman@src.gnome.org>
7# Copyright (C) 2012 Bastian Winkler <buz@netbuz.org>
8#
9# This library is free software; you can redistribute it and/or
10# modify it under the terms of the GNU Lesser General Public
11# License as published by the Free Software Foundation; either
12# version 2.1 of the License, or (at your option) any later version.
13#
14# This library is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17# Lesser General Public License for more details.
18#
19# You should have received a copy of the GNU Lesser General Public
20# License along with this library; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
22# USA
23
24import functools
25import warnings
26from collections import namedtuple
27
28import gi.module
29from gi.overrides import override, deprecated_attr
30from gi.repository import GLib
31from gi import PyGIDeprecationWarning
32from gi import _propertyhelper as propertyhelper
33from gi import _signalhelper as signalhelper
34from gi import _gi
35
36
37GObjectModule = gi.module.get_introspection_module('GObject')
38
39__all__ = []
40
41
42from gi import _option as option
43option = option
44
45
46# API aliases for backwards compatibility
47for name in ['markup_escape_text', 'get_application_name',
48             'set_application_name', 'get_prgname', 'set_prgname',
49             'main_depth', 'filename_display_basename',
50             'filename_display_name', 'filename_from_utf8',
51             'uri_list_extract_uris',
52             'MainLoop', 'MainContext', 'main_context_default',
53             'source_remove', 'Source', 'Idle', 'Timeout', 'PollFD',
54             'idle_add', 'timeout_add', 'timeout_add_seconds',
55             'io_add_watch', 'child_watch_add', 'get_current_time',
56             'spawn_async']:
57    globals()[name] = getattr(GLib, name)
58    deprecated_attr("GObject", name, "GLib." + name)
59    __all__.append(name)
60
61# deprecated constants
62for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
63             'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
64             'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
65             'IO_STATUS_ERROR', 'IO_STATUS_NORMAL', 'IO_STATUS_EOF',
66             'IO_STATUS_AGAIN', 'IO_FLAG_APPEND', 'IO_FLAG_NONBLOCK',
67             'IO_FLAG_IS_READABLE', 'IO_FLAG_IS_WRITEABLE',
68             'IO_FLAG_IS_SEEKABLE', 'IO_FLAG_MASK', 'IO_FLAG_GET_MASK',
69             'IO_FLAG_SET_MASK',
70             'SPAWN_LEAVE_DESCRIPTORS_OPEN', 'SPAWN_DO_NOT_REAP_CHILD',
71             'SPAWN_SEARCH_PATH', 'SPAWN_STDOUT_TO_DEV_NULL',
72             'SPAWN_STDERR_TO_DEV_NULL', 'SPAWN_CHILD_INHERITS_STDIN',
73             'SPAWN_FILE_AND_ARGV_ZERO',
74             'OPTION_FLAG_HIDDEN', 'OPTION_FLAG_IN_MAIN', 'OPTION_FLAG_REVERSE',
75             'OPTION_FLAG_NO_ARG', 'OPTION_FLAG_FILENAME', 'OPTION_FLAG_OPTIONAL_ARG',
76             'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
77             'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
78             'glib_version']:
79    with warnings.catch_warnings():
80        # TODO: this uses deprecated Glib attributes, silence for now
81        warnings.simplefilter('ignore', PyGIDeprecationWarning)
82        globals()[name] = getattr(GLib, name)
83    deprecated_attr("GObject", name, "GLib." + name)
84    __all__.append(name)
85
86
87for name in ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
88             'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
89             'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']:
90    new_name = name.split("_", 1)[-1]
91    globals()[name] = getattr(GLib, new_name)
92    deprecated_attr("GObject", name, "GLib." + new_name)
93    __all__.append(name)
94
95# these are not currently exported in GLib gir, presumably because they are
96# platform dependent; so get them from our static bindings
97for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
98             'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
99             'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
100             'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
101    new_name = name.split("_", 1)[-1]
102    globals()[name] = getattr(GLib, new_name)
103    deprecated_attr("GObject", name, "GLib." + new_name)
104    __all__.append(name)
105
106
107TYPE_INVALID = GObjectModule.type_from_name('invalid')
108TYPE_NONE = GObjectModule.type_from_name('void')
109TYPE_INTERFACE = GObjectModule.type_from_name('GInterface')
110TYPE_CHAR = GObjectModule.type_from_name('gchar')
111TYPE_UCHAR = GObjectModule.type_from_name('guchar')
112TYPE_BOOLEAN = GObjectModule.type_from_name('gboolean')
113TYPE_INT = GObjectModule.type_from_name('gint')
114TYPE_UINT = GObjectModule.type_from_name('guint')
115TYPE_LONG = GObjectModule.type_from_name('glong')
116TYPE_ULONG = GObjectModule.type_from_name('gulong')
117TYPE_INT64 = GObjectModule.type_from_name('gint64')
118TYPE_UINT64 = GObjectModule.type_from_name('guint64')
119TYPE_ENUM = GObjectModule.type_from_name('GEnum')
120TYPE_FLAGS = GObjectModule.type_from_name('GFlags')
121TYPE_FLOAT = GObjectModule.type_from_name('gfloat')
122TYPE_DOUBLE = GObjectModule.type_from_name('gdouble')
123TYPE_STRING = GObjectModule.type_from_name('gchararray')
124TYPE_POINTER = GObjectModule.type_from_name('gpointer')
125TYPE_BOXED = GObjectModule.type_from_name('GBoxed')
126TYPE_PARAM = GObjectModule.type_from_name('GParam')
127TYPE_OBJECT = GObjectModule.type_from_name('GObject')
128TYPE_PYOBJECT = GObjectModule.type_from_name('PyObject')
129TYPE_GTYPE = GObjectModule.type_from_name('GType')
130TYPE_STRV = GObjectModule.type_from_name('GStrv')
131TYPE_VARIANT = GObjectModule.type_from_name('GVariant')
132TYPE_GSTRING = GObjectModule.type_from_name('GString')
133TYPE_VALUE = GObjectModule.Value.__gtype__
134TYPE_UNICHAR = TYPE_UINT
135__all__ += ['TYPE_INVALID', 'TYPE_NONE', 'TYPE_INTERFACE', 'TYPE_CHAR',
136            'TYPE_UCHAR', 'TYPE_BOOLEAN', 'TYPE_INT', 'TYPE_UINT', 'TYPE_LONG',
137            'TYPE_ULONG', 'TYPE_INT64', 'TYPE_UINT64', 'TYPE_ENUM', 'TYPE_FLAGS',
138            'TYPE_FLOAT', 'TYPE_DOUBLE', 'TYPE_STRING', 'TYPE_POINTER',
139            'TYPE_BOXED', 'TYPE_PARAM', 'TYPE_OBJECT', 'TYPE_PYOBJECT',
140            'TYPE_GTYPE', 'TYPE_STRV', 'TYPE_VARIANT', 'TYPE_GSTRING',
141            'TYPE_UNICHAR', 'TYPE_VALUE']
142
143
144# Deprecated, use GLib directly
145for name in ['Pid', 'GError', 'OptionGroup', 'OptionContext']:
146    globals()[name] = getattr(GLib, name)
147    deprecated_attr("GObject", name, "GLib." + name)
148    __all__.append(name)
149
150
151# Deprecated, use: GObject.ParamFlags.* directly
152for name in ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
153             'PARAM_READABLE', 'PARAM_WRITABLE']:
154    new_name = name.split("_", 1)[-1]
155    globals()[name] = getattr(GObjectModule.ParamFlags, new_name)
156    deprecated_attr("GObject", name, "GObject.ParamFlags." + new_name)
157    __all__.append(name)
158
159# PARAM_READWRITE should come from the gi module but cannot due to:
160# https://gitlab.gnome.org/GNOME/gobject-introspection/issues/75
161PARAM_READWRITE = GObjectModule.ParamFlags.READABLE | \
162    GObjectModule.ParamFlags.WRITABLE
163deprecated_attr("GObject", "PARAM_READWRITE", "GObject.ParamFlags.READWRITE")
164__all__.append("PARAM_READWRITE")
165
166
167# Deprecated, use: GObject.SignalFlags.* directly
168for name in ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
169             'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
170             'SIGNAL_RUN_LAST']:
171    new_name = name.split("_", 1)[-1]
172    globals()[name] = getattr(GObjectModule.SignalFlags, new_name)
173    deprecated_attr("GObject", name, "GObject.SignalFlags." + new_name)
174    __all__.append(name)
175
176# Static types
177GBoxed = _gi.GBoxed
178GEnum = _gi.GEnum
179GFlags = _gi.GFlags
180GInterface = _gi.GInterface
181GObject = _gi.GObject
182GObjectWeakRef = _gi.GObjectWeakRef
183GParamSpec = _gi.GParamSpec
184GPointer = _gi.GPointer
185GType = _gi.GType
186Warning = _gi.Warning
187__all__ += ['GBoxed', 'GEnum', 'GFlags', 'GInterface', 'GObject',
188            'GObjectWeakRef', 'GParamSpec', 'GPointer', 'GType',
189            'Warning']
190
191
192features = {'generic-c-marshaller': True}
193list_properties = _gi.list_properties
194new = _gi.new
195pygobject_version = _gi.pygobject_version
196threads_init = GLib.threads_init
197type_register = _gi.type_register
198__all__ += ['features', 'list_properties', 'new',
199            'pygobject_version', 'threads_init', 'type_register']
200
201
202class Value(GObjectModule.Value):
203    def __init__(self, value_type=None, py_value=None):
204        GObjectModule.Value.__init__(self)
205        if value_type is not None:
206            self.init(value_type)
207            if py_value is not None:
208                self.set_value(py_value)
209
210    @property
211    def __g_type(self):
212        # XXX: This is the same as self.g_type, but the field marshalling
213        # code is currently very slow.
214        return _gi._gvalue_get_type(self)
215
216    def set_boxed(self, boxed):
217        if not self.__g_type.is_a(TYPE_BOXED):
218            warnings.warn('Calling set_boxed() on a non-boxed type deprecated',
219                          PyGIDeprecationWarning, stacklevel=2)
220        # Workaround the introspection marshalers inability to know
221        # these methods should be marshaling boxed types. This is because
222        # the type information is stored on the GValue.
223        _gi._gvalue_set(self, boxed)
224
225    def get_boxed(self):
226        if not self.__g_type.is_a(TYPE_BOXED):
227            warnings.warn('Calling get_boxed() on a non-boxed type deprecated',
228                          PyGIDeprecationWarning, stacklevel=2)
229        return _gi._gvalue_get(self)
230
231    def set_value(self, py_value):
232        gtype = self.__g_type
233
234        if gtype == TYPE_CHAR:
235            self.set_char(py_value)
236        elif gtype == TYPE_UCHAR:
237            self.set_uchar(py_value)
238        elif gtype == TYPE_STRING:
239            if not isinstance(py_value, str) and py_value is not None:
240                raise TypeError("Expected string but got %s%s" %
241                                (py_value, type(py_value)))
242            _gi._gvalue_set(self, py_value)
243        elif gtype == TYPE_PARAM:
244            self.set_param(py_value)
245        elif gtype.is_a(TYPE_FLAGS):
246            self.set_flags(py_value)
247        elif gtype == TYPE_POINTER:
248            self.set_pointer(py_value)
249        elif gtype == TYPE_GTYPE:
250            self.set_gtype(py_value)
251        elif gtype == TYPE_VARIANT:
252            self.set_variant(py_value)
253        else:
254            # Fall back to _gvalue_set which handles some more cases
255            # like fundamentals for which a converter is registered
256            try:
257                _gi._gvalue_set(self, py_value)
258            except TypeError:
259                if gtype == TYPE_INVALID:
260                    raise TypeError("GObject.Value needs to be initialized first")
261                raise
262
263    def get_value(self):
264        gtype = self.__g_type
265
266        if gtype == TYPE_CHAR:
267            return self.get_char()
268        elif gtype == TYPE_UCHAR:
269            return self.get_uchar()
270        elif gtype == TYPE_PARAM:
271            return self.get_param()
272        elif gtype.is_a(TYPE_ENUM):
273            return self.get_enum()
274        elif gtype.is_a(TYPE_FLAGS):
275            return self.get_flags()
276        elif gtype == TYPE_POINTER:
277            return self.get_pointer()
278        elif gtype == TYPE_GTYPE:
279            return self.get_gtype()
280        elif gtype == TYPE_VARIANT:
281            # get_variant was missing annotations
282            # https://gitlab.gnome.org/GNOME/glib/merge_requests/492
283            return self.dup_variant()
284        else:
285            try:
286                return _gi._gvalue_get(self)
287            except TypeError:
288                if gtype == TYPE_INVALID:
289                    return None
290                raise
291
292    def __repr__(self):
293        return '<Value (%s) %s>' % (self.__g_type.name, self.get_value())
294
295
296Value = override(Value)
297__all__.append('Value')
298
299
300def type_from_name(name):
301    type_ = GObjectModule.type_from_name(name)
302    if type_ == TYPE_INVALID:
303        raise RuntimeError('unknown type name: %s' % name)
304    return type_
305
306
307__all__.append('type_from_name')
308
309
310def type_parent(type_):
311    parent = GObjectModule.type_parent(type_)
312    if parent == TYPE_INVALID:
313        raise RuntimeError('no parent for type')
314    return parent
315
316
317__all__.append('type_parent')
318
319
320def _validate_type_for_signal_method(type_):
321    if hasattr(type_, '__gtype__'):
322        type_ = type_.__gtype__
323    if not type_.is_instantiatable() and not type_.is_interface():
324        raise TypeError('type must be instantiable or an interface, got %s' % type_)
325
326
327def signal_list_ids(type_):
328    _validate_type_for_signal_method(type_)
329    return GObjectModule.signal_list_ids(type_)
330
331
332__all__.append('signal_list_ids')
333
334
335def signal_list_names(type_):
336    ids = signal_list_ids(type_)
337    return tuple(GObjectModule.signal_name(i) for i in ids)
338
339
340__all__.append('signal_list_names')
341
342
343def signal_lookup(name, type_):
344    _validate_type_for_signal_method(type_)
345    return GObjectModule.signal_lookup(name, type_)
346
347
348__all__.append('signal_lookup')
349
350
351SignalQuery = namedtuple('SignalQuery',
352                         ['signal_id',
353                          'signal_name',
354                          'itype',
355                          'signal_flags',
356                          'return_type',
357                          # n_params',
358                          'param_types'])
359
360
361def signal_query(id_or_name, type_=None):
362    if type_ is not None:
363        id_or_name = signal_lookup(id_or_name, type_)
364
365    res = GObjectModule.signal_query(id_or_name)
366    assert res is not None
367
368    if res.signal_id == 0:
369        return None
370
371    # Return a named tuple to allows indexing which is compatible with the
372    # static bindings along with field like access of the gi struct.
373    # Note however that the n_params was not returned from the static bindings
374    # so we must skip over it.
375    return SignalQuery(res.signal_id, res.signal_name, res.itype,
376                       res.signal_flags, res.return_type,
377                       tuple(res.param_types))
378
379
380__all__.append('signal_query')
381
382
383class _HandlerBlockManager(object):
384    def __init__(self, obj, handler_id):
385        self.obj = obj
386        self.handler_id = handler_id
387
388    def __enter__(self):
389        pass
390
391    def __exit__(self, exc_type, exc_value, traceback):
392        GObjectModule.signal_handler_unblock(self.obj, self.handler_id)
393
394
395def signal_handler_block(obj, handler_id):
396    """Blocks the signal handler from being invoked until
397    handler_unblock() is called.
398
399    :param GObject.Object obj:
400        Object instance to block handlers for.
401    :param int handler_id:
402        Id of signal to block.
403    :returns:
404        A context manager which optionally can be used to
405        automatically unblock the handler:
406
407    .. code-block:: python
408
409        with GObject.signal_handler_block(obj, id):
410            pass
411    """
412    GObjectModule.signal_handler_block(obj, handler_id)
413    return _HandlerBlockManager(obj, handler_id)
414
415
416__all__.append('signal_handler_block')
417
418
419def signal_parse_name(detailed_signal, itype, force_detail_quark):
420    """Parse a detailed signal name into (signal_id, detail).
421
422    :param str detailed_signal:
423        Signal name which can include detail.
424        For example: "notify:prop_name"
425    :returns:
426        Tuple of (signal_id, detail)
427    :raises ValueError:
428        If the given signal is unknown.
429    """
430    res, signal_id, detail = GObjectModule.signal_parse_name(detailed_signal, itype,
431                                                             force_detail_quark)
432    if res:
433        return signal_id, detail
434    else:
435        raise ValueError('%s: unknown signal name: %s' % (itype, detailed_signal))
436
437
438__all__.append('signal_parse_name')
439
440
441def remove_emission_hook(obj, detailed_signal, hook_id):
442    signal_id, detail = signal_parse_name(detailed_signal, obj, True)
443    GObjectModule.signal_remove_emission_hook(signal_id, hook_id)
444
445
446__all__.append('remove_emission_hook')
447
448
449# GObject accumulators with pure Python implementations
450# These return a tuple of (continue_emission, accumulation_result)
451
452def signal_accumulator_first_wins(ihint, return_accu, handler_return, user_data=None):
453    # Stop emission but return the result of the last handler
454    return (False, handler_return)
455
456
457__all__.append('signal_accumulator_first_wins')
458
459
460def signal_accumulator_true_handled(ihint, return_accu, handler_return, user_data=None):
461    # Stop emission if the last handler returns True
462    return (not handler_return, handler_return)
463
464
465__all__.append('signal_accumulator_true_handled')
466
467
468# Statically bound signal functions which need to clobber GI (for now)
469
470add_emission_hook = _gi.add_emission_hook
471signal_new = _gi.signal_new
472
473__all__ += ['add_emission_hook', 'signal_new']
474
475
476class _FreezeNotifyManager(object):
477    def __init__(self, obj):
478        self.obj = obj
479
480    def __enter__(self):
481        pass
482
483    def __exit__(self, exc_type, exc_value, traceback):
484        self.obj.thaw_notify()
485
486
487def _signalmethod(func):
488    # Function wrapper for signal functions used as instance methods.
489    # This is needed when the signal functions come directly from GI.
490    # (they are not already wrapped)
491    @functools.wraps(func)
492    def meth(*args, **kwargs):
493        return func(*args, **kwargs)
494    return meth
495
496
497class Object(GObjectModule.Object):
498    def _unsupported_method(self, *args, **kargs):
499        raise RuntimeError('This method is currently unsupported.')
500
501    def _unsupported_data_method(self, *args, **kargs):
502        raise RuntimeError('Data access methods are unsupported. '
503                           'Use normal Python attributes instead')
504
505    # Generic data methods are not needed in python as it can be handled
506    # with standard attribute access: https://bugzilla.gnome.org/show_bug.cgi?id=641944
507    get_data = _unsupported_data_method
508    get_qdata = _unsupported_data_method
509    set_data = _unsupported_data_method
510    steal_data = _unsupported_data_method
511    steal_qdata = _unsupported_data_method
512    replace_data = _unsupported_data_method
513    replace_qdata = _unsupported_data_method
514
515    # The following methods as unsupported until we verify
516    # they work as gi methods.
517    bind_property_full = _unsupported_method
518    compat_control = _unsupported_method
519    interface_find_property = _unsupported_method
520    interface_install_property = _unsupported_method
521    interface_list_properties = _unsupported_method
522    notify_by_pspec = _unsupported_method
523    run_dispose = _unsupported_method
524    watch_closure = _unsupported_method
525
526    # Make all reference management methods private but still accessible.
527    _ref = GObjectModule.Object.ref
528    _ref_sink = GObjectModule.Object.ref_sink
529    _unref = GObjectModule.Object.unref
530    _force_floating = GObjectModule.Object.force_floating
531
532    ref = _unsupported_method
533    ref_sink = _unsupported_method
534    unref = _unsupported_method
535    force_floating = _unsupported_method
536
537    # The following methods are static APIs which need to leap frog the
538    # gi methods until we verify the gi methods can replace them.
539    get_property = _gi.GObject.get_property
540    get_properties = _gi.GObject.get_properties
541    set_property = _gi.GObject.set_property
542    set_properties = _gi.GObject.set_properties
543    bind_property = _gi.GObject.bind_property
544    connect = _gi.GObject.connect
545    connect_after = _gi.GObject.connect_after
546    connect_object = _gi.GObject.connect_object
547    connect_object_after = _gi.GObject.connect_object_after
548    disconnect_by_func = _gi.GObject.disconnect_by_func
549    handler_block_by_func = _gi.GObject.handler_block_by_func
550    handler_unblock_by_func = _gi.GObject.handler_unblock_by_func
551    emit = _gi.GObject.emit
552    chain = _gi.GObject.chain
553    weak_ref = _gi.GObject.weak_ref
554    __copy__ = _gi.GObject.__copy__
555    __deepcopy__ = _gi.GObject.__deepcopy__
556
557    def freeze_notify(self):
558        """Freezes the object's property-changed notification queue.
559
560        :returns:
561            A context manager which optionally can be used to
562            automatically thaw notifications.
563
564        This will freeze the object so that "notify" signals are blocked until
565        the thaw_notify() method is called.
566
567        .. code-block:: python
568
569            with obj.freeze_notify():
570                pass
571        """
572        super(Object, self).freeze_notify()
573        return _FreezeNotifyManager(self)
574
575    def connect_data(self, detailed_signal, handler, *data, **kwargs):
576        """Connect a callback to the given signal with optional user data.
577
578        :param str detailed_signal:
579            A detailed signal to connect to.
580        :param callable handler:
581            Callback handler to connect to the signal.
582        :param *data:
583            Variable data which is passed through to the signal handler.
584        :param GObject.ConnectFlags connect_flags:
585            Flags used for connection options.
586        :returns:
587            A signal id which can be used with disconnect.
588        """
589        flags = kwargs.get('connect_flags', 0)
590        if flags & GObjectModule.ConnectFlags.AFTER:
591            connect_func = _gi.GObject.connect_after
592        else:
593            connect_func = _gi.GObject.connect
594
595        if flags & GObjectModule.ConnectFlags.SWAPPED:
596            if len(data) != 1:
597                raise ValueError('Using GObject.ConnectFlags.SWAPPED requires exactly '
598                                 'one argument for user data, got: %s' % [data])
599
600            def new_handler(obj, *args):
601                # Swap obj with the last element in args which will be the user
602                # data passed to the connect function.
603                args = list(args)
604                swap = args.pop()
605                args = args + [obj]
606                return handler(swap, *args)
607        else:
608            new_handler = handler
609
610        return connect_func(self, detailed_signal, new_handler, *data)
611
612    #
613    # Aliases
614    #
615
616    handler_block = signal_handler_block
617    handler_unblock = _signalmethod(GObjectModule.signal_handler_unblock)
618    disconnect = _signalmethod(GObjectModule.signal_handler_disconnect)
619    handler_disconnect = _signalmethod(GObjectModule.signal_handler_disconnect)
620    handler_is_connected = _signalmethod(GObjectModule.signal_handler_is_connected)
621    stop_emission_by_name = _signalmethod(GObjectModule.signal_stop_emission_by_name)
622
623    #
624    # Deprecated Methods
625    #
626
627    def stop_emission(self, detailed_signal):
628        """Deprecated, please use stop_emission_by_name."""
629        warnings.warn(self.stop_emission.__doc__, PyGIDeprecationWarning, stacklevel=2)
630        return self.stop_emission_by_name(detailed_signal)
631
632    emit_stop_by_name = stop_emission
633
634
635Object = override(Object)
636GObject = Object
637__all__ += ['Object', 'GObject']
638
639
640class Binding(GObjectModule.Binding):
641    def __call__(self):
642        warnings.warn('Using parentheses (binding()) to retrieve the Binding object is no '
643                      'longer needed because the binding is returned directly from "bind_property.',
644                      PyGIDeprecationWarning, stacklevel=2)
645        return self
646
647    def unbind(self):
648        # Fixed in newer glib
649        if (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION) >= (2, 57, 3):
650            return super(Binding, self).unbind()
651
652        if hasattr(self, '_unbound'):
653            raise ValueError('binding has already been cleared out')
654        else:
655            setattr(self, '_unbound', True)
656            super(Binding, self).unbind()
657
658
659Binding = override(Binding)
660__all__.append('Binding')
661
662
663Property = propertyhelper.Property
664Signal = signalhelper.Signal
665SignalOverride = signalhelper.SignalOverride
666# Deprecated naming "property" available for backwards compatibility.
667# Keep this at the end of the file to avoid clobbering the builtin.
668property = Property
669deprecated_attr("GObject", "property", "GObject.Property")
670__all__ += ['Property', 'Signal', 'SignalOverride', 'property']
671