[pygobject] Allow calling io_add_watch with a file object



commit 0f94a0a4ebd2bbfd06d8f9a2bb2b17dabf7678ef
Author: Martin Pitt <martinpitt gnome org>
Date:   Mon Oct 29 23:00:31 2012 +0100

    Allow calling io_add_watch with a file object
    
    The old static bindings allowed that, so we need to allow it to maintain
    backwards compatibility. Deprecate this mode as well, so that we can get rid of
    it at some point.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687047

 gi/overrides/GLib.py |    7 +++++++
 tests/test_glib.py   |   26 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index c785b9e..e1146ac 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -601,6 +601,7 @@ __all__.append('timeout_add_seconds')
 # The real GLib API is io_add_watch(IOChannel, priority, condition, callback,
 # user_data). This needs to take into account several deprecated APIs:
 # - calling with an fd as first argument
+# - calling with a Python file object as first argument
 # - calling without a priority as second argument
 # and the usual "call without user_data", in which case the callback does not
 # get an user_data either.
@@ -627,6 +628,12 @@ def io_add_watch(channel, priority, condition, callback=_unspecified, user_data=
                       PyGIDeprecationWarning)
         func_fdtransform = lambda _, cond, data: func(channel, cond, data)
         real_channel = GLib.IOChannel.unix_new(channel)
+    elif isinstance(channel, file):
+        # backwards compatibility: Allow calling with Python file
+        warnings.warn('Calling io_add_watch with a file object is deprecated; call it with a GLib.IOChannel object',
+                      PyGIDeprecationWarning)
+        func_fdtransform = lambda _, cond, data: func(channel, cond, data)
+        real_channel = GLib.IOChannel.unix_new(channel.fileno())
     else:
         assert isinstance(channel, GLib.IOChannel)
         func_fdtransform = func
diff --git a/tests/test_glib.py b/tests/test_glib.py
index 3753ea6..59004ae 100644
--- a/tests/test_glib.py
+++ b/tests/test_glib.py
@@ -4,6 +4,7 @@
 import unittest
 import os.path
 import warnings
+import subprocess
 
 from gi.repository import GLib
 from gi import PyGIDeprecationWarning
@@ -153,3 +154,28 @@ https://my.org/q?x=1&y=2
 
         self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', 'moo'),
                                      (r, GLib.IOCondition.IN, b'b', 'moo')])
+
+    def test_io_add_watch_pyfile(self):
+        call_data = []
+
+        cmd = subprocess.Popen('sleep 0.1; echo hello; sleep 0.2; echo world',
+                               shell=True, stdout=subprocess.PIPE)
+
+        def cb(file, condition):
+            call_data.append((file, condition, file.readline()))
+            return True
+
+        # io_add_watch() takes an IOChannel, calling with a Python file is deprecated
+        with warnings.catch_warnings(record=True) as warn:
+            warnings.simplefilter('always')
+            GLib.io_add_watch(cmd.stdout, GLib.IOCondition.IN, cb)
+            self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
+
+        ml = GLib.MainLoop()
+        GLib.timeout_add(400, ml.quit)
+        ml.run()
+
+        cmd.wait()
+
+        self.assertEqual(call_data, [(cmd.stdout, GLib.IOCondition.IN, b'hello\n'),
+                                     (cmd.stdout, GLib.IOCondition.IN, b'world\n')])



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]