1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
4 # Copyright (C) 2012 Canonical Ltd.
5 # Author: Martin Pitt <martin.pitt@ubuntu.com>
6 # Copyright (C) 2012 Simon Feltman <sfeltman@src.gnome.org>
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
24 from collections import namedtuple
28 from gi.overrides import override
29 from gi.repository import GLib
31 from gi._gobject import _gobject
32 from gi._gobject import propertyhelper
33 from gi._gobject import signalhelper
35 GObjectModule = gi.module.get_introspection_module('GObject')
40 from gi._glib import option
41 sys.modules['gi._gobject.option'] = option
44 # API aliases for backwards compatibility
45 for name in ['markup_escape_text', 'get_application_name',
46 'set_application_name', 'get_prgname', 'set_prgname',
47 'main_depth', 'filename_display_basename',
48 'filename_display_name', 'filename_from_utf8',
49 'uri_list_extract_uris',
50 'MainLoop', 'MainContext', 'main_context_default',
51 'source_remove', 'Source', 'Idle', 'Timeout', 'PollFD',
52 'idle_add', 'timeout_add', 'timeout_add_seconds',
53 'io_add_watch', 'child_watch_add', 'get_current_time',
55 globals()[name] = gi.overrides.deprecated(getattr(GLib, name), 'GLib.' + name)
58 # constants are also deprecated, but cannot mark them as such
59 for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
60 'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
61 'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
62 'IO_STATUS_ERROR', 'IO_STATUS_NORMAL', 'IO_STATUS_EOF',
63 'IO_STATUS_AGAIN', 'IO_FLAG_APPEND', 'IO_FLAG_NONBLOCK',
64 'IO_FLAG_IS_READABLE', 'IO_FLAG_IS_WRITEABLE',
65 'IO_FLAG_IS_SEEKABLE', 'IO_FLAG_MASK', 'IO_FLAG_GET_MASK',
67 'SPAWN_LEAVE_DESCRIPTORS_OPEN', 'SPAWN_DO_NOT_REAP_CHILD',
68 'SPAWN_SEARCH_PATH', 'SPAWN_STDOUT_TO_DEV_NULL',
69 'SPAWN_STDERR_TO_DEV_NULL', 'SPAWN_CHILD_INHERITS_STDIN',
70 'SPAWN_FILE_AND_ARGV_ZERO',
71 'OPTION_FLAG_HIDDEN', 'OPTION_FLAG_IN_MAIN', 'OPTION_FLAG_REVERSE',
72 'OPTION_FLAG_NO_ARG', 'OPTION_FLAG_FILENAME', 'OPTION_FLAG_OPTIONAL_ARG',
73 'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
74 'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
76 globals()[name] = getattr(GLib, name)
80 G_MININT8 = GLib.MININT8
81 G_MAXINT8 = GLib.MAXINT8
82 G_MAXUINT8 = GLib.MAXUINT8
83 G_MININT16 = GLib.MININT16
84 G_MAXINT16 = GLib.MAXINT16
85 G_MAXUINT16 = GLib.MAXUINT16
86 G_MININT32 = GLib.MININT32
87 G_MAXINT32 = GLib.MAXINT32
88 G_MAXUINT32 = GLib.MAXUINT32
89 G_MININT64 = GLib.MININT64
90 G_MAXINT64 = GLib.MAXINT64
91 G_MAXUINT64 = GLib.MAXUINT64
92 __all__ += ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
93 'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
94 'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']
96 # these are not currently exported in GLib gir, presumably because they are
97 # platform dependent; so get them from our static bindings
98 for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
99 'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
100 'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
101 'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
102 globals()[name] = getattr(_gobject, name)
106 TYPE_INVALID = GObjectModule.type_from_name('invalid')
107 TYPE_NONE = GObjectModule.type_from_name('void')
108 TYPE_INTERFACE = GObjectModule.type_from_name('GInterface')
109 TYPE_CHAR = GObjectModule.type_from_name('gchar')
110 TYPE_UCHAR = GObjectModule.type_from_name('guchar')
111 TYPE_BOOLEAN = GObjectModule.type_from_name('gboolean')
112 TYPE_INT = GObjectModule.type_from_name('gint')
113 TYPE_UINT = GObjectModule.type_from_name('guint')
114 TYPE_LONG = GObjectModule.type_from_name('glong')
115 TYPE_ULONG = GObjectModule.type_from_name('gulong')
116 TYPE_INT64 = GObjectModule.type_from_name('gint64')
117 TYPE_UINT64 = GObjectModule.type_from_name('guint64')
118 TYPE_ENUM = GObjectModule.type_from_name('GEnum')
119 TYPE_FLAGS = GObjectModule.type_from_name('GFlags')
120 TYPE_FLOAT = GObjectModule.type_from_name('gfloat')
121 TYPE_DOUBLE = GObjectModule.type_from_name('gdouble')
122 TYPE_STRING = GObjectModule.type_from_name('gchararray')
123 TYPE_POINTER = GObjectModule.type_from_name('gpointer')
124 TYPE_BOXED = GObjectModule.type_from_name('GBoxed')
125 TYPE_PARAM = GObjectModule.type_from_name('GParam')
126 TYPE_OBJECT = GObjectModule.type_from_name('GObject')
127 TYPE_PYOBJECT = GObjectModule.type_from_name('PyObject')
128 TYPE_GTYPE = GObjectModule.type_from_name('GType')
129 TYPE_STRV = GObjectModule.type_from_name('GStrv')
130 TYPE_VARIANT = GObjectModule.type_from_name('GVariant')
131 TYPE_GSTRING = GObjectModule.type_from_name('GString')
132 TYPE_UNICHAR = TYPE_UINT
133 __all__ += ['TYPE_INVALID', 'TYPE_NONE', 'TYPE_INTERFACE', 'TYPE_CHAR',
134 'TYPE_UCHAR', 'TYPE_BOOLEAN', 'TYPE_INT', 'TYPE_UINT', 'TYPE_LONG',
135 'TYPE_ULONG', 'TYPE_INT64', 'TYPE_UINT64', 'TYPE_ENUM', 'TYPE_FLAGS',
136 'TYPE_FLOAT', 'TYPE_DOUBLE', 'TYPE_STRING', 'TYPE_POINTER',
137 'TYPE_BOXED', 'TYPE_PARAM', 'TYPE_OBJECT', 'TYPE_PYOBJECT',
138 'TYPE_GTYPE', 'TYPE_STRV', 'TYPE_VARIANT', 'TYPE_GSTRING', 'TYPE_UNICHAR']
141 # Deprecated, use GLib directly
144 OptionGroup = GLib.OptionGroup
145 OptionContext = GLib.OptionContext
146 __all__ += ['Pid', 'GError', 'OptionGroup', 'OptionContext']
149 # Deprecated, use: GObject.ParamFlags.* directly
150 PARAM_CONSTRUCT = GObjectModule.ParamFlags.CONSTRUCT
151 PARAM_CONSTRUCT_ONLY = GObjectModule.ParamFlags.CONSTRUCT_ONLY
152 PARAM_LAX_VALIDATION = GObjectModule.ParamFlags.LAX_VALIDATION
153 PARAM_READABLE = GObjectModule.ParamFlags.READABLE
154 PARAM_WRITABLE = GObjectModule.ParamFlags.WRITABLE
155 # PARAM_READWRITE should come from the gi module but cannot due to:
156 # https://bugzilla.gnome.org/show_bug.cgi?id=687615
157 PARAM_READWRITE = PARAM_READABLE | PARAM_WRITABLE
158 __all__ += ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
159 'PARAM_READABLE', 'PARAM_WRITABLE', 'PARAM_READWRITE']
162 # Deprecated, use: GObject.SignalFlags.* directly
163 SIGNAL_ACTION = GObjectModule.SignalFlags.ACTION
164 SIGNAL_DETAILED = GObjectModule.SignalFlags.DETAILED
165 SIGNAL_NO_HOOKS = GObjectModule.SignalFlags.NO_HOOKS
166 SIGNAL_NO_RECURSE = GObjectModule.SignalFlags.NO_RECURSE
167 SIGNAL_RUN_CLEANUP = GObjectModule.SignalFlags.RUN_CLEANUP
168 SIGNAL_RUN_FIRST = GObjectModule.SignalFlags.RUN_FIRST
169 SIGNAL_RUN_LAST = GObjectModule.SignalFlags.RUN_LAST
170 __all__ += ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
171 'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
176 GBoxed = _gobject.GBoxed
177 GEnum = _gobject.GEnum
178 GFlags = _gobject.GFlags
179 GInterface = _gobject.GInterface
180 GObject = _gobject.GObject
181 GObjectWeakRef = _gobject.GObjectWeakRef
182 GParamSpec = _gobject.GParamSpec
183 GPointer = _gobject.GPointer
184 GType = _gobject.GType
185 Warning = _gobject.Warning
186 __all__ += ['GBoxed', 'GEnum', 'GFlags', 'GInterface', 'GObject',
187 'GObjectWeakRef', 'GParamSpec', 'GPointer', 'GType',
191 add_emission_hook = _gobject.add_emission_hook
192 features = _gobject.features
193 list_properties = _gobject.list_properties
195 pygobject_version = _gobject.pygobject_version
196 remove_emission_hook = _gobject.remove_emission_hook
197 signal_accumulator_true_handled = _gobject.signal_accumulator_true_handled
198 signal_new = _gobject.signal_new
199 threads_init = _gobject.threads_init
200 type_register = _gobject.type_register
201 __all__ += ['add_emission_hook', 'features', 'list_properties',
202 'new', 'pygobject_version', 'remove_emission_hook',
203 'signal_accumulator_true_handled',
204 'signal_new', 'threads_init', 'type_register']
207 class Value(GObjectModule.Value):
209 if self._free_on_dealloc:
212 Value = override(Value)
213 __all__.append('Value')
216 def type_from_name(name):
217 type_ = GObjectModule.type_from_name(name)
218 if type_ == TYPE_INVALID:
219 raise RuntimeError('unknown type name: %s' % name)
222 __all__.append('type_from_name')
225 def type_parent(type_):
226 parent = GObjectModule.type_parent(type_)
227 if parent == TYPE_INVALID:
228 raise RuntimeError('no parent for type')
231 __all__.append('type_parent')
234 def _validate_type_for_signal_method(type_):
235 if hasattr(type_, '__gtype__'):
236 type_ = type_.__gtype__
237 if not type_.is_instantiatable() and not type_.is_interface():
238 raise TypeError('type must be instantiable or an interface, got %s' % type_)
241 def signal_list_ids(type_):
242 _validate_type_for_signal_method(type_)
243 return GObjectModule.signal_list_ids(type_)
245 __all__.append('signal_list_ids')
248 def signal_list_names(type_):
249 ids = signal_list_ids(type_)
250 return tuple(GObjectModule.signal_name(i) for i in ids)
252 __all__.append('signal_list_names')
255 def signal_lookup(name, type_):
256 _validate_type_for_signal_method(type_)
257 return GObjectModule.signal_lookup(name, type_)
259 __all__.append('signal_lookup')
262 def signal_query(id_or_name, type_=None):
263 SignalQuery = namedtuple('SignalQuery',
272 # signal_query needs to use a static method until the following bugs are fixed:
273 # https://bugzilla.gnome.org/show_bug.cgi?id=687550
274 # https://bugzilla.gnome.org/show_bug.cgi?id=687545
275 # https://bugzilla.gnome.org/show_bug.cgi?id=687541
276 if type_ is not None:
277 id_or_name = signal_lookup(id_or_name, type_)
279 res = _gobject.signal_query(id_or_name)
283 # Return a named tuple which allows indexing like the static bindings
284 # along with field like access of the gi struct.
285 # Note however that the n_params was not returned from the static bindings.
286 return SignalQuery(*res)
288 __all__.append('signal_query')
291 class _HandlerBlockManager(object):
292 def __init__(self, obj, handler_id):
294 self.handler_id = handler_id
299 def __exit__(self, exc_type, exc_value, traceback):
300 _gobject.GObject.handler_unblock(self.obj, self.handler_id)
303 class _FreezeNotifyManager(object):
304 def __init__(self, obj):
310 def __exit__(self, exc_type, exc_value, traceback):
311 self.obj.thaw_notify()
314 class Object(GObjectModule.Object):
315 def _unsupported_method(self, *args, **kargs):
316 raise RuntimeError('This method is currently unsupported.')
318 def _unsupported_data_method(self, *args, **kargs):
319 raise RuntimeError('Data access methods are unsupported. '
320 'Use normal Python attributes instead')
322 # Generic data methods are not needed in python as it can be handled
323 # with standard attribute access: https://bugzilla.gnome.org/show_bug.cgi?id=641944
324 get_data = _unsupported_data_method
325 get_qdata = _unsupported_data_method
326 set_data = _unsupported_data_method
327 steal_data = _unsupported_data_method
328 steal_qdata = _unsupported_data_method
329 replace_data = _unsupported_data_method
330 replace_qdata = _unsupported_data_method
332 # The following methods as unsupported until we verify
333 # they work as gi methods.
334 bind_property_full = _unsupported_method
335 compat_control = _unsupported_method
336 force_floating = _unsupported_method
337 interface_find_property = _unsupported_method
338 interface_install_property = _unsupported_method
339 interface_list_properties = _unsupported_method
340 is_floating = _unsupported_method
341 notify_by_pspec = _unsupported_method
342 ref = _unsupported_method
343 ref_count = _unsupported_method
344 ref_sink = _unsupported_method
345 run_dispose = _unsupported_method
346 unref = _unsupported_method
347 watch_closure = _unsupported_method
349 # The following methods are static APIs which need to leap frog the
350 # gi methods until we verify the gi methods can replace them.
351 get_property = _gobject.GObject.get_property
352 get_properties = _gobject.GObject.get_properties
353 set_property = _gobject.GObject.set_property
354 set_properties = _gobject.GObject.set_properties
355 bind_property = _gobject.GObject.bind_property
356 connect = _gobject.GObject.connect
357 connect_after = _gobject.GObject.connect_after
358 connect_object = _gobject.GObject.connect_object
359 connect_object_after = _gobject.GObject.connect_object_after
360 disconnect = _gobject.GObject.disconnect
361 disconnect_by_func = _gobject.GObject.disconnect_by_func
362 handler_disconnect = _gobject.GObject.handler_disconnect
363 handler_is_connected = _gobject.GObject.handler_is_connected
364 handler_block_by_func = _gobject.GObject.handler_block_by_func
365 handler_unblock_by_func = _gobject.GObject.handler_unblock_by_func
366 emit = _gobject.GObject.emit
367 emit_stop_by_name = _gobject.GObject.emit_stop_by_name
368 stop_emission = _gobject.GObject.stop_emission
369 chain = _gobject.GObject.chain
370 weak_ref = _gobject.GObject.weak_ref
371 __copy__ = _gobject.GObject.__copy__
372 __deepcopy__ = _gobject.GObject.__deepcopy__
374 def handler_block(self, handler_id):
375 """Blocks the signal handler from being invoked until handler_unblock() is called.
377 Returns a context manager which optionally can be used to
378 automatically unblock the handler:
380 >>> with obj.handler_block(id):
384 # Note Object.handler_block is a static method specific to pygobject and not
385 # found in introspection. We need to continue using the static method
386 # until we figure out a technique to call the global signal_handler_block.
387 # But this requires a gpointer to the Object which we currently don't have
388 # access to in python.
389 _gobject.GObject.handler_block(self, handler_id)
390 return _HandlerBlockManager(self, handler_id)
392 def freeze_notify(self):
393 """Freezes the object's property-changed notification queue.
395 This will freeze the object so that "notify" signals are blocked until
396 the thaw_notify() method is called.
398 Returns a context manager which optionally can be used to
399 automatically thaw notifications:
401 >>> with obj.freeze_notify():
404 super(Object, self).freeze_notify()
405 return _FreezeNotifyManager(self)
408 Object = override(Object)
410 __all__ += ['Object', 'GObject']
413 Property = propertyhelper.Property
414 Signal = signalhelper.Signal
415 SignalOverride = signalhelper.SignalOverride
416 # Deprecated naming "property" available for backwards compatibility.
417 # Keep this at the end of the file to avoid clobbering the builtin.
419 __all__ += ['Property', 'Signal', 'SignalOverride', 'property']