diff options
author | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:16:14 +0300 |
---|---|---|
committer | shmel1k <shmel1k@ydb.tech> | 2023-11-26 18:43:30 +0300 |
commit | b8cf9e88f4c5c64d9406af533d8948deb050d695 (patch) | |
tree | 218eb61fb3c3b96ec08b4d8cdfef383104a87d63 /contrib/python/Twisted/py2/twisted/internet/gireactor.py | |
parent | 523f645a83a0ec97a0332dbc3863bb354c92a328 (diff) | |
download | ydb-b8cf9e88f4c5c64d9406af533d8948deb050d695.tar.gz |
add kikimr_configure
Diffstat (limited to 'contrib/python/Twisted/py2/twisted/internet/gireactor.py')
-rw-r--r-- | contrib/python/Twisted/py2/twisted/internet/gireactor.py | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/contrib/python/Twisted/py2/twisted/internet/gireactor.py b/contrib/python/Twisted/py2/twisted/internet/gireactor.py new file mode 100644 index 0000000000..f1b0d27333 --- /dev/null +++ b/contrib/python/Twisted/py2/twisted/internet/gireactor.py @@ -0,0 +1,188 @@ +# Copyright (c) Twisted Matrix Laboratories. +# See LICENSE for details. + +""" +This module provides support for Twisted to interact with the glib +mainloop via GObject Introspection. + +In order to use this support, simply do the following:: + + from twisted.internet import gireactor + gireactor.install() + +If you wish to use a GApplication, register it with the reactor:: + + from twisted.internet import reactor + reactor.registerGApplication(app) + +Then use twisted.internet APIs as usual. + +On Python 3, pygobject v3.4 or later is required. +""" + +from __future__ import division, absolute_import + +from twisted.python.compat import _PY3 +from twisted.internet.error import ReactorAlreadyRunning +from twisted.internet import _glibbase +from twisted.python import runtime + +if _PY3: + # We require a sufficiently new version of pygobject, so always exists: + _pygtkcompatPresent = True +else: + # We can't just try to import gi.pygtkcompat, because that would import + # gi, and the goal here is to not import gi in cases where that would + # cause segfault. + from twisted.python.modules import theSystemPath + _pygtkcompatPresent = True + try: + theSystemPath["gi.pygtkcompat"] + except KeyError: + _pygtkcompatPresent = False + + +# Modules that we want to ensure aren't imported if we're on older versions of +# GI: +_PYGTK_MODULES = ['gobject', 'glib', 'gio', 'gtk'] + +def _oldGiInit(): + """ + Make sure pygtk and gi aren't loaded at the same time, and import Glib if + possible. + """ + # We can't immediately prevent imports, because that confuses some buggy + # code in gi: + _glibbase.ensureNotImported( + _PYGTK_MODULES, + "Introspected and static glib/gtk bindings must not be mixed; can't " + "import gireactor since pygtk2 module is already imported.") + + global GLib + from gi.repository import GLib + if getattr(GLib, "threads_init", None) is not None: + GLib.threads_init() + + _glibbase.ensureNotImported([], "", + preventImports=_PYGTK_MODULES) + + +if not _pygtkcompatPresent: + # Older versions of gi don't have compatibility layer, so just enforce no + # imports of pygtk and gi at same time: + _oldGiInit() +else: + # Newer version of gi, so we can try to initialize compatibility layer; if + # real pygtk was already imported we'll get ImportError at this point + # rather than segfault, so unconditional import is fine. + import gi.pygtkcompat + gi.pygtkcompat.enable() + # At this point importing gobject will get you gi version, and importing + # e.g. gtk will either fail in non-segfaulty way or use gi version if user + # does gi.pygtkcompat.enable_gtk(). So, no need to prevent imports of + # old school pygtk modules. + from gi.repository import GLib + if getattr(GLib, "threads_init", None) is not None: + GLib.threads_init() + + + +class GIReactor(_glibbase.GlibReactorBase): + """ + GObject-introspection event loop reactor. + + @ivar _gapplication: A C{Gio.Application} instance that was registered + with C{registerGApplication}. + """ + _POLL_DISCONNECTED = (GLib.IOCondition.HUP | GLib.IOCondition.ERR | + GLib.IOCondition.NVAL) + _POLL_IN = GLib.IOCondition.IN + _POLL_OUT = GLib.IOCondition.OUT + + # glib's iochannel sources won't tell us about any events that we haven't + # asked for, even if those events aren't sensible inputs to the poll() + # call. + INFLAGS = _POLL_IN | _POLL_DISCONNECTED + OUTFLAGS = _POLL_OUT | _POLL_DISCONNECTED + + # By default no Application is registered: + _gapplication = None + + + def __init__(self, useGtk=False): + _gtk = None + if useGtk is True: + from gi.repository import Gtk as _gtk + + _glibbase.GlibReactorBase.__init__(self, GLib, _gtk, useGtk=useGtk) + + + def registerGApplication(self, app): + """ + Register a C{Gio.Application} or C{Gtk.Application}, whose main loop + will be used instead of the default one. + + We will C{hold} the application so it doesn't exit on its own. In + versions of C{python-gi} 3.2 and later, we exit the event loop using + the C{app.quit} method which overrides any holds. Older versions are + not supported. + """ + if self._gapplication is not None: + raise RuntimeError( + "Can't register more than one application instance.") + if self._started: + raise ReactorAlreadyRunning( + "Can't register application after reactor was started.") + if not hasattr(app, "quit"): + raise RuntimeError("Application registration is not supported in" + " versions of PyGObject prior to 3.2.") + self._gapplication = app + def run(): + app.hold() + app.run(None) + self._run = run + + self._crash = app.quit + + + +class PortableGIReactor(_glibbase.PortableGlibReactorBase): + """ + Portable GObject Introspection event loop reactor. + """ + def __init__(self, useGtk=False): + _gtk = None + if useGtk is True: + from gi.repository import Gtk as _gtk + + _glibbase.PortableGlibReactorBase.__init__(self, GLib, _gtk, + useGtk=useGtk) + + + def registerGApplication(self, app): + """ + Register a C{Gio.Application} or C{Gtk.Application}, whose main loop + will be used instead of the default one. + """ + raise NotImplementedError("GApplication is not currently supported on Windows.") + + + +def install(useGtk=False): + """ + Configure the twisted mainloop to be run inside the glib mainloop. + + @param useGtk: should GTK+ rather than glib event loop be + used (this will be slightly slower but does support GUI). + """ + if runtime.platform.getType() == 'posix': + reactor = GIReactor(useGtk=useGtk) + else: + reactor = PortableGIReactor(useGtk=useGtk) + + from twisted.internet.main import installReactor + installReactor(reactor) + return reactor + + +__all__ = ['install'] |