3 from gi import _gobject
5 # support overrides in different directories than our gi module
6 from pkgutil import extend_path
7 __path__ = extend_path(__path__, __name__)
12 class _Registry(dict):
13 def __setitem__(self, key, value):
14 '''We do checks here to make sure only submodules of the override
15 module are added. Key and value should be the same object and come
16 from the gi.override module.
18 We add the override to the dict as "override_module.name". For instance
19 if we were overriding Gtk.Button you would retrive it as such:
20 registry['Gtk.Button']
23 raise KeyError('You have tried to modify the registry. This should only be done by the override decorator')
26 info = getattr(value, '__info__')
27 except AttributeError:
28 raise TypeError('Can not override a type %s, which is not in a gobject introspection typelib' % value.__name__)
30 if not value.__module__.startswith('gi.overrides'):
31 raise KeyError('You have tried to modify the registry outside of the overrides module. This is not allowed')
33 g_type = info.get_g_type()
34 assert g_type != _gobject.TYPE_NONE
35 if g_type != _gobject.TYPE_INVALID:
38 # strip gi.overrides from module name
39 module = value.__module__[13:]
40 key = "%s.%s" % (module, value.__name__)
41 super(_Registry, self).__setitem__(key, value)
43 def register(self, override_class):
44 self[override_class] = override_class
47 class overridefunc(object):
48 '''decorator for overriding a function'''
49 def __init__(self, func):
50 if not hasattr(func, '__info__'):
51 raise TypeError("func must be an gi function")
52 from ..importer import modules
53 self.module = modules[func.__module__]._introspection_module
55 def __call__(self, func):
56 def wrapper(*args, **kwargs):
57 return func(*args, **kwargs)
58 wrapper.__name__ = func.__name__
59 setattr(self.module, func.__name__, wrapper)
62 registry = _Registry()
66 '''Decorator for registering an override'''
67 if isinstance(type_, types.FunctionType):
68 return overridefunc(type_)
70 registry.register(type_)