Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-libvirt-python for 
openSUSE:Factory checked in at 2022-07-07 12:56:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-libvirt-python (Old)
 and      /work/SRC/openSUSE:Factory/.python-libvirt-python.new.1523 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-libvirt-python"

Thu Jul  7 12:56:37 2022 rev:58 rq:987262 version:8.5.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-libvirt-python/python-libvirt-python.changes  
    2022-06-03 14:15:45.417245583 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-libvirt-python.new.1523/python-libvirt-python.changes
    2022-07-07 12:56:55.575284147 +0200
@@ -1,0 +2,6 @@
+Tue Jul  5 22:54:11 UTC 2022 - James Fehlig <jfeh...@suse.com>
+
+- Update to 8.5.0
+  - Add all new APIs and constants in libvirt 8.5.0
+
+-------------------------------------------------------------------

Old:
----
  libvirt-python-8.4.0.tar.gz

New:
----
  libvirt-python-8.5.0.tar.gz

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

Other differences:
------------------
++++++ python-libvirt-python.spec ++++++
--- /var/tmp/diff_new_pack.JEkN8o/_old  2022-07-07 12:56:56.075284891 +0200
+++ /var/tmp/diff_new_pack.JEkN8o/_new  2022-07-07 12:56:56.075284891 +0200
@@ -23,7 +23,7 @@
 %define srcname libvirt-python
 Name:           python-libvirt-python
 URL:            https://libvirt.org/
-Version:        8.4.0
+Version:        8.5.0
 Release:        0
 Summary:        Library providing a virtualization API
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.JEkN8o/_old  2022-07-07 12:56:56.103284933 +0200
+++ /var/tmp/diff_new_pack.JEkN8o/_new  2022-07-07 12:56:56.107284939 +0200
@@ -1,7 +1,7 @@
 <services>
   <service name="tar_scm" mode="disabled">
     <param name="filename">libvirt-python</param>
-    <param name="revision">v8.4.0</param>
+    <param name="revision">v8.5.0</param>
     <param name="scm">git</param>
     <param name="submodules">disable</param>
     <param name="url">https://gitlab.com/libvirt/libvirt-python.git</param>

++++++ libvirt-python-8.4.0.tar.gz -> libvirt-python-8.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libvirt-python-8.4.0/examples/event-test.py 
new/libvirt-python-8.5.0/examples/event-test.py
--- old/libvirt-python-8.4.0/examples/event-test.py     2022-05-13 
13:28:11.000000000 +0200
+++ new/libvirt-python-8.5.0/examples/event-test.py     2022-06-25 
06:38:30.000000000 +0200
@@ -438,8 +438,9 @@
 def virEventLoopPollStart() -> None:
     global eventLoopThread
     virEventLoopPollRegister()
-    eventLoopThread = threading.Thread(target=virEventLoopPollRun, 
name="libvirtEventLoop")
-    eventLoopThread.setDaemon(True)
+    eventLoopThread = threading.Thread(target=virEventLoopPollRun,
+                                       name="libvirtEventLoop",
+                                       daemon=True)
     eventLoopThread.start()
 
 
@@ -449,16 +450,19 @@
     import asyncio
     loop = asyncio.new_event_loop()
     libvirtaio.virEventRegisterAsyncIOImpl(loop=loop)
-    eventLoopThread = threading.Thread(target=virEventLoopAIORun, 
args=(loop,), name="libvirtEventLoop")
-    eventLoopThread.setDaemon(True)
+    eventLoopThread = threading.Thread(target=virEventLoopAIORun,
+                                       args=(loop,),
+                                       name="libvirtEventLoop",
+                                       daemon=True)
     eventLoopThread.start()
 
 
 def virEventLoopNativeStart() -> None:
     global eventLoopThread
     libvirt.virEventRegisterDefaultImpl()
-    eventLoopThread = threading.Thread(target=virEventLoopNativeRun, 
name="libvirtEventLoop")
-    eventLoopThread.setDaemon(True)
+    eventLoopThread = threading.Thread(target=virEventLoopNativeRun,
+                                       name="libvirtEventLoop",
+                                       daemon=True)
     eventLoopThread.start()
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libvirt-python-8.4.0/libvirtaio.py 
new/libvirt-python-8.5.0/libvirtaio.py
--- old/libvirt-python-8.4.0/libvirtaio.py      2022-05-13 13:28:11.000000000 
+0200
+++ new/libvirt-python-8.5.0/libvirtaio.py      2022-06-25 06:38:30.000000000 
+0200
@@ -21,8 +21,27 @@
 
 Register the implementation of default loop:
 
