Imported Upstream version 3.9.91
[platform/upstream/python-gobject.git] / gi / overrides / GObject.py
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
24 import sys
25 import warnings
26 import functools
27 from collections import namedtuple
28
29 import gi.overrides
30 import gi.module
31 from gi.overrides import override
32 from gi.repository import GLib
33 from gi import PyGIDeprecationWarning
34
35 from gi._gobject import _gobject
36 from gi._gobject import propertyhelper
37 from gi._gobject import signalhelper
38
39 GObjectModule = gi.module.get_introspection_module('GObject')
40
41 __all__ = []
42
43
44 from gi._glib import option
45 sys.modules['gi._gobject.option'] = option
46
47
48 # API aliases for backwards compatibility
49 for name in ['markup_escape_text', 'get_application_name',
50              'set_application_name', 'get_prgname', 'set_prgname',
51              'main_depth', 'filename_display_basename',
52              'filename_display_name', 'filename_from_utf8',
53              'uri_list_extract_uris',
54              'MainLoop', 'MainContext', 'main_context_default',
55              'source_remove', 'Source', 'Idle', 'Timeout', 'PollFD',
56              'idle_add', 'timeout_add', 'timeout_add_seconds',
57              'io_add_watch', 'child_watch_add', 'get_current_time',
58              'spawn_async']:
59     globals()[name] = gi.overrides.deprecated(getattr(GLib, name), 'GLib.' + name)
60     __all__.append(name)
61
62 # constants are also deprecated, but cannot mark them as such
63 for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
64              'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
65              'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
66              'IO_STATUS_ERROR', 'IO_STATUS_NORMAL', 'IO_STATUS_EOF',
67              'IO_STATUS_AGAIN', 'IO_FLAG_APPEND', 'IO_FLAG_NONBLOCK',
68              'IO_FLAG_IS_READABLE', 'IO_FLAG_IS_WRITEABLE',
69              'IO_FLAG_IS_SEEKABLE', 'IO_FLAG_MASK', 'IO_FLAG_GET_MASK',
70              'IO_FLAG_SET_MASK',
71              'SPAWN_LEAVE_DESCRIPTORS_OPEN', 'SPAWN_DO_NOT_REAP_CHILD',
72              'SPAWN_SEARCH_PATH', 'SPAWN_STDOUT_TO_DEV_NULL',
73              'SPAWN_STDERR_TO_DEV_NULL', 'SPAWN_CHILD_INHERITS_STDIN',
74              'SPAWN_FILE_AND_ARGV_ZERO',
75              'OPTION_FLAG_HIDDEN', 'OPTION_FLAG_IN_MAIN', 'OPTION_FLAG_REVERSE',
76              'OPTION_FLAG_NO_ARG', 'OPTION_FLAG_FILENAME', 'OPTION_FLAG_OPTIONAL_ARG',
77              'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
78              'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
79              'glib_version']:
80     globals()[name] = getattr(GLib, name)
81     __all__.append(name)
82
83
84 G_MININT8 = GLib.MININT8
85 G_MAXINT8 = GLib.MAXINT8
86 G_MAXUINT8 = GLib.MAXUINT8
87 G_MININT16 = GLib.MININT16
88 G_MAXINT16 = GLib.MAXINT16
89 G_MAXUINT16 = GLib.MAXUINT16
90 G_MININT32 = GLib.MININT32
91 G_MAXINT32 = GLib.MAXINT32
92 G_MAXUINT32 = GLib.MAXUINT32
93 G_MININT64 = GLib.MININT64
94 G_MAXINT64 = GLib.MAXINT64
95 G_MAXUINT64 = GLib.MAXUINT64
96 __all__ += ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
97             'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
98             'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']
99
100 # these are not currently exported in GLib gir, presumably because they are
101 # platform dependent; so get them from our static bindings
102 for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
103              'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
104              'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
105              'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
106     globals()[name] = getattr(_gobject, name)
107     __all__.append(name)
108
109
110 TYPE_INVALID = GObjectModule.type_from_name('invalid')
111 TYPE_NONE = GObjectModule.type_from_name('void')
112 TYPE_INTERFACE = GObjectModule.type_from_name('GInterface')
113 TYPE_CHAR = GObjectModule.type_from_name('gchar')
114 TYPE_UCHAR = GObjectModule.type_from_name('guchar')
115 TYPE_BOOLEAN = GObjectModule.type_from_name('gboolean')
116 TYPE_INT = GObjectModule.type_from_name('gint')
117 TYPE_UINT = GObjectModule.type_from_name('guint')
118 TYPE_LONG = GObjectModule.type_from_name('glong')
119 TYPE_ULONG = GObjectModule.type_from_name('gulong')
120 TYPE_INT64 = GObjectModule.type_from_name('gint64')
121 TYPE_UINT64 = GObjectModule.type_from_name('guint64')
122 TYPE_ENUM = GObjectModule.type_from_name('GEnum')
123 TYPE_FLAGS = GObjectModule.type_from_name('GFlags')
124 TYPE_FLOAT = GObjectModule.type_from_name('gfloat')
125 TYPE_DOUBLE = GObjectModule.type_from_name('gdouble')
126 TYPE_STRING = GObjectModule.type_from_name('gchararray')
127 TYPE_POINTER = GObjectModule.type_from_name('gpointer')
128 TYPE_BOXED = GObjectModule.type_from_name('GBoxed')
129 TYPE_PARAM = GObjectModule.type_from_name('GParam')
130 TYPE_OBJECT = GObjectModule.type_from_name('GObject')
131 TYPE_PYOBJECT = GObjectModule.type_from_name('PyObject')
132 TYPE_GTYPE = GObjectModule.type_from_name('GType')
133 TYPE_STRV = GObjectModule.type_from_name('GStrv')
134 TYPE_VARIANT = GObjectModule.type_from_name('GVariant')
135 TYPE_GSTRING = GObjectModule.type_from_name('GString')
136 TYPE_VALUE = GObjectModule.Value.__gtype__
137 TYPE_UNICHAR = TYPE_UINT
138 __all__ += ['TYPE_INVALID', 'TYPE_NONE', 'TYPE_INTERFACE', 'TYPE_CHAR',
139             'TYPE_UCHAR', 'TYPE_BOOLEAN', 'TYPE_INT', 'TYPE_UINT', 'TYPE_LONG',
140             'TYPE_ULONG', 'TYPE_INT64', 'TYPE_UINT64', 'TYPE_ENUM', 'TYPE_FLAGS',
141             'TYPE_FLOAT', 'TYPE_DOUBLE', 'TYPE_STRING', 'TYPE_POINTER',
142             'TYPE_BOXED', 'TYPE_PARAM', 'TYPE_OBJECT', 'TYPE_PYOBJECT',
143             'TYPE_GTYPE', 'TYPE_STRV', 'TYPE_VARIANT', 'TYPE_GSTRING',
144             'TYPE_UNICHAR', 'TYPE_VALUE']
145
146
147 # Deprecated, use GLib directly
148 Pid = GLib.Pid
149 GError = GLib.GError
150 OptionGroup = GLib.OptionGroup
151 OptionContext = GLib.OptionContext
152 __all__ += ['Pid', 'GError', 'OptionGroup', 'OptionContext']
153
154
155 # Deprecated, use: GObject.ParamFlags.* directly
156 PARAM_CONSTRUCT = GObjectModule.ParamFlags.CONSTRUCT
157 PARAM_CONSTRUCT_ONLY = GObjectModule.ParamFlags.CONSTRUCT_ONLY
158 PARAM_LAX_VALIDATION = GObjectModule.ParamFlags.LAX_VALIDATION
159 PARAM_READABLE = GObjectModule.ParamFlags.READABLE
160 PARAM_WRITABLE = GObjectModule.ParamFlags.WRITABLE
161 # PARAM_READWRITE should come from the gi module but cannot due to:
162 # https://bugzilla.gnome.org/show_bug.cgi?id=687615
163 PARAM_READWRITE = PARAM_READABLE | PARAM_WRITABLE
164 __all__ += ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
165             'PARAM_READABLE', 'PARAM_WRITABLE', 'PARAM_READWRITE']
166
167
168 # Deprecated, use: GObject.SignalFlags.* directly
169 SIGNAL_ACTION = GObjectModule.SignalFlags.ACTION
170 SIGNAL_DETAILED = GObjectModule.SignalFlags.DETAILED
171 SIGNAL_NO_HOOKS = GObjectModule.SignalFlags.NO_HOOKS
172 SIGNAL_NO_RECURSE = GObjectModule.SignalFlags.NO_RECURSE
173 SIGNAL_RUN_CLEANUP = GObjectModule.SignalFlags.RUN_CLEANUP
174 SIGNAL_RUN_FIRST = GObjectModule.SignalFlags.RUN_FIRST
175 SIGNAL_RUN_LAST = GObjectModule.SignalFlags.RUN_LAST
176 __all__ += ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
177             'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
178             'SIGNAL_RUN_LAST']
179
180
181 # Static types
182 GBoxed = _gobject.GBoxed
183 GEnum = _gobject.GEnum
184 GFlags = _gobject.GFlags
185 GInterface = _gobject.GInterface
186 GObject = _gobject.GObject
187 GObjectWeakRef = _gobject.GObjectWeakRef
188 GParamSpec = _gobject.GParamSpec
189 GPointer = _gobject.GPointer
190 GType = _gobject.GType
191 Warning = _gobject.Warning
192 __all__ += ['GBoxed', 'GEnum', 'GFlags', 'GInterface', 'GObject',
193             'GObjectWeakRef', 'GParamSpec', 'GPointer', 'GType',
194             'Warning']
195
196
197 features = _gobject.features
198 list_properties = _gobject.list_properties
199 new = _gobject.new
200 pygobject_version = _gobject.pygobject_version
201 threads_init = GLib.threads_init
202 type_register = _gobject.type_register
203 __all__ += ['features', 'list_properties', 'new',
204             'pygobject_version', 'threads_init', 'type_register']
205
206
207 class Value(GObjectModule.Value):
208     def __new__(cls, *args, **kwargs):
209         return GObjectModule.Value.__new__(cls)
210
211     def __init__(self, value_type=None, py_value=None):
212         GObjectModule.Value.__init__(self)
213         if value_type is not None:
214             self.init(value_type)
215             if py_value is not None:
216                 self.set_value(py_value)
217
218     def __del__(self):
219         if self._free_on_dealloc and self.g_type != TYPE_INVALID:
220             self.unset()
221
222     def set_boxed(self, boxed):
223         # Workaround the introspection marshalers inability to know
224         # these methods should be marshaling boxed types. This is because
225         # the type information is stored on the GValue.
226         _gobject._gvalue_set(self, boxed)
227
228     def get_boxed(self):
229         return _gobject._gvalue_get(self)
230
231     def set_value(self, py_value):
232         gtype = self.g_type
233
234         if gtype == _gobject.TYPE_INVALID:
235             raise TypeError("GObject.Value needs to be initialized first")
236         elif gtype == TYPE_BOOLEAN:
237             self.set_boolean(py_value)
238         elif gtype == TYPE_CHAR:
239             self.set_char(py_value)
240         elif gtype == TYPE_UCHAR:
241             self.set_uchar(py_value)
242         elif gtype == TYPE_INT:
243             self.set_int(py_value)
244         elif gtype == TYPE_UINT:
245             self.set_uint(py_value)
246         elif gtype == TYPE_LONG:
247             self.set_long(py_value)
248         elif gtype == TYPE_ULONG:
249             self.set_ulong(py_value)
250         elif gtype == TYPE_INT64:
251             self.set_int64(py_value)
252         elif gtype == TYPE_UINT64:
253             self.set_uint64(py_value)
254         elif gtype == TYPE_FLOAT:
255             self.set_float(py_value)
256         elif gtype == TYPE_DOUBLE:
257             self.set_double(py_value)
258         elif gtype == TYPE_STRING:
259             if isinstance(py_value, str):
260                 py_value = str(py_value)
261             elif sys.version_info < (3, 0):
262                 if isinstance(py_value, unicode):
263                     py_value = py_value.encode('UTF-8')
264                 else:
265                     raise ValueError("Expected string or unicode but got %s%s" %
266                                      (py_value, type(py_value)))
267             else:
268                 raise ValueError("Expected string but got %s%s" %
269                                  (py_value, type(py_value)))
270             self.set_string(py_value)
271         elif gtype == TYPE_PARAM:
272             self.set_param(py_value)
273         elif gtype.is_a(TYPE_ENUM):
274             self.set_enum(py_value)
275         elif gtype.is_a(TYPE_FLAGS):
276             self.set_flags(py_value)
277         elif gtype.is_a(TYPE_BOXED):
278             self.set_boxed(py_value)
279         elif gtype == TYPE_POINTER:
280             self.set_pointer(py_value)
281         elif gtype.is_a(TYPE_OBJECT):
282             self.set_object(py_value)
283         elif gtype == TYPE_UNICHAR:
284             self.set_uint(int(py_value))
285         # elif gtype == TYPE_OVERRIDE:
286         #     pass
287         elif gtype == TYPE_GTYPE:
288             self.set_gtype(py_value)
289         elif gtype == TYPE_VARIANT:
290             self.set_variant(py_value)
291         elif gtype == TYPE_PYOBJECT:
292             self.set_boxed(py_value)
293         else:
294             raise TypeError("Unknown value type %s" % gtype)
295
296     def get_value(self):
297         gtype = self.g_type
298
299         if gtype == TYPE_BOOLEAN:
300             return self.get_boolean()
301         elif gtype == TYPE_CHAR:
302             return self.get_char()
303         elif gtype == TYPE_UCHAR:
304             return self.get_uchar()
305         elif gtype == TYPE_INT:
306             return self.get_int()
307         elif gtype == TYPE_UINT:
308             return self.get_uint()
309         elif gtype == TYPE_LONG:
310             return self.get_long()
311         elif gtype == TYPE_ULONG:
312             return self.get_ulong()
313         elif gtype == TYPE_INT64:
314             return self.get_int64()
315         elif gtype == TYPE_UINT64:
316             return self.get_uint64()
317         elif gtype == TYPE_FLOAT:
318             return self.get_float()
319         elif gtype == TYPE_DOUBLE:
320             return self.get_double()
321         elif gtype == TYPE_STRING:
322             return self.get_string()
323         elif gtype == TYPE_PARAM:
324             return self.get_param()
325         elif gtype.is_a(TYPE_ENUM):
326             return self.get_enum()
327         elif gtype.is_a(TYPE_FLAGS):
328             return self.get_flags()
329         elif gtype.is_a(TYPE_BOXED):
330             return self.get_boxed()
331         elif gtype == TYPE_POINTER:
332             return self.get_pointer()
333         elif gtype.is_a(TYPE_OBJECT):
334             return self.get_object()
335         elif gtype == TYPE_UNICHAR:
336             return self.get_uint()
337         elif gtype == TYPE_GTYPE:
338             return self.get_gtype()
339         elif gtype == TYPE_VARIANT:
340             return self.get_variant()
341         elif gtype == TYPE_PYOBJECT:
342             pass
343         else:
344             return None
345
346     def __repr__(self):
347         return '<Value (%s) %s>' % (self.g_type.name, self.get_value())
348
349 Value = override(Value)
350 __all__.append('Value')
351
352
353 def type_from_name(name):
354     type_ = GObjectModule.type_from_name(name)
355     if type_ == TYPE_INVALID:
356         raise RuntimeError('unknown type name: %s' % name)
357     return type_
358
359 __all__.append('type_from_name')
360
361
362 def type_parent(type_):
363     parent = GObjectModule.type_parent(type_)
364     if parent == TYPE_INVALID:
365         raise RuntimeError('no parent for type')
366     return parent
367
368 __all__.append('type_parent')
369
370
371 def _validate_type_for_signal_method(type_):
372     if hasattr(type_, '__gtype__'):
373         type_ = type_.__gtype__
374     if not type_.is_instantiatable() and not type_.is_interface():
375         raise TypeError('type must be instantiable or an interface, got %s' % type_)
376
377
378 def signal_list_ids(type_):
379     _validate_type_for_signal_method(type_)
380     return GObjectModule.signal_list_ids(type_)
381
382 __all__.append('signal_list_ids')
383
384
385 def signal_list_names(type_):
386     ids = signal_list_ids(type_)
387     return tuple(GObjectModule.signal_name(i) for i in ids)
388
389 __all__.append('signal_list_names')
390
391
392 def signal_lookup(name, type_):
393     _validate_type_for_signal_method(type_)
394     return GObjectModule.signal_lookup(name, type_)
395
396 __all__.append('signal_lookup')
397
398
399 def signal_query(id_or_name, type_=None):
400     SignalQuery = namedtuple('SignalQuery',
401                              ['signal_id',
402                               'signal_name',
403                               'itype',
404                               'signal_flags',
405                               'return_type',
406                               # n_params',
407                               'param_types'])
408
409     # signal_query needs to use a static method until the following bugs are fixed:
410     # https://bugzilla.gnome.org/show_bug.cgi?id=687550
411     # https://bugzilla.gnome.org/show_bug.cgi?id=687545
412     # https://bugzilla.gnome.org/show_bug.cgi?id=687541
413     if type_ is not None:
414         id_or_name = signal_lookup(id_or_name, type_)
415
416     res = _gobject.signal_query(id_or_name)
417     if res is None:
418         return None
419
420     # Return a named tuple which allows indexing like the static bindings
421     # along with field like access of the gi struct.
422     # Note however that the n_params was not returned from the static bindings.
423     return SignalQuery(*res)
424
425 __all__.append('signal_query')
426
427
428 # Check needed for glib versions which annotate signal related methods
429 # with a void pointer instead of GObject.Object.
430 # See: https://bugzilla.gnome.org/show_bug.cgi?id=685387
431 _is_first_signal_arg_void = GObjectModule.signal_stop_emission.get_arguments()[0].get_pytype_hint() == 'void'
432
433
434 def _get_instance_for_signal(obj):
435     if not _is_first_signal_arg_void:
436         return obj
437     elif isinstance(obj, GObjectModule.Object):
438         return obj.__gpointer__
439     else:
440         raise TypeError('Unsupported object "%s" for signal function' % obj)
441
442
443 class _HandlerBlockManager(object):
444     def __init__(self, obj, handler_id):
445         self.obj = obj
446         self.handler_id = handler_id
447
448     def __enter__(self):
449         pass
450
451     def __exit__(self, exc_type, exc_value, traceback):
452         signal_handler_unblock(self.obj, self.handler_id)
453
454
455 def signal_handler_block(obj, handler_id):
456     """Blocks the signal handler from being invoked until handler_unblock() is called.
457
458     Returns a context manager which optionally can be used to
459     automatically unblock the handler:
460
461       with GObject.signal_handler_block(obj, id):
462          pass
463     """
464     GObjectModule.signal_handler_block(_get_instance_for_signal(obj), handler_id)
465     return _HandlerBlockManager(obj, handler_id)
466
467 __all__.append('signal_handler_block')
468
469
470 if _is_first_signal_arg_void:
471     # The following functions wrap GI functions but coerce the first arg into
472     # something compatible with gpointer
473
474     def _wrap_signal_func(func):
475         @functools.wraps(func)
476         def wrapper(obj, *args, **kwargs):
477             return func(_get_instance_for_signal(obj), *args, **kwargs)
478         return wrapper
479
480     signal_handler_unblock = _wrap_signal_func(GObjectModule.signal_handler_unblock)
481     signal_handler_disconnect = _wrap_signal_func(GObjectModule.signal_handler_disconnect)
482     signal_handler_is_connected = _wrap_signal_func(GObjectModule.signal_handler_is_connected)
483     signal_stop_emission = _wrap_signal_func(GObjectModule.signal_stop_emission)
484     signal_stop_emission_by_name = _wrap_signal_func(GObjectModule.signal_stop_emission_by_name)
485     signal_has_handler_pending = _wrap_signal_func(GObjectModule.signal_has_handler_pending)
486     signal_get_invocation_hint = _wrap_signal_func(GObjectModule.signal_get_invocation_hint)
487     signal_connect_closure = _wrap_signal_func(GObjectModule.signal_connect_closure)
488     signal_connect_closure_by_id = _wrap_signal_func(GObjectModule.signal_connect_closure_by_id)
489     signal_handler_find = _wrap_signal_func(GObjectModule.signal_handler_find)
490     signal_handlers_destroy = _wrap_signal_func(GObjectModule.signal_handlers_destroy)
491     signal_handlers_block_matched = _wrap_signal_func(GObjectModule.signal_handlers_block_matched)
492     signal_handlers_unblock_matched = _wrap_signal_func(GObjectModule.signal_handlers_unblock_matched)
493     signal_handlers_disconnect_matched = _wrap_signal_func(GObjectModule.signal_handlers_disconnect_matched)
494
495     __all__ += ['signal_handler_unblock',
496                 'signal_handler_disconnect', 'signal_handler_is_connected',
497                 'signal_stop_emission', 'signal_stop_emission_by_name',
498                 'signal_has_handler_pending', 'signal_get_invocation_hint',
499                 'signal_connect_closure', 'signal_connect_closure_by_id',
500                 'signal_handler_find', 'signal_handlers_destroy',
501                 'signal_handlers_block_matched', 'signal_handlers_unblock_matched',
502                 'signal_handlers_disconnect_matched']
503 else:
504     # First signal arg is GObject.Object but we need these as globals for
505     # our GObject.Object class override below
506     signal_handler_disconnect = GObjectModule.signal_handler_disconnect
507     signal_handler_unblock = GObjectModule.signal_handler_unblock
508     signal_handler_disconnect = GObjectModule.signal_handler_disconnect
509     signal_handler_is_connected = GObjectModule.signal_handler_is_connected
510     signal_stop_emission_by_name = GObjectModule.signal_stop_emission_by_name
511
512
513 def signal_parse_name(detailed_signal, itype, force_detail_quark):
514     """Parse a detailed signal name into (signal_id, detail).
515
516     :Raises ValueError:
517         If the given signal is unknown.
518
519     :Returns:
520         Tuple of (signal_id, detail)
521     """
522     res, signal_id, detail = GObjectModule.signal_parse_name(detailed_signal, itype,
523                                                              force_detail_quark)
524     if res:
525         return signal_id, detail
526     else:
527         raise ValueError('%s: unknown signal name: %s' % (itype, detailed_signal))
528
529 __all__.append('signal_parse_name')
530
531
532 def remove_emission_hook(obj, detailed_signal, hook_id):
533     signal_id, detail = signal_parse_name(detailed_signal, obj, True)
534     GObjectModule.signal_remove_emission_hook(signal_id, hook_id)
535
536 __all__.append('remove_emission_hook')
537
538
539 # GObject accumulators with pure Python implementations
540 # These return a tuple of (continue_emission, accumulation_result)
541
542 def signal_accumulator_first_wins(ihint, return_accu, handler_return, user_data=None):
543     # Stop emission but return the result of the last handler
544     return (False, handler_return)
545
546 __all__.append('signal_accumulator_first_wins')
547
548
549 def signal_accumulator_true_handled(ihint, return_accu, handler_return, user_data=None):
550     # Stop emission if the last handler returns True
551     return (not handler_return, handler_return)
552
553 __all__.append('signal_accumulator_true_handled')
554
555
556 # Statically bound signal functions which need to clobber GI (for now)
557
558 add_emission_hook = _gobject.add_emission_hook
559 signal_new = _gobject.signal_new
560
561 __all__ += ['add_emission_hook', 'signal_new']
562
563
564 class _FreezeNotifyManager(object):
565     def __init__(self, obj):
566         self.obj = obj
567
568     def __enter__(self):
569         pass
570
571     def __exit__(self, exc_type, exc_value, traceback):
572         self.obj.thaw_notify()
573
574
575 def _signalmethod(func):
576     # Function wrapper for signal functions used as instance methods.
577     # This is needed when the signal functions come directly from GI.
578     # (they are not already wrapped)
579     @functools.wraps(func)
580     def meth(*args, **kwargs):
581         return func(*args, **kwargs)
582     return meth
583
584
585 class Object(GObjectModule.Object):
586     def _unsupported_method(self, *args, **kargs):
587         raise RuntimeError('This method is currently unsupported.')
588
589     def _unsupported_data_method(self, *args, **kargs):
590         raise RuntimeError('Data access methods are unsupported. '
591                            'Use normal Python attributes instead')
592
593     # Generic data methods are not needed in python as it can be handled
594     # with standard attribute access: https://bugzilla.gnome.org/show_bug.cgi?id=641944
595     get_data = _unsupported_data_method
596     get_qdata = _unsupported_data_method
597     set_data = _unsupported_data_method
598     steal_data = _unsupported_data_method
599     steal_qdata = _unsupported_data_method
600     replace_data = _unsupported_data_method
601     replace_qdata = _unsupported_data_method
602
603     # The following methods as unsupported until we verify
604     # they work as gi methods.
605     bind_property_full = _unsupported_method
606     compat_control = _unsupported_method
607     interface_find_property = _unsupported_method
608     interface_install_property = _unsupported_method
609     interface_list_properties = _unsupported_method
610     notify_by_pspec = _unsupported_method
611     run_dispose = _unsupported_method
612     watch_closure = _unsupported_method
613
614     # Make all reference management methods private but still accessible.
615     _ref = GObjectModule.Object.ref
616     _ref_sink = GObjectModule.Object.ref_sink
617     _unref = GObjectModule.Object.unref
618     _force_floating = GObjectModule.Object.force_floating
619
620     ref = _unsupported_method
621     ref_sink = _unsupported_method
622     unref = _unsupported_method
623     force_floating = _unsupported_method
624
625     # The following methods are static APIs which need to leap frog the
626     # gi methods until we verify the gi methods can replace them.
627     get_property = _gobject.GObject.get_property
628     get_properties = _gobject.GObject.get_properties
629     set_property = _gobject.GObject.set_property
630     set_properties = _gobject.GObject.set_properties
631     bind_property = _gobject.GObject.bind_property
632     connect = _gobject.GObject.connect
633     connect_after = _gobject.GObject.connect_after
634     connect_object = _gobject.GObject.connect_object
635     connect_object_after = _gobject.GObject.connect_object_after
636     disconnect_by_func = _gobject.GObject.disconnect_by_func
637     handler_block_by_func = _gobject.GObject.handler_block_by_func
638     handler_unblock_by_func = _gobject.GObject.handler_unblock_by_func
639     emit = _gobject.GObject.emit
640     chain = _gobject.GObject.chain
641     weak_ref = _gobject.GObject.weak_ref
642     __copy__ = _gobject.GObject.__copy__
643     __deepcopy__ = _gobject.GObject.__deepcopy__
644
645     def freeze_notify(self):
646         """Freezes the object's property-changed notification queue.
647
648         This will freeze the object so that "notify" signals are blocked until
649         the thaw_notify() method is called.
650
651         Returns a context manager which optionally can be used to
652         automatically thaw notifications:
653
654           with obj.freeze_notify():
655               pass
656         """
657         super(Object, self).freeze_notify()
658         return _FreezeNotifyManager(self)
659
660     #
661     # Aliases
662     #
663
664     disconnect = _signalmethod(signal_handler_disconnect)
665     handler_block = _signalmethod(signal_handler_block)
666     handler_unblock = _signalmethod(signal_handler_unblock)
667     handler_disconnect = _signalmethod(signal_handler_disconnect)
668     handler_is_connected = _signalmethod(signal_handler_is_connected)
669     stop_emission_by_name = _signalmethod(signal_stop_emission_by_name)
670
671     #
672     # Deprecated Methods
673     #
674
675     def stop_emission(self, detailed_signal):
676         """Deprecated, please use stop_emission_by_name."""
677         warnings.warn(self.stop_emission.__doc__, PyGIDeprecationWarning, stacklevel=2)
678         return signal_stop_emission_by_name(self, detailed_signal)
679
680     emit_stop_by_name = stop_emission
681
682
683 Object = override(Object)
684 GObject = Object
685 __all__ += ['Object', 'GObject']
686
687
688 Property = propertyhelper.Property
689 Signal = signalhelper.Signal
690 SignalOverride = signalhelper.SignalOverride
691 # Deprecated naming "property" available for backwards compatibility.
692 # Keep this at the end of the file to avoid clobbering the builtin.
693 property = Property
694 __all__ += ['Property', 'Signal', 'SignalOverride', 'property']