Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pika for openSUSE:Factory 
checked in at 2026-09-02 17:00:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pika (Old)
 and      /work/SRC/openSUSE:Factory/.python-pika.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pika"

Wed Sep  2 17:00:57 2026 rev:25 rq:1375242 version:1.4.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pika/python-pika.changes  2026-06-15 
19:48:26.936006579 +0200
+++ /work/SRC/openSUSE:Factory/.python-pika.new.1265/python-pika.changes        
2026-09-02 17:01:09.959043775 +0200
@@ -1,0 +2,11 @@
+Tue Sep  1 22:15:15 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.4.4:
+  * Revert "Fix callLater typing by passing keyword arguments"
+    #1678 (jeremycline)
+  * Importing pika.adapters can break asyncio subprocesses on
+    Windows #1639
+  * Stop mutating global asyncio event loop policy on import
+    #1642 (lukebakken)
+
+-------------------------------------------------------------------

Old:
----
  1.4.1.tar.gz

New:
----
  1.4.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pika.spec ++++++
--- /var/tmp/diff_new_pack.cwoUl3/_old  2026-09-02 17:01:12.409127940 +0200
+++ /var/tmp/diff_new_pack.cwoUl3/_new  2026-09-02 17:01:12.412128043 +0200
@@ -19,7 +19,7 @@
 %define mod_name pika
 %{?sle15_python_module_pythons}
 Name:           python-%{mod_name}
-Version:        1.4.1
+Version:        1.4.4
 Release:        0
 Summary:        Pika Python AMQP Client Library
 License:        BSD-3-Clause

++++++ 1.4.1.tar.gz -> 1.4.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/CHANGELOG.md new/pika-1.4.4/CHANGELOG.md
--- old/pika-1.4.1/CHANGELOG.md 2026-05-22 19:39:45.000000000 +0200
+++ new/pika-1.4.4/CHANGELOG.md 2026-08-06 22:45:29.000000000 +0200
@@ -1,5 +1,25 @@
 # Changelog
 
+## [1.4.4](https://github.com/pika/pika/tree/1.4.2) (2026-08-06)
+
+[Full Changelog](https://github.com/pika/pika/compare/1.4.2...1.4.4)
+
+**Merged pull requests:**
+
+- Revert "Fix callLater typing by passing keyword arguments" 
[\#1678](https://github.com/pika/pika/pull/1678) 
([jeremycline](https://github.com/jeremycline))
+
+## [1.4.2](https://github.com/pika/pika/tree/1.4.2) (2026-07-23)
+
+[Full Changelog](https://github.com/pika/pika/compare/1.4.1...1.4.2)
+
+**Closed issues:**
+
+- Importing pika.adapters can break asyncio subprocesses on Windows 
[\#1639](https://github.com/pika/pika/issues/1639)
+
+**Merged pull requests:**
+
+- Stop mutating global asyncio event loop policy on import 
[\#1642](https://github.com/pika/pika/pull/1642) 
([lukebakken](https://github.com/lukebakken))
+
 ## [1.4.1](https://github.com/pika/pika/tree/1.4.1) (2026-05-22)
 
 **Merged pull requests:**
@@ -1300,6 +1320,3 @@
         consumption loop.
     -   Updated stop_consuming() to iterate through all the registered
         consumers in self.\_consumers and issue a basic_cancel.
-
-
-\* *This Changelog was automatically generated by 
[github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/RELEASE.md new/pika-1.4.4/RELEASE.md
--- old/pika-1.4.1/RELEASE.md   2026-05-22 19:39:45.000000000 +0200
+++ new/pika-1.4.4/RELEASE.md   2026-08-06 22:45:29.000000000 +0200
@@ -1,22 +1,22 @@
 # Release process
 
-* Create `pika-1.5.0` branch
+* Create `pika-1.4.4` branch
 * Update `CHANGELOG.md`. Be sure to use the `--since-tag X.Y.Z` argument:
     ```
-    github_changelog_generator --token ghp_XXXX --user pika --project pika 
--since-tag 1.4.1 --future-release 1.5.0
+    github_changelog_generator --user pika --project pika --token $TOKEN 
--since-tag 1.4.4 --future-release 1.4.4 --release-branch 1.4.x
     ```
     Review the generated file for invalid entries. More than likely you will 
have to hand-edit `CHANGELOG.md`
 * Update version in `pyproject.toml` and `pika/__init__.py`
-* Commit changes to `pika-1.5.0` branch and push:
+* Commit changes to `pika-1.4.4` branch and push:
     ```
-    git commit -a -m 'pika 1.5.0' && git push
+    git commit -a -m 'pika 1.4.4' && git push origin pika-1.4.4
     ```
 * Open PR and ensure build is green
 * Merge PR
 * Update local `main`
 * Tag version (using your GPG keyid) and push:
     ```
-    git tag -a -s -u B1B82CC0CF84BA70147EBD05D99DE30E43EAE440 -m 'pika 1.5.0' 
'1.5.0' && git push --tags
+    git tag -a -s -u B1B82CC0CF84BA70147EBD05D99DE30E43EAE440 -m 'pika 1.4.4' 
'1.4.4' && git push --tags
     ```
 * Ensure build is green (if one triggered)
 * Note the release's milestone number, then create release via GitHub Release 
UI or `gh` command like:
@@ -25,22 +25,22 @@
     python -m build --sdist --wheel --outdir dist/ .
 
     # This creates the release on GitHub:
-    gh release create '1.5.0' --notes 'https://pypi.org/project/pika/1.5.0/ | 
[GitHub milestone](https://github.com/pika/pika/milestone/23?closed=1)' ./dist/*
+    gh release create '1.4.4' --notes 'https://pypi.org/project/pika/1.4.4/ | 
[GitHub milestone](https://github.com/pika/pika/milestone/27?closed=1)' ./dist/*
     ```
 * Ensure the publish build succeeded. Example success output looks like this:
     ```
-    Checking dist/pika-1.5.0-py3-none-any.whl: PASSED
-    Checking dist/pika-1.5.0.tar.gz: PASSED
+    Checking dist/pika-1.4.4-py3-none-any.whl: PASSED
+    Checking dist/pika-1.4.4.tar.gz: PASSED
     Uploading distributions to https://upload.pypi.org/legacy/
-    Uploading pika-1.5.0-py3-none-any.whl
+    Uploading pika-1.4.4-py3-none-any.whl
     ...
     ...
     ...
     View at:
-    https://pypi.org/project/pika/1.5.0/
+    https://pypi.org/project/pika/1.4.4/
     ```
 
-* View the release on PyPI: https://pypi.org/project/pika/1.5.0/
+* View the release on PyPI: https://pypi.org/project/pika/1.4.4/
 * Ensure the release works!
   * Start RabbitMQ
     ```
@@ -51,7 +51,7 @@
     cd path/to/pika/examples
     python -m venv venv
     source ./venv/bin/activate
-    pip install pika==1.5.0
+    pip install pika==1.4.4
     python ./asynchronous_publisher_example.py
     ```
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/pika/__init__.py 
new/pika-1.4.4/pika/__init__.py
--- old/pika-1.4.1/pika/__init__.py     2026-05-22 19:39:45.000000000 +0200
+++ new/pika-1.4.4/pika/__init__.py     2026-08-06 22:45:29.000000000 +0200
@@ -1,4 +1,4 @@
-__version__ = '1.4.1'
+__version__ = '1.4.4'
 
 import logging
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/pika/adapters/asyncio_connection.py 
new/pika-1.4.4/pika/adapters/asyncio_connection.py
--- old/pika-1.4.1/pika/adapters/asyncio_connection.py  2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/pika/adapters/asyncio_connection.py  2026-08-06 
22:45:29.000000000 +0200
@@ -14,9 +14,6 @@
 
 LOGGER = logging.getLogger(__name__)
 
-if sys.platform == 'win32':
-    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
-
 
 class AsyncioConnection(base_connection.BaseConnection):
     """ The AsyncioConnection runs on the Asyncio EventLoop.
@@ -133,7 +130,18 @@
             try:
                 loop = asyncio.get_running_loop()
             except RuntimeError:
-                loop = asyncio.new_event_loop()
+                if sys.platform == 'win32':
+                    loop = asyncio.SelectorEventLoop()
+                else:
+                    loop = asyncio.new_event_loop()
+        if sys.platform == 'win32' and not isinstance(
+                loop, asyncio.SelectorEventLoop):
+            raise TypeError(
+                'On Windows, Pika requires an asyncio.SelectorEventLoop '
+                'because it uses add_reader/add_writer. The running loop '
+                f'is {type(loop).__name__}. Either pass a SelectorEventLoop '
+                'via custom_ioloop, or run with '
+                'asyncio.run(main(), loop_factory=asyncio.SelectorEventLoop).')
         self._loop = loop
 
     def get_native_ioloop(self) -> asyncio.AbstractEventLoop:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/pika/adapters/twisted_connection.py 
new/pika-1.4.4/pika/adapters/twisted_connection.py
--- old/pika-1.4.1/pika/adapters/twisted_connection.py  2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/pika/adapters/twisted_connection.py  2026-08-06 
22:45:29.000000000 +0200
@@ -1137,7 +1137,15 @@
                          on_close_callback=on_close_callback,
                          internal_connection_workflow=False)
 
-        self._reactor = custom_reactor or reactor
+        # Annotated as `Any` rather than as a reactor interface on purpose.
+        # Reactor implementations rename the parameters the interfaces
+        # declare: `IReactorTime.callLater(delay, callable, *args, **kw)` but
+        # `AsyncioSelectorReactor.callLater(seconds, f, *args, **kwargs)`.
+        # Only positional arguments work across every reactor, and a typed
+        # attribute makes the type checker reject the positional call because
+        # `IReactorTime.callLater` is unbound, so `delay` is consumed as
+        # `self`. See https://github.com/pika/pika/pull/1678.
+        self._reactor: Any = custom_reactor or reactor
         self._transport: Optional[
             twisted.internet.interfaces.
             ITransport] = None  # to be provided by `connection_made()`
@@ -1148,8 +1156,7 @@
 
         """
         check_callback_arg(callback, 'callback')
-        return _TimerHandle(self._reactor.callLater(
-            delay, callback))  # pyright: ignore[reportAttributeAccessIssue]
+        return _TimerHandle(self._reactor.callLater(delay, callback))
 
     def _adapter_remove_timeout(self, timeout_id: Any) -> None:
         """Implement
@@ -1165,8 +1172,7 @@
 
         """
         check_callback_arg(callback, 'callback')
-        self._reactor.callFromThread(
-            callback)  # pyright: ignore[reportAttributeAccessIssue]
+        self._reactor.callFromThread(callback)
 
     def _adapter_connect_stream(self) -> None:
         """Implement pure virtual
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/pyproject.toml 
new/pika-1.4.4/pyproject.toml
--- old/pika-1.4.1/pyproject.toml       2026-05-22 19:39:45.000000000 +0200
+++ new/pika-1.4.4/pyproject.toml       2026-08-06 22:45:29.000000000 +0200
@@ -4,7 +4,7 @@
 
 [project]
 name = "pika"
-version = "1.4.1"
+version = "1.4.4"
 maintainers = [
     {name = "Gavin M. Roy", email = "[email protected]"},
     {name = "Luke Bakken", email = "[email protected]"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/acceptance/twisted_adapter_tests.py 
new/pika-1.4.4/tests/acceptance/twisted_adapter_tests.py
--- old/pika-1.4.1/tests/acceptance/twisted_adapter_tests.py    2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/tests/acceptance/twisted_adapter_tests.py    2026-08-06 
22:45:29.000000000 +0200
@@ -828,15 +828,36 @@
         self.conn._impl.close.assert_not_called()
 
 
+class _AsyncioReactorSignatureStub:
+    """
+    A reactor stub using `AsyncioSelectorReactor`'s parameter names.
+
+    `AsyncioSelectorReactor.callLater(seconds, f, *args, **kwargs)` renames 
the parameters that
+    `IReactorTime.callLater(delay, callable, *args, **kw)` declares, so only 
positional arguments
+    work across every reactor.
+    """
+
+    def __init__(self):
+        self.call_later_args = []
+
+    def callLater(self, seconds, f, *args, **kwargs):
+        self.call_later_args.append((seconds, f, args, kwargs))
+        return mock.Mock()
+
+
 class TwistedConnectionAdapterTestCase(TestCase):
 
     def setUp(self):
         self.conn = _TwistedConnectionAdapter(None, None, None, None, None)
 
     def tearDown(self):
-        if self.conn._transport is None:
-            self.conn._transport = mock.Mock()
-        self.conn.close()
+        self._close_adapter(self.conn)
+
+    @staticmethod
+    def _close_adapter(conn):
+        if conn._transport is None:
+            conn._transport = mock.Mock()
+        conn.close()
 
     def test_adapter_disconnect_stream(self):
         # Verify that the underlying transport is aborted.
@@ -861,6 +882,18 @@
         self.assertNotIn(timer_id._handle, reactor.getDelayedCalls())
         callback.assert_not_called()
 
+    def test_timeout_passes_positional_args(self):
+        # Verify that `callLater` is called positionally. The default reactor
+        # names its parameters `delay` and `callable`, so a keyword call passes
+        # here while crashing on `AsyncioSelectorReactor`, which names them
+        # `seconds` and `f`.
+        callback = mock.Mock()
+        stub = _AsyncioReactorSignatureStub()
+        conn = _TwistedConnectionAdapter(None, None, None, None, stub)
+        self.addCleanup(self._close_adapter, conn)
+        conn._adapter_call_later(5, callback)
+        self.assertEqual(stub.call_later_args, [(5, callback, (), {})])
+
     @pytest.mark.timeout(5)
     def test_call_threadsafe(self):
         # Verify that the method is actually called using the reactor's
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/base/async_test_base.py 
new/pika-1.4.4/tests/base/async_test_base.py
--- old/pika-1.4.1/tests/base/async_test_base.py        2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/tests/base/async_test_base.py        2026-08-06 
22:45:29.000000000 +0200
@@ -370,7 +370,7 @@
     @run_test_in_thread_with_timeout
     def test_with_asyncio(self):
         """AsyncioConnection"""
-        import asyncio
         from pika.adapters.asyncio_connection import AsyncioConnection
-        ioloop_factory = asyncio.new_event_loop
+        from tests.base.asyncio_loop import new_pika_asyncio_loop
+        ioloop_factory = new_pika_asyncio_loop
         self.start(AsyncioConnection, ioloop_factory)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/base/asyncio_loop.py 
new/pika-1.4.4/tests/base/asyncio_loop.py
--- old/pika-1.4.1/tests/base/asyncio_loop.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/pika-1.4.4/tests/base/asyncio_loop.py   2026-08-06 22:45:29.000000000 
+0200
@@ -0,0 +1,19 @@
+"""Shared helper for creating asyncio event loops in tests."""
+
+from __future__ import annotations
+
+import asyncio
+import sys
+
+
+def new_pika_asyncio_loop() -> asyncio.AbstractEventLoop:
+    """
+    Create a new asyncio event loop suitable for Pika's AsyncioConnection.
+
+    On Windows, Pika requires a `SelectorEventLoop` because it uses 
`add_reader`/`add_writer`, which
+    the default `ProactorEventLoop` does not support. Elsewhere, the default
+    `asyncio.new_event_loop()` is selector-based.
+    """
+    if sys.platform == 'win32':
+        return asyncio.SelectorEventLoop()
+    return asyncio.new_event_loop()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/stubs/io_services_test_stubs.py 
new/pika-1.4.4/tests/stubs/io_services_test_stubs.py
--- old/pika-1.4.1/tests/stubs/io_services_test_stubs.py        2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/tests/stubs/io_services_test_stubs.py        2026-08-06 
22:45:29.000000000 +0200
@@ -113,10 +113,10 @@
         # Test entry point for `asyncio` event loop-based io services
         # implementation.
 
-        import asyncio
         from pika.adapters.asyncio_connection import 
(_AsyncioIOServicesAdapter)
+        from tests.base.asyncio_loop import new_pika_asyncio_loop
 
-        native_loop = asyncio.new_event_loop()
+        native_loop = new_pika_asyncio_loop()
         self._run_start(
             nbio_factory=lambda: _AsyncioIOServicesAdapter(native_loop),
             native_loop=native_loop)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/unit/asyncio_connection_tests.py 
new/pika-1.4.4/tests/unit/asyncio_connection_tests.py
--- old/pika-1.4.1/tests/unit/asyncio_connection_tests.py       2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/tests/unit/asyncio_connection_tests.py       2026-08-06 
22:45:29.000000000 +0200
@@ -5,8 +5,10 @@
 import asyncio
 import threading
 import unittest
+from unittest.mock import patch
 
 from pika.adapters.asyncio_connection import _AsyncioIOServicesAdapter
+from tests.base.asyncio_loop import new_pika_asyncio_loop
 
 # missing-docstring
 # pylint: disable=C0111
@@ -19,7 +21,7 @@
     """Tests for _AsyncioIOServicesAdapter loop initialisation logic."""
 
     def test_explicit_loop_is_used_as_is(self):
-        loop = asyncio.new_event_loop()
+        loop = new_pika_asyncio_loop()
         try:
             adapter = _AsyncioIOServicesAdapter(loop)
             self.assertIs(adapter.get_native_ioloop(), loop)
@@ -33,7 +35,7 @@
             adapter = _AsyncioIOServicesAdapter()
             results.append(adapter.get_native_ioloop())
 
-        loop = asyncio.new_event_loop()
+        loop = new_pika_asyncio_loop()
         try:
             loop.run_until_complete(_run())
             self.assertIs(results[0], loop)
@@ -69,3 +71,51 @@
         self.assertEqual(errors, [])
         self.assertEqual(len(results), 1)
         self.assertIsInstance(results[0], asyncio.AbstractEventLoop)
+
+    @patch('pika.adapters.asyncio_connection.sys')
+    def test_windows_proactor_loop_raises_type_error(self, mock_sys):
+        mock_sys.platform = 'win32'
+        mock_sys.version_info = (3, 12)
+        if not hasattr(asyncio, 'ProactorEventLoop'):
+            self.skipTest('ProactorEventLoop not available on this OS')
+        loop = asyncio.ProactorEventLoop()
+        try:
+            with self.assertRaises(TypeError) as ctx:
+                _AsyncioIOServicesAdapter(loop)
+            self.assertIn('SelectorEventLoop', str(ctx.exception))
+        finally:
+            loop.close()
+
+    @patch('pika.adapters.asyncio_connection.sys')
+    def test_windows_selector_loop_accepted(self, mock_sys):
+        mock_sys.platform = 'win32'
+        mock_sys.version_info = (3, 12)
+        loop = asyncio.SelectorEventLoop()
+        try:
+            adapter = _AsyncioIOServicesAdapter(loop)
+            self.assertIs(adapter.get_native_ioloop(), loop)
+        finally:
+            loop.close()
+
+    @patch('pika.adapters.asyncio_connection.sys')
+    def test_windows_no_loop_creates_selector_event_loop(self, mock_sys):
+        mock_sys.platform = 'win32'
+        mock_sys.version_info = (3, 12)
+        results = []
+        errors = []
+
+        def _thread_target():
+            try:
+                adapter = _AsyncioIOServicesAdapter()
+                results.append(adapter.get_native_ioloop())
+            except Exception as exc:
+                errors.append(exc)
+
+        t = threading.Thread(target=_thread_target)
+        t.start()
+        t.join()
+
+        self.assertEqual(errors, [])
+        self.assertEqual(len(results), 1)
+        self.assertIsInstance(results[0], asyncio.SelectorEventLoop)
+        results[0].close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pika-1.4.1/tests/unit/io_services_test_stubs_test.py 
new/pika-1.4.4/tests/unit/io_services_test_stubs_test.py
--- old/pika-1.4.1/tests/unit/io_services_test_stubs_test.py    2026-05-22 
19:39:45.000000000 +0200
+++ new/pika-1.4.4/tests/unit/io_services_test_stubs_test.py    2026-08-06 
22:45:29.000000000 +0200
@@ -2,8 +2,6 @@
 Test for io_services_test_stubs.py
 """
 
-import pika.compat
-
 try:
     import asyncio
 except ImportError:
@@ -15,7 +13,7 @@
 import tornado.ioloop
 
 from pika.adapters import select_connection
-
+from tests.base.asyncio_loop import new_pika_asyncio_loop
 from tests.stubs.io_services_test_stubs import IOServicesTestStubs
 
 # Suppress invalid-name, since our test names are descriptive and quite long
@@ -26,9 +24,7 @@
 # pylint: disable=C0111
 
 if asyncio is not None:
-    if pika.compat.ON_WINDOWS:
-        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
-    loop = asyncio.new_event_loop()
+    loop = new_pika_asyncio_loop()
     asyncio.set_event_loop(loop)
 else:
     loop = None
@@ -90,6 +86,16 @@
         self.assertNotEqual(threading.current_thread().ident,
                             self._runner_thread_id)
 
-        # And make sure the loop actually works using this rudimentary test
-        nbio.add_callback_threadsafe(nbio.stop)
+        # And make sure the loop actually works using this rudimentary test.
+        #
+        # NOTE: stop is scheduled two turns out rather than one. On Windows,
+        # Tornado wraps the Proactor loop in an AddThreadSelectorEventLoop
+        # whose SelectorThread defers starting (and thus awaiting its
+        # `thread_manager_anext` bootstrap task) until the loop's first turn.
+        # Stopping after a single turn destroys that task while still pending,
+        # producing a "coroutine was never awaited" RuntimeWarning. Letting the
+        # loop run one extra turn lets the task start so close() tears it down
+        # cleanly.
+        nbio.add_callback_threadsafe(
+            lambda: nbio.add_callback_threadsafe(nbio.stop))
         nbio.run()

Reply via email to