-    >>> import libvirtaio
-    >>> libvirtaio.virEventRegisterAsyncIOImpl()
+    import asyncio
+    import libvirtaio
+
+    async def myapp():
+      libvirtaio.virEventRegisterAsyncIOImpl()
+
+      conn = libvirt.open("test:///default")
+
+For compatibility with Python < 3.7:
+
+    loop = asyncio.new_event_loop()
+    asyncio.set_event_loop(loop)
+
+    loop.run_until_complete(myapp())
+
+    asyncio.set_event_loop(None)
+    loop.close()
+
+If Python >= 3.7 can be required then
+
+    asyncio.run(myapp())
 
 .. seealso::
     https://libvirt.org/html/libvirt-libvirt-event.html
@@ -46,14 +65,6 @@
     'virEventRegisterAsyncIOImpl',
 ]
 
-# Python < 3.4.4 doesn't have 'ensure_future', so we have to fall
-# back to 'async'; however, since 'async' is a reserved keyword
-# in Python >= 3.7, we can't perform a straightforward import and
-# we have to resort to getattr() instead
-ensure_future = getattr(asyncio, "ensure_future", None)
-if not ensure_future:
-    ensure_future = getattr(asyncio, "async")
-
 
 class Callback(object):
     '''Base class for holding callback
@@ -219,8 +230,7 @@
         return '<{} iden={} timeout={}>'.format(
             self.__class__.__name__, self.iden, self.timeout)
 
-    @asyncio.coroutine
-    def _timer(self) -> Generator[Any, None, None]:
+    async def _timer(self) -> Generator[Any, None, None]:
         '''An actual timer running on the event loop.
 
         This is a coroutine.
@@ -230,10 +240,10 @@
                 if self.timeout > 0:
                     timeout = self.timeout * 1e-3
                     self.impl.log.debug('sleeping %r', timeout)
-                    yield from asyncio.sleep(timeout)
+                    await asyncio.sleep(timeout)
                 else:
                     # scheduling timeout for next loop iteration
-                    yield
+                    await asyncio.sleep(0)
 
             except asyncio.CancelledError:
                 self.impl.log.debug('timer %d cancelled', self.iden)
@@ -248,8 +258,8 @@
 
         if self.timeout >= 0 and self._task is None:
             self.impl.log.debug('timer %r start', self.iden)
-            self._task = ensure_future(self._timer(),
-                                       loop=self.impl.loop)
+            self._task = asyncio.ensure_future(self._timer(),
+                                               loop=self.impl.loop)
 
         elif self.timeout < 0 and self._task is not None:
             self.impl.log.debug('timer %r stop', self.iden)
@@ -280,10 +290,11 @@
         self.descriptors = DescriptorDict(self)
         self.log = logging.getLogger(self.__class__.__name__)
 
-        # NOTE invariant: _finished.is_set() iff _pending == 0
         self._pending = 0
