import sys
import warnings
-import functools
from collections import namedtuple
import gi.overrides
import gi.module
-from gi.overrides import override
+from gi.overrides import override, deprecated_attr
from gi.repository import GLib
from gi import PyGIDeprecationWarning
-from gi._gobject import _gobject
-from gi._gobject import propertyhelper
-from gi._gobject import signalhelper
+from gi import _propertyhelper as propertyhelper
+from gi import _signalhelper as signalhelper
+
+_gobject = gi._gi._gobject
GObjectModule = gi.module.get_introspection_module('GObject')
__all__ = []
-from gi._glib import option
+from gi import _option as option
sys.modules['gi._gobject.option'] = option
'idle_add', 'timeout_add', 'timeout_add_seconds',
'io_add_watch', 'child_watch_add', 'get_current_time',
'spawn_async']:
- globals()[name] = gi.overrides.deprecated(getattr(GLib, name), 'GLib.' + name)
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
-# constants are also deprecated, but cannot mark them as such
+# deprecated constants
for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
'glib_version']:
- globals()[name] = getattr(GLib, name)
+ with warnings.catch_warnings():
+ # TODO: this uses deprecated Glib attributes, silence for now
+ warnings.simplefilter('ignore', PyGIDeprecationWarning)
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
-G_MININT8 = GLib.MININT8
-G_MAXINT8 = GLib.MAXINT8
-G_MAXUINT8 = GLib.MAXUINT8
-G_MININT16 = GLib.MININT16
-G_MAXINT16 = GLib.MAXINT16
-G_MAXUINT16 = GLib.MAXUINT16
-G_MININT32 = GLib.MININT32
-G_MAXINT32 = GLib.MAXINT32
-G_MAXUINT32 = GLib.MAXUINT32
-G_MININT64 = GLib.MININT64
-G_MAXINT64 = GLib.MAXINT64
-G_MAXUINT64 = GLib.MAXUINT64
-__all__ += ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
- 'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
- 'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']
+for name in ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
+ 'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
+ 'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GLib, new_name)
+ deprecated_attr("GObject", name, "GLib." + new_name)
+ __all__.append(name)
# these are not currently exported in GLib gir, presumably because they are
# platform dependent; so get them from our static bindings
'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
- globals()[name] = getattr(_gobject, name)
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GLib, new_name)
+ deprecated_attr("GObject", name, "GLib." + new_name)
__all__.append(name)
# Deprecated, use GLib directly
-Pid = GLib.Pid
-GError = GLib.GError
-OptionGroup = GLib.OptionGroup
-OptionContext = GLib.OptionContext
-__all__ += ['Pid', 'GError', 'OptionGroup', 'OptionContext']
+for name in ['Pid', 'GError', 'OptionGroup', 'OptionContext']:
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
+ __all__.append(name)
# Deprecated, use: GObject.ParamFlags.* directly
-PARAM_CONSTRUCT = GObjectModule.ParamFlags.CONSTRUCT
-PARAM_CONSTRUCT_ONLY = GObjectModule.ParamFlags.CONSTRUCT_ONLY
-PARAM_LAX_VALIDATION = GObjectModule.ParamFlags.LAX_VALIDATION
-PARAM_READABLE = GObjectModule.ParamFlags.READABLE
-PARAM_WRITABLE = GObjectModule.ParamFlags.WRITABLE
+for name in ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
+ 'PARAM_READABLE', 'PARAM_WRITABLE']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GObjectModule.ParamFlags, new_name)
+ deprecated_attr("GObject", name, "GObject.ParamFlags." + new_name)
+ __all__.append(name)
+
# PARAM_READWRITE should come from the gi module but cannot due to:
# https://bugzilla.gnome.org/show_bug.cgi?id=687615
-PARAM_READWRITE = PARAM_READABLE | PARAM_WRITABLE
-__all__ += ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
- 'PARAM_READABLE', 'PARAM_WRITABLE', 'PARAM_READWRITE']
+PARAM_READWRITE = GObjectModule.ParamFlags.READABLE | \
+ GObjectModule.ParamFlags.WRITABLE
+__all__.append("PARAM_READWRITE")
+# READWRITE is part of ParamFlags since glib 2.42. Only mark PARAM_READWRITE as
+# deprecated in case ParamFlags.READWRITE is available. Also include the glib
+# version in the warning so it's clear that this needs a newer glib, unlike
+# the other ParamFlags related deprecations.
+# https://bugzilla.gnome.org/show_bug.cgi?id=726037
+if hasattr(GObjectModule.ParamFlags, "READWRITE"):
+ deprecated_attr("GObject", "PARAM_READWRITE",
+ "GObject.ParamFlags.READWRITE (glib 2.42+)")
-# Deprecated, use: GObject.SignalFlags.* directly
-SIGNAL_ACTION = GObjectModule.SignalFlags.ACTION
-SIGNAL_DETAILED = GObjectModule.SignalFlags.DETAILED
-SIGNAL_NO_HOOKS = GObjectModule.SignalFlags.NO_HOOKS
-SIGNAL_NO_RECURSE = GObjectModule.SignalFlags.NO_RECURSE
-SIGNAL_RUN_CLEANUP = GObjectModule.SignalFlags.RUN_CLEANUP
-SIGNAL_RUN_FIRST = GObjectModule.SignalFlags.RUN_FIRST
-SIGNAL_RUN_LAST = GObjectModule.SignalFlags.RUN_LAST
-__all__ += ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
- 'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
- 'SIGNAL_RUN_LAST']
+# Deprecated, use: GObject.SignalFlags.* directly
+for name in ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
+ 'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
+ 'SIGNAL_RUN_LAST']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GObjectModule.SignalFlags, new_name)
+ deprecated_attr("GObject", name, "GObject.SignalFlags." + new_name)
+ __all__.append(name)
# Static types
GBoxed = _gobject.GBoxed
class Value(GObjectModule.Value):
- def __new__(cls, *args, **kwargs):
- return GObjectModule.Value.__new__(cls)
-
def __init__(self, value_type=None, py_value=None):
GObjectModule.Value.__init__(self)
if value_type is not None:
if self._free_on_dealloc and self.g_type != TYPE_INVALID:
self.unset()
+ # We must call base class __del__() after unset.
+ super(Value, self).__del__()
+
def set_boxed(self, boxed):
# Workaround the introspection marshalers inability to know
# these methods should be marshaling boxed types. This is because
def __repr__(self):
return '<Value (%s) %s>' % (self.g_type.name, self.get_value())
+
Value = override(Value)
__all__.append('Value')
raise RuntimeError('unknown type name: %s' % name)
return type_
+
__all__.append('type_from_name')
raise RuntimeError('no parent for type')
return parent
+
__all__.append('type_parent')
_validate_type_for_signal_method(type_)
return GObjectModule.signal_list_ids(type_)
+
__all__.append('signal_list_ids')
ids = signal_list_ids(type_)
return tuple(GObjectModule.signal_name(i) for i in ids)
+
__all__.append('signal_list_names')
_validate_type_for_signal_method(type_)
return GObjectModule.signal_lookup(name, type_)
+
__all__.append('signal_lookup')
+SignalQuery = namedtuple('SignalQuery',
+ ['signal_id',
+ 'signal_name',
+ 'itype',
+ 'signal_flags',
+ 'return_type',
+ # n_params',
+ 'param_types'])
+
+
def signal_query(id_or_name, type_=None):
- SignalQuery = namedtuple('SignalQuery',
- ['signal_id',
- 'signal_name',
- 'itype',
- 'signal_flags',
- 'return_type',
- # n_params',
- 'param_types'])
-
- # signal_query needs to use a static method until the following bugs are fixed:
- # https://bugzilla.gnome.org/show_bug.cgi?id=687550
- # https://bugzilla.gnome.org/show_bug.cgi?id=687545
- # https://bugzilla.gnome.org/show_bug.cgi?id=687541
if type_ is not None:
id_or_name = signal_lookup(id_or_name, type_)
- res = _gobject.signal_query(id_or_name)
+ res = GObjectModule.signal_query(id_or_name)
if res is None:
return None
- # Return a named tuple which allows indexing like the static bindings
- # along with field like access of the gi struct.
- # Note however that the n_params was not returned from the static bindings.
- return SignalQuery(*res)
+ if res.signal_id == 0:
+ return None
+
+ # Return a named tuple to allows indexing which is compatible with the
+ # static bindings along with field like access of the gi struct.
+ # Note however that the n_params was not returned from the static bindings
+ # so we must skip over it.
+ return SignalQuery(res.signal_id, res.signal_name, res.itype,
+ res.signal_flags, res.return_type,
+ tuple(res.param_types))
+
__all__.append('signal_query')
def signal_handler_block(obj, handler_id):
- """Blocks the signal handler from being invoked until handler_unblock() is called.
+ """Blocks the signal handler from being invoked until
+ handler_unblock() is called.
+
+ :param GObject.Object obj:
+ Object instance to block handlers for.
+ :param int handler_id:
+ Id of signal to block.
+ :returns:
+ A context manager which optionally can be used to
+ automatically unblock the handler:
- Returns a context manager which optionally can be used to
- automatically unblock the handler:
+ .. code-block:: python
- with GObject.signal_handler_block(obj, id):
- pass
+ with GObject.signal_handler_block(obj, id):
+ pass
"""
GObjectModule.signal_handler_block(obj, handler_id)
return _HandlerBlockManager(obj, handler_id)
+
__all__.append('signal_handler_block')
def signal_parse_name(detailed_signal, itype, force_detail_quark):
"""Parse a detailed signal name into (signal_id, detail).
- :Raises ValueError:
- If the given signal is unknown.
-
- :Returns:
+ :param str detailed_signal:
+ Signal name which can include detail.
+ For example: "notify:prop_name"
+ :returns:
Tuple of (signal_id, detail)
+ :raises ValueError:
+ If the given signal is unknown.
"""
res, signal_id, detail = GObjectModule.signal_parse_name(detailed_signal, itype,
force_detail_quark)
else:
raise ValueError('%s: unknown signal name: %s' % (itype, detailed_signal))
+
__all__.append('signal_parse_name')
signal_id, detail = signal_parse_name(detailed_signal, obj, True)
GObjectModule.signal_remove_emission_hook(signal_id, hook_id)
+
__all__.append('remove_emission_hook')
# Stop emission but return the result of the last handler
return (False, handler_return)
+
__all__.append('signal_accumulator_first_wins')
# Stop emission if the last handler returns True
return (not handler_return, handler_return)
+
__all__.append('signal_accumulator_true_handled')
# Function wrapper for signal functions used as instance methods.
# This is needed when the signal functions come directly from GI.
# (they are not already wrapped)
- @functools.wraps(func)
+ @gi.overrides.wraps(func)
def meth(*args, **kwargs):
return func(*args, **kwargs)
return meth
def freeze_notify(self):
"""Freezes the object's property-changed notification queue.
+ :returns:
+ A context manager which optionally can be used to
+ automatically thaw notifications.
+
This will freeze the object so that "notify" signals are blocked until
the thaw_notify() method is called.
- Returns a context manager which optionally can be used to
- automatically thaw notifications:
+ .. code-block:: python
- with obj.freeze_notify():
- pass
+ with obj.freeze_notify():
+ pass
"""
super(Object, self).freeze_notify()
return _FreezeNotifyManager(self)
+ def connect_data(self, detailed_signal, handler, *data, **kwargs):
+ """Connect a callback to the given signal with optional user data.
+
+ :param str detailed_signal:
+ A detailed signal to connect to.
+ :param callable handler:
+ Callback handler to connect to the signal.
+ :param *data:
+ Variable data which is passed through to the signal handler.
+ :param GObject.ConnectFlags connect_flags:
+ Flags used for connection options.
+ :returns:
+ A signal id which can be used with disconnect.
+ """
+ flags = kwargs.get('connect_flags', 0)
+ if flags & GObjectModule.ConnectFlags.AFTER:
+ connect_func = _gobject.GObject.connect_after
+ else:
+ connect_func = _gobject.GObject.connect
+
+ if flags & GObjectModule.ConnectFlags.SWAPPED:
+ if len(data) != 1:
+ raise ValueError('Using GObject.ConnectFlags.SWAPPED requires exactly '
+ 'one argument for user data, got: %s' % [data])
+
+ def new_handler(obj, *args):
+ # Swap obj with the last element in args which will be the user
+ # data passed to the connect function.
+ args = list(args)
+ swap = args.pop()
+ args = args + [obj]
+ return handler(swap, *args)
+ else:
+ new_handler = handler
+
+ return connect_func(self, detailed_signal, new_handler, *data)
+
#
# Aliases
#
# Deprecated naming "property" available for backwards compatibility.
# Keep this at the end of the file to avoid clobbering the builtin.
property = Property
+deprecated_attr("GObject", "property", "GObject.Property")
__all__ += ['Property', 'Signal', 'SignalOverride', 'property']