-        self._finished = asyncio.Event(loop=loop)
-        self._finished.set()
+        # Transient asyncio.Event instance dynamically created
+        # and destroyed by drain()
+        # NOTE invariant: _finished.is_set() iff _pending == 0
+        self._finished = None
 
     def __repr__(self) -> str:
         return '<{} callbacks={} descriptors={}>'.format(
@@ -292,13 +303,14 @@
     def _pending_inc(self) -> None:
         '''Increase the count of pending affairs. Do not use directly.'''
         self._pending += 1
-        self._finished.clear()
+        if self._finished is not None:
+            self._finished.clear()
 
     def _pending_dec(self) -> None:
         '''Decrease the count of pending affairs. Do not use directly.'''
         assert self._pending > 0
         self._pending -= 1
-        if self._pending == 0:
+        if self._pending == 0 and self._finished is not None:
             self._finished.set()
 
     def register(self) -> "virEventAsyncIOImpl":
@@ -312,10 +324,9 @@
 
     def schedule_ff_callback(self, iden: int, opaque: _T) -> None:
         '''Schedule a ff callback from one of the handles or timers'''
-        ensure_future(self._ff_callback(iden, opaque), loop=self.loop)
+        asyncio.ensure_future(self._ff_callback(iden, opaque), loop=self.loop)
 
-    @asyncio.coroutine
-    def _ff_callback(self, iden: int, opaque: _T) -> None:
+    async def _ff_callback(self, iden: int, opaque: _T) -> None:
         '''Directly free the opaque object
 
         This is a coroutine.
@@ -324,15 +335,18 @@
         libvirt.virEventInvokeFreeCallback(opaque)
         self._pending_dec()
 
-    @asyncio.coroutine
-    def drain(self) -> Generator[Any, None, None]:
+    async def drain(self) -> None:
         '''Wait for the implementation to become idle.
 
         This is a coroutine.
         '''
         self.log.debug('drain()')
         if self._pending:
-            yield from self._finished.wait()
+            assert self._finished is None
+            self._finished = asyncio.Event()
+            await self._finished.wait()
+            self._finished = None
+            assert self._pending == 0
         self.log.debug('drain ended')
 
     def is_idle(self) -> bool:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libvirt-python-8.4.0/setup.py 
new/libvirt-python-8.5.0/setup.py
--- old/libvirt-python-8.4.0/setup.py   2022-05-13 13:28:11.000000000 +0200
+++ new/libvirt-python-8.5.0/setup.py   2022-06-25 06:38:30.000000000 +0200
@@ -312,8 +312,17 @@
         pytest = self.find_pytest_path()
         subprocess.check_call([pytest])
 
-
 class my_clean(Command):
+    user_options = [
+        ('all', None, 'unused, compatibility with distutils')
+    ]
+
+    def initialize_options(self):
+        self.all = False
+
+    def finalize_options(self):
+        pass
+
     def run(self):
         if os.path.exists("build"):
             shutil.rmtree("build", ignore_errors=True)
@@ -326,7 +335,7 @@
 _c_modules, _py_modules = get_module_lists()
 
 setup(name = 'libvirt-python',
-      version = '8.4.0',
+      version = '8.5.0',
       url = 'http://www.libvirt.org',
       maintainer = 'Libvirt Maintainers',
       maintainer_email = 'libvir-l...@redhat.com',
@@ -359,5 +368,7 @@
           "Programming Language :: Python :: 3.6",
           "Programming Language :: Python :: 3.7",
           "Programming Language :: Python :: 3.8",
+          "Programming Language :: Python :: 3.9",
+          "Programming Language :: Python :: 3.10",
       ]
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libvirt-python-8.4.0/tests/eventmock.py 
new/libvirt-python-8.5.0/tests/eventmock.py
--- old/libvirt-python-8.4.0/tests/eventmock.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/libvirt-python-8.5.0/tests/eventmock.py 2022-06-25 06:38:30.000000000 
+0200
@@ -0,0 +1,82 @@
+
+import libvirt
+import libvirtmod
+
+_add_handle_impl = None
+_update_handle_impl = None
+_remove_handle_impl = None
+
+_add_timeout_impl = None
+_update_timeout_impl = None
+_remove_timeout_impl = None
+
+_registered = False
+
+def _add_handle(fd: int, event: int, cb: libvirt._EventCB, opaque: libvirt._T) 
-> int:
+    global _add_handle_impl
+    assert _add_handle_impl != None
+    return _add_handle_impl(fd, event, cb, opaque)
+
+def _update_handle(watch: int, event: int) -> None:
+    global _update_handle_impl
+    assert _update_handle_impl != None
+    _update_handle_impl(watch, event)
+
+def _remove_handle(watch: int) -> int:
+    global _remove_handle_impl
+    assert _remove_handle_impl != None
+    return _remove_handle_impl(watch)
+
+def _add_timeout(timeout: int, cb: libvirt._TimerCB, opaque: libvirt._T) -> 
int:
+    global _add_timeout_impl
+    assert _add_timeout_impl != None
+    return _add_timeout_impl(timeout, cb, opaque)
+
+def _update_timeout(timer: int, timeout: int) -> None:
+    global _update_timeout_impl
+    assert _update_timeout_impl != None
+    _update_timeout_impl(timer, timeout)
+
+def _remove_timeout(timer: int) -> int:
+    global _remove_timeout_impl
+    assert _remove_timeout_impl != None
+    return _remove_timeout_impl(timer)
+
+# libvirt.virEventRegisterImpl() is a one time call per process
+# This method is intended to be used with mock patching, so that
+# tests can get the appearance of being able to call
+# virEventRegisterImpl many times.
+#
+# Note, this relies on the tests closing all connection objects
+# and not leaving any handles/timers pending when they stop
+# running their event loop impl.
+
+def virEventRegisterImplMock(add_handle_impl,
+                             update_handle_impl,
+                             remove_handle_impl,
+                             add_timeout_impl,
+                             update_timeout_impl,
+                             remove_timeout_impl):
+    global _add_handle_impl
+    global _update_handle_impl
+    global _remove_handle_impl
+    global _add_timeout_impl
+    global _update_timeout_impl
+    global _remove_timeout_impl
+
+    _add_handle_impl = add_handle_impl
+    _update_handle_impl = update_handle_impl
+    _remove_handle_impl = remove_handle_impl
+    _add_timeout_impl = add_timeout_impl
+    _update_timeout_impl = update_timeout_impl
+    _remove_timeout_impl = remove_timeout_impl
+
+    global _registered
+    if not _registered:
+        libvirtmod.virEventRegisterImpl(_add_handle,
+                                        _update_handle,
+                                        _remove_timeout,
+                                        _add_timeout,
+                                        _update_timeout,
+                                        _remove_timeout)
+        _registered = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libvirt-python-8.4.0/tests/test_aio.py 
new/libvirt-python-8.5.0/tests/test_aio.py
--- old/libvirt-python-8.4.0/tests/test_aio.py  1970-01-01 01:00:00.000000000 
+0100
+++ new/libvirt-python-8.5.0/tests/test_aio.py  2022-06-25 06:38:30.000000000 
+0200
@@ -0,0 +1,156 @@
+import asyncio
+import libvirt
+import libvirtaio
+import sys
+import unittest
+from unittest import mock
+
+import eventmock
+
+
+class TestLibvirtAio(unittest.TestCase):
+    async def _run(self, register):
+        def lifecycleCallback(conn, dom, event, detail, domainChangedEvent):
+            if (event == libvirt.VIR_DOMAIN_EVENT_STOPPED or
+                    event == libvirt.VIR_DOMAIN_EVENT_STARTED):
+                domainChangedEvent.set()
+
+        if register:
+            libvirtEvents = libvirtaio.virEventRegisterAsyncIOImpl()
+        else:
+            libvirtEvents = libvirtaio.getCurrentImpl()
+
+        conn = libvirt.open("test:///default")
+        dom = conn.lookupByName("test")
+
+        eventRegistered = False
+        domainStopped = False
+        try:
+            # Ensure the VM is running.
+            self.assertEqual([libvirt.VIR_DOMAIN_RUNNING, 
libvirt.VIR_DOMAIN_RUNNING_UNKNOWN], dom.state())
+            self.assertTrue(libvirtEvents.is_idle())
+
+            # Register VM start/stopped event handler.
+            domainChangedEvent = asyncio.Event()
+            conn.domainEventRegisterAny(dom, 
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, lifecycleCallback, domainChangedEvent)
+            eventRegistered = True
+
+            self.assertFalse(libvirtEvents.is_idle())
+
+            # Stop the VM.
+            dom.destroy()
+            domainStopped = True
+
+            # Ensure domain stopped event is received.
+            await asyncio.wait_for(domainChangedEvent.wait(), 2)
+            self.assertEqual([libvirt.VIR_DOMAIN_SHUTOFF, 
libvirt.VIR_DOMAIN_SHUTOFF_DESTROYED], dom.state())
+
+            # Start the VM.
+            domainChangedEvent.clear()
+            domainStopped = False
+            dom.create()
+
+            # Ensure domain started event is received.
+            await asyncio.wait_for(domainChangedEvent.wait(), 2)
+            self.assertEqual([libvirt.VIR_DOMAIN_RUNNING, 
libvirt.VIR_DOMAIN_RUNNING_BOOTED], dom.state())
+            self.assertFalse(libvirtEvents.is_idle())
+
+            # Deregister the VM start/stopped event handler.
+            eventRegistered = False
+            
conn.domainEventDeregisterAny(libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE)
+
+            # Wait for event queue to clear.
+            await libvirtEvents.drain()
+
+            # Make sure event queue is cleared.
+            self.assertTrue(libvirtEvents.is_idle())
+
+        finally:
+            if eventRegistered:
+                
conn.domainEventDeregisterAny(libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE)
+
+            if domainStopped:
+                dom.create()
+
+    @mock.patch('libvirt.virEventRegisterImpl',
+                side_effect=eventmock.virEventRegisterImplMock)
+    def testEventsWithManualLoopSetup(self, mock_event_register):
+        # Register libvirt events after starting the asyncio loop.
+        #
+        # Manually create and set the event loop against this
+        # thread.
+        loop = asyncio.new_event_loop()
+        asyncio.set_event_loop(loop)
+
+        loop.run_until_complete(self._run(register=True))
+
+        loop.close()
+        asyncio.set_event_loop(None)
+        mock_event_register.assert_called_once()
+
+    @mock.patch('libvirt.virEventRegisterImpl',
+                side_effect=eventmock.virEventRegisterImplMock)
+    @unittest.skipIf(sys.version_info < (3,7), "test requires Python 3.7+")
+    def testEventsWithAsyncioRun(self, mock_event_register):
+        # Register libvirt events after starting the asyncio loop.
+        #
+        # Use asyncio helper to create and set the event loop
+        # against this thread.
+        asyncio.run(self._run(register=True))
+        mock_event_register.assert_called_once()
+
+    @mock.patch('libvirt.virEventRegisterImpl',
+                side_effect=eventmock.virEventRegisterImplMock)
+    def testEventsPreInitExplicit(self, mock_event_register):
+        # Register libvirt events before starting the asyncio loop.
+        #
+        # Tell virEventRegisterAsyncIOImpl() explicitly what loop
+        # to use before we set a loop for this thread.
+        loop = asyncio.new_event_loop()
+        libvirtaio.virEventRegisterAsyncIOImpl(loop)
+        asyncio.set_event_loop(loop)
+
+        loop.run_until_complete(self._run(register=False))
+
+        loop.close()
+        asyncio.set_event_loop(None)
+        mock_event_register.assert_called_once()
+
+    @mock.patch('libvirt.virEventRegisterImpl',
+                side_effect=eventmock.virEventRegisterImplMock)
+    @unittest.skipIf(sys.version_info >= (3,10), "test incompatible with 3.10")
+    def testEventsPreInitImplicit(self, mock_event_register):
+        # Register libvirt events before starting the asyncio loop.
+        #
+        # Allow virEventRegisterAsyncIOImpl() to implicitly find the
+        # loop we set for this thread.
+        loop = asyncio.new_event_loop()
+        asyncio.set_event_loop(loop)
+        libvirtaio.virEventRegisterAsyncIOImpl()
+
+        loop.run_until_complete(self._run(register=False))
+
+        loop.close()
+        asyncio.set_event_loop(None)
+        mock_event_register.assert_called_once()
+
+    @mock.patch('libvirt.virEventRegisterImpl',
+                side_effect=eventmock.virEventRegisterImplMock)
+    @unittest.skipIf(sys.version_info >= (3,10), "test incompatible with 3.10")
+    def testEventsImplicitLoopInit(self, mock_event_register):
+        # Register libvirt events before starting the asyncio loop.
+        #
+        # Let virEventRegisterAsyncIOImpl() auto-create a default
+        # event loop, which we then register against this thread.
+        #
+        # Historically this often worked if called from the main thead,
+        # but since Python 3.10 this triggers a deprecation warning,
+        # which will turn into a RuntimeError in a later release.
+        libvirtaio.virEventRegisterAsyncIOImpl()
+        loop = asyncio.get_event_loop()
+
+        loop.run_until_complete(self._run(register=False))
+
+        loop.close()
+        asyncio.set_event_loop(None)
+        mock_event_register.assert_called_once()

Reply via email to