Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-zeroconf for openSUSE:Factory 
checked in at 2022-06-07 11:57:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-zeroconf (Old)
 and      /work/SRC/openSUSE:Factory/.python-zeroconf.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-zeroconf"

Tue Jun  7 11:57:26 2022 rev:31 rq:980756 version:0.38.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-zeroconf/python-zeroconf.changes  
2022-02-05 23:23:42.443709574 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-zeroconf.new.1548/python-zeroconf.changes    
    2022-06-07 11:57:26.940152432 +0200
@@ -1,0 +2,9 @@
+Sat Jun  4 12:14:38 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 0.38.6:
+  * Performance improvements for fetching ServiceInfo
+  * Fix ServiceBrowsers not getting ServiceStateChange.Removed callbacks on 
PTR record expire
+  * Fix missing minimum version of python 3.7
+  * Fix IP Address updates when hostname is uppercase
+
+-------------------------------------------------------------------

Old:
----
  python-zeroconf-0.38.3.obscpio

New:
----
  python-zeroconf-0.38.6.obscpio

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

Other differences:
------------------
++++++ python-zeroconf.spec ++++++
--- /var/tmp/diff_new_pack.FTMIHM/_old  2022-06-07 11:57:27.652153007 +0200
+++ /var/tmp/diff_new_pack.FTMIHM/_new  2022-06-07 11:57:27.656153010 +0200
@@ -20,7 +20,7 @@
 %define skip_python2 1
 %define skip_python36 1
 Name:           python-zeroconf
-Version:        0.38.3
+Version:        0.38.6
 Release:        0
 Summary:        Pure Python Multicast DNS Service Discovery Library 
(Bonjour/Avahi compatible)
 License:        LGPL-2.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.FTMIHM/_old  2022-06-07 11:57:27.692153039 +0200
+++ /var/tmp/diff_new_pack.FTMIHM/_new  2022-06-07 11:57:27.696153042 +0200
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="disabled">
     <param name="url">https://github.com/jstasiak/python-zeroconf</param>
     <param name="scm">git</param>
-    <param name="revision">0.38.3</param>
+    <param name="revision">0.38.6</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">(.*)</param>
   </service>

++++++ python-zeroconf-0.38.3.obscpio -> python-zeroconf-0.38.6.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/.github/workflows/ci.yml 
new/python-zeroconf-0.38.6/.github/workflows/ci.yml
--- old/python-zeroconf-0.38.3/.github/workflows/ci.yml 2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/.github/workflows/ci.yml 2022-05-06 
21:11:56.000000000 +0200
@@ -27,7 +27,7 @@
       - name: Set up Python ${{ matrix.python-version }}
         uses: actions/setup-python@v2
         with:
-          python-version: '3.x'
+          python-version: ${{ matrix.python-version }}
           architecture: 'x64'
       - uses: actions/cache@v2
         id: cache
@@ -43,22 +43,22 @@
           ${{ matrix.venvcmd }}
           pip install --upgrade -r requirements-dev.txt 
pytest-github-actions-annotate-failures
       - name: Validate readme
-        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy3' }}
+        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy-3.7' }}
         run: |
           ${{ matrix.venvcmd }}
           python -m readme_renderer README.rst -o -
       - name: Run flake8
-        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy3' }}
+        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy-3.7' }}
         run: |
           ${{ matrix.venvcmd }}
           make flake8
       - name: Run mypy
-        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy3' }}
+        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy-3.7' }}
         run: |
           ${{ matrix.venvcmd }}
           make mypy
       - name: Run black_check
-        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy3' }}
+        if: ${{ runner.os == 'Linux' && matrix.python-version != 'pypy-3.7' }}
         run: |
           ${{ matrix.venvcmd }}
           make black_check
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/Makefile 
new/python-zeroconf-0.38.6/Makefile
--- old/python-zeroconf-0.38.3/Makefile 2022-02-01 00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/Makefile 2022-05-06 21:11:56.000000000 +0200
@@ -1,4 +1,4 @@
-# version: 1.1
+# version: 1.2
 
 .PHONY: all virtualenv
 MAX_LINE_LENGTH=110
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/README.rst 
new/python-zeroconf-0.38.6/README.rst
--- old/python-zeroconf-0.38.3/README.rst       2022-02-01 00:23:46.000000000 
+0100
+++ new/python-zeroconf-0.38.6/README.rst       2022-05-06 21:11:56.000000000 
+0200
@@ -99,17 +99,20 @@
 
 .. code-block:: python
 
-    from zeroconf import ServiceBrowser, Zeroconf
+    from zeroconf import ServiceBrowser, ServiceListener, Zeroconf
     
     
-    class MyListener:
+    class MyListener(ServiceListener):
     
-        def remove_service(self, zeroconf, type, name):
-            print("Service %s removed" % (name,))
+        def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
+            print(f"Service {name} updated")
     
-        def add_service(self, zeroconf, type, name):
-            info = zeroconf.get_service_info(type, name)
-            print("Service %s added, service info: %s" % (name, info))
+        def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
+            print(f"Service {name} removed")
+    
+        def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
+            info = zc.get_service_info(type_, name)
+            print(f"Service {name} added, service info: {info}")
     
     
     zeroconf = Zeroconf()
@@ -138,6 +141,33 @@
 Changelog
 =========
 
+
+0.38.6
+======
+
+* Performance improvements for fetching ServiceInfo (#1068) @bdraco
+
+
+0.38.5
+======
+
+* Fix ServiceBrowsers not getting ServiceStateChange.Removed callbacks on PTR 
record expire (#1064) @bdraco
+
+  ServiceBrowsers were only getting a `ServiceStateChange.Removed` callback
+  when the record was sent with a TTL of 0. ServiceBrowsers now correctly
+  get a `ServiceStateChange.Removed` callback when the record expires as well.
+* Fix missing minimum version of python 3.7 (#1060) @stevencrader
+
+
+0.38.4
+======
+
+* Fix IP Address updates when hostname is uppercase (#1057) @bdraco
+
+  ServiceBrowsers would not callback updates when the ip address changed
+  if the hostname contained uppercase characters
+
+
 0.38.3
 ======
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/requirements-dev.txt 
new/python-zeroconf-0.38.6/requirements-dev.txt
--- old/python-zeroconf-0.38.3/requirements-dev.txt     2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/requirements-dev.txt     2022-05-06 
21:11:56.000000000 +0200
@@ -7,8 +7,7 @@
 flake8-import-order
 ifaddr
 mypy;implementation_name=="cpython"
-# 0.11.0 breaks things https://github.com/PyCQA/pep8-naming/issues/152
-pep8-naming!=0.6.0,!=0.11.0
+pep8-naming>=0.12.0
 pylint
 pytest
 pytest-asyncio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/setup.cfg 
new/python-zeroconf-0.38.6/setup.cfg
--- old/python-zeroconf-0.38.3/setup.cfg        2022-02-01 00:23:46.000000000 
+0100
+++ new/python-zeroconf-0.38.6/setup.cfg        2022-05-06 21:11:56.000000000 
+0200
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.38.3
+current_version = 0.38.6
 commit = True
 tag = True
 tag_name = {new_version}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/setup.py 
new/python-zeroconf-0.38.6/setup.py
--- old/python-zeroconf-0.38.3/setup.py 2022-02-01 00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/setup.py 2022-05-06 21:11:56.000000000 +0200
@@ -27,6 +27,7 @@
     platforms=['unix', 'linux', 'osx'],
     license='LGPL',
     zip_safe=False,
+    python_requires='>=3.7',
     classifiers=[
         'Development Status :: 3 - Alpha',
         'Intended Audience :: Developers',
@@ -36,10 +37,10 @@
         'Operating System :: POSIX :: Linux',
         'Operating System :: MacOS :: MacOS X',
         'Topic :: Software Development :: Libraries',
-        'Programming Language :: Python :: 3.5',
-        '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',
         'Programming Language :: Python :: Implementation :: CPython',
         'Programming Language :: Python :: Implementation :: PyPy',
     ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-zeroconf-0.38.3/tests/services/test_browser.py 
new/python-zeroconf-0.38.6/tests/services/test_browser.py
--- old/python-zeroconf-0.38.3/tests/services/test_browser.py   2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/tests/services/test_browser.py   2022-05-06 
21:11:56.000000000 +0200
@@ -3,7 +3,6 @@
 
 """ Unit tests for zeroconf._services.browser. """
 
-import asyncio
 import logging
 import socket
 import time
@@ -17,7 +16,7 @@
 import zeroconf as r
 from zeroconf import DNSPointer, DNSQuestion, const, current_time_millis, 
millis_to_seconds
 import zeroconf._services.browser as _services_browser
-from zeroconf import Zeroconf
+from zeroconf import _core, _handlers, Zeroconf
 from zeroconf._services import ServiceStateChange
 from zeroconf._services.browser import ServiceBrowser
 from zeroconf._services.info import ServiceInfo
@@ -1099,4 +1098,83 @@
     ]
     browser.cancel()
 
+    zc.close()
+
+
[email protected](_handlers, '_DNS_PTR_MIN_TTL', 1)
[email protected](_core, "_CACHE_CLEANUP_INTERVAL", 10)
+def test_service_browser_expire_callbacks():
+    """Test that the ServiceBrowser matching does not match partial names."""
+    # instantiate a zeroconf instance
+    zc = Zeroconf(interfaces=['127.0.0.1'])
+    # start a browser
+    type_ = "_old._tcp.local."
+    registration_name = "uniquezip323.%s" % type_
+    callbacks = []
+
+    class MyServiceListener(r.ServiceListener):
+        def add_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            if name == registration_name:
+                callbacks.append(("add", type_, name))
+
+        def remove_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            if name == registration_name:
+                callbacks.append(("remove", type_, name))
+
+        def update_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            if name == registration_name:
+                callbacks.append(("update", type_, name))
+
+    listener = MyServiceListener()
+
+    browser = r.ServiceBrowser(zc, type_, None, listener)
+
+    desc = {'path': '/~paul2/'}
+    address_parsed = "10.0.1.3"
+    address = socket.inet_aton(address_parsed)
+    info = ServiceInfo(
+        type_,
+        registration_name,
+        80,
+        0,
+        0,
+        desc,
+        "newname-2.local.",
+        host_ttl=1,
+        other_ttl=1,
+        addresses=[address],
+    )
+
+    def mock_incoming_msg(records) -> r.DNSIncoming:
+        generated = r.DNSOutgoing(const._FLAGS_QR_RESPONSE)
+        for record in records:
+            generated.add_answer_at_time(record, 0)
+        return r.DNSIncoming(generated.packets()[0])
+
+    _inject_response(
+        zc,
+        mock_incoming_msg([info.dns_pointer(), info.dns_service(), 
info.dns_text(), *info.dns_addresses()]),
+    )
+    time.sleep(0.3)
+    info.port = 400
+    _inject_response(
+        zc,
+        mock_incoming_msg([info.dns_service()]),
+    )
+
+    assert callbacks == [
+        ('add', type_, registration_name),
+        ('update', type_, registration_name),
+    ]
+    time.sleep(1.1)
+    assert callbacks == [
+        ('add', type_, registration_name),
+        ('update', type_, registration_name),
+        ('remove', type_, registration_name),
+    ]
+    browser.cancel()
+
     zc.close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/tests/services/test_info.py 
new/python-zeroconf-0.38.6/tests/services/test_info.py
--- old/python-zeroconf-0.38.3/tests/services/test_info.py      2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/tests/services/test_info.py      2022-05-06 
21:11:56.000000000 +0200
@@ -3,6 +3,7 @@
 
 """ Unit tests for zeroconf._services.info. """
 
+import asyncio
 import logging
 import socket
 import threading
@@ -16,6 +17,7 @@
 
 import zeroconf as r
 from zeroconf import DNSAddress, const
+from zeroconf._services import types
 from zeroconf._services.info import ServiceInfo
 from zeroconf.asyncio import AsyncZeroconf
 
@@ -798,3 +800,68 @@
     await aiozc.async_close()
 
     assert request_count == 4
+
+
[email protected]
+async def test_release_wait_when_new_recorded_added():
+    """Test that async_request returns as soon as new matching records are 
added to the cache."""
+    type_ = "_http._tcp.local."
+    registration_name = "multiarec.%s" % type_
+    desc = {'path': '/~paulsm/'}
+    aiozc = AsyncZeroconf(interfaces=['127.0.0.1'])
+    host = "multahost.local."
+
+    # New kwarg way
+    info = ServiceInfo(type_, registration_name, 80, 0, 0, desc, host)
+    task = asyncio.create_task(info.async_request(aiozc.zeroconf, timeout=200))
+    generated = r.DNSOutgoing(const._FLAGS_QR_RESPONSE)
+    generated.add_answer_at_time(
+        r.DNSNsec(
+            registration_name,
+            const._TYPE_NSEC,
+            const._CLASS_IN | const._CLASS_UNIQUE,
+            const._DNS_OTHER_TTL,
+            registration_name,
+            [const._TYPE_AAAA],
+        ),
+        0,
+    )
+    generated.add_answer_at_time(
+        r.DNSService(
+            registration_name,
+            const._TYPE_SRV,
+            const._CLASS_IN | const._CLASS_UNIQUE,
+            10000,
+            0,
+            0,
+            80,
+            host,
+        ),
+        0,
+    )
+    generated.add_answer_at_time(
+        r.DNSAddress(
+            host,
+            const._TYPE_A,
+            const._CLASS_IN,
+            10000,
+            b'\x7f\x00\x00\x01',
+        ),
+        0,
+    )
+    generated.add_answer_at_time(
+        r.DNSText(
+            registration_name,
+            const._TYPE_TXT,
+            const._CLASS_IN | const._CLASS_UNIQUE,
+            10000,
+            b'\x04ff=0\x04ci=2\x04sf=0\x0bsh=6fLM5A==',
+        ),
+        0,
+    )
+    await aiozc.zeroconf.async_wait_for_start()
+    await asyncio.sleep(0)
+    aiozc.zeroconf.handle_response(r.DNSIncoming(generated.packets()[0]))
+    assert await asyncio.wait_for(task, timeout=2)
+    assert info.addresses == [b'\x7f\x00\x00\x01']
+    await aiozc.async_close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/tests/test_asyncio.py 
new/python-zeroconf-0.38.6/tests/test_asyncio.py
--- old/python-zeroconf-0.38.3/tests/test_asyncio.py    2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/tests/test_asyncio.py    2022-05-06 
21:11:56.000000000 +0200
@@ -1132,3 +1132,42 @@
     assert outgoing.questions == [question]
     assert outgoing.id == query.id
     await aiozc.async_close()
+
+
[email protected]
+async def test_update_with_uppercase_names(run_isolated):
+    """Test an ip update from a shelly which uses uppercase names."""
+    aiozc = AsyncZeroconf(interfaces=['127.0.0.1'])
+    await aiozc.zeroconf.async_wait_for_start()
+
+    callbacks = []
+
+    class MyServiceListener(ServiceListener):
+        def add_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            callbacks.append(("add", type_, name))
+
+        def remove_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            callbacks.append(("remove", type_, name))
+
+        def update_service(self, zc, type_, name) -> None:
+            nonlocal callbacks
+            callbacks.append(("update", type_, name))
+
+    listener = MyServiceListener()
+    browser = AsyncServiceBrowser(aiozc.zeroconf, "_http._tcp.local.", None, 
listener)
+    protocol = aiozc.zeroconf.engine.protocols[0]
+
+    packet = 
b'\x00\x00\x84\x80\x00\x00\x00\n\x00\x00\x00\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x14\x07_shelly\x04_tcp\x05local\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x12\x05_http\x04_tcp\x05local\x00\x07_shelly\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00.\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\'\x00\x00\x00\x00\x00P\x19ShellyPro4PM-94B97EC07650\x05local\x00\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x00\x10\x80\x01\x00\x00\x00x\x00"\napp=Pro4PM\x10ver=0.10.0-beta5\x05gen=2\x05_http\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00,\x19ShellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x19ShellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\'\x00\x00\x00\x00\x00P\x19ShellyPro4PM-94B97EC07650\x05local\x00\x19Sh
 
ellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x00\x10\x80\x01\x00\x00\x00x\x00\x06\x05gen=2\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\xbc=\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00/\x80\x01\x00\x00\x00x\x00$\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00\x01@'
+    protocol.datagram_received(packet, ('127.0.0.1', 6503))
+    await asyncio.sleep(0)
+    packet = 
b'\x00\x00\x84\x80\x00\x00\x00\n\x00\x00\x00\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x14\x07_shelly\x04_tcp\x05local\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x12\x05_http\x04_tcp\x05local\x00\x07_shelly\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00.\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\'\x00\x00\x00\x00\x00P\x19ShellyPro4PM-94B97EC07650\x05local\x00\x19shellypro4pm-94b97ec07650\x07_shelly\x04_tcp\x05local\x00\x00\x10\x80\x01\x00\x00\x00x\x00"\napp=Pro4PM\x10ver=0.10.0-beta5\x05gen=2\x05_http\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00,\x19ShellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x19ShellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\'\x00\x00\x00\x00\x00P\x19ShellyPro4PM-94B97EC07650\x05local\x00\x19Sh
 
ellyPro4PM-94B97EC07650\x05_http\x04_tcp\x05local\x00\x00\x10\x80\x01\x00\x00\x00x\x00\x06\x05gen=2\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\xbcA\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00/\x80\x01\x00\x00\x00x\x00$\x19ShellyPro4PM-94B97EC07650\x05local\x00\x00\x01@'
+    protocol.datagram_received(packet, ('127.0.0.1', 6503))
+
+    await aiozc.async_close()
+
+    assert callbacks == [
+        ('add', '_http._tcp.local.', 
'ShellyPro4PM-94B97EC07650._http._tcp.local.'),
+        ('update', '_http._tcp.local.', 
'ShellyPro4PM-94B97EC07650._http._tcp.local.'),
+    ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/tests/test_core.py 
new/python-zeroconf-0.38.6/tests/test_core.py
--- old/python-zeroconf-0.38.3/tests/test_core.py       2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/tests/test_core.py       2022-05-06 
21:11:56.000000000 +0200
@@ -18,7 +18,7 @@
 from unittest.mock import patch
 
 import zeroconf as r
-from zeroconf import _core, const, Zeroconf, current_time_millis
+from zeroconf import _core, const, Zeroconf, current_time_millis, 
NotRunningException
 from zeroconf.asyncio import AsyncZeroconf
 from zeroconf._protocol import outgoing
 
@@ -798,3 +798,15 @@
 
     zc.close()
     bgthread.join()
+
+
[email protected]
[email protected](sys.version_info[:3][1] < 8, 'Requires Python 3.8 or later to 
patch _async_setup')
+@patch("zeroconf._core._STARTUP_TIMEOUT", 0)
+@patch("zeroconf._core.AsyncEngine._async_setup")
+async def test_event_loop_blocked(mock_start):
+    """Test we raise NotRunningException when waiting for startup that times 
out."""
+    aiozc = AsyncZeroconf(interfaces=['127.0.0.1'])
+    with pytest.raises(NotRunningException):
+        await aiozc.zeroconf.async_wait_for_start()
+    assert aiozc.zeroconf.started is False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/tests/test_dns.py 
new/python-zeroconf-0.38.6/tests/test_dns.py
--- old/python-zeroconf-0.38.3/tests/test_dns.py        2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/tests/test_dns.py        2022-05-06 
21:11:56.000000000 +0200
@@ -334,6 +334,17 @@
     assert len(record_set) == 4
 
 
+def test_dns_service_server_key():
+    """Test DNSService server_key is lowercase."""
+    srv1 = r.DNSService(
+        'X._tcp._http.local.', const._TYPE_SRV, const._CLASS_IN, 
const._DNS_HOST_TTL, 0, 0, 80, 'X.local.'
+    )
+    assert srv1.name == 'X._tcp._http.local.'
+    assert srv1.key == 'x._tcp._http.local.'
+    assert srv1.server == 'X.local.'
+    assert srv1.server_key == 'x.local.'
+
+
 def test_dns_nsec_record_hashablity():
     """Test DNSNsec are hashable."""
     nsec1 = r.DNSNsec(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/__init__.py 
new/python-zeroconf-0.38.6/zeroconf/__init__.py
--- old/python-zeroconf-0.38.3/zeroconf/__init__.py     2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/__init__.py     2022-05-06 
21:11:56.000000000 +0200
@@ -79,7 +79,7 @@
 
 __author__ = 'Paul Scott-Murphy, William McBrine'
 __maintainer__ = 'Jakub Stasiak <[email protected]>'
-__version__ = '0.38.3'
+__version__ = '0.38.6'
 __license__ = 'LGPL'
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_cache.py 
new/python-zeroconf-0.38.6/zeroconf/_cache.py
--- old/python-zeroconf-0.38.3/zeroconf/_cache.py       2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_cache.py       2022-05-06 
21:11:56.000000000 +0200
@@ -27,6 +27,7 @@
     DNSAddress,
     DNSEntry,
     DNSHinfo,
+    DNSNsec,
     DNSPointer,
     DNSRecord,
     DNSService,
@@ -61,9 +62,11 @@
     # Functions prefixed with async_ are NOT threadsafe and must
     # be run in the event loop.
 
-    def _async_add(self, entry: DNSRecord) -> None:
+    def _async_add(self, entry: DNSRecord) -> bool:
         """Adds an entry.
 
+        Returns true if the entry was not already in the cache.
+
         This function must be run in from event loop.
         """
         # Previously storage of records was implemented as a list
@@ -72,17 +75,25 @@
         # replaces any existing records that are __eq__ to each other which
         # removes the risk that accessing the cache from the wrong
         # direction would return the old incorrect entry.
-        self.cache.setdefault(entry.key, {})[entry] = entry
+        store = self.cache.setdefault(entry.key, {})
+        new = entry not in store and not isinstance(entry, DNSNsec)
+        store[entry] = entry
         if isinstance(entry, DNSService):
-            self.service_cache.setdefault(entry.server, {})[entry] = entry
+            self.service_cache.setdefault(entry.server_key, {})[entry] = entry
+        return new
 
-    def async_add_records(self, entries: Iterable[DNSRecord]) -> None:
+    def async_add_records(self, entries: Iterable[DNSRecord]) -> bool:
         """Add multiple records.
 
+        Returns true if any of the records were not in the cache.
+
         This function must be run in from event loop.
         """
+        new = False
         for entry in entries:
-            self._async_add(entry)
+            if self._async_add(entry):
+                new = True
+        return new
 
     def _async_remove(self, entry: DNSRecord) -> None:
         """Removes an entry.
@@ -90,7 +101,7 @@
         This function must be run in from event loop.
         """
         if isinstance(entry, DNSService):
-            _remove_key(self.service_cache, entry.server, entry)
+            _remove_key(self.service_cache, entry.server_key, entry)
         _remove_key(self.cache, entry.key, entry)
 
     def async_remove_records(self, entries: Iterable[DNSRecord]) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_core.py 
new/python-zeroconf-0.38.6/zeroconf/_core.py
--- old/python-zeroconf-0.38.3/zeroconf/_core.py        2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_core.py        2022-05-06 
21:11:56.000000000 +0200
@@ -167,9 +167,9 @@
         now = current_time_millis()
         self.zc.question_history.async_expire(now)
         self.zc.record_manager.async_updates(
-            now, [RecordUpdate(record, None) for record in 
self.zc.cache.async_expire(now)]
+            now, [RecordUpdate(record, record) for record in 
self.zc.cache.async_expire(now)]
         )
-        self.zc.record_manager.async_updates_complete()
+        self.zc.record_manager.async_updates_complete(False)
         assert self.loop is not None
         self._cleanup_timer = self.loop.call_later(
             millis_to_seconds(_CACHE_CLEANUP_INTERVAL), 
self._async_cache_cleanup
@@ -184,6 +184,8 @@
 
     def _async_shutdown(self) -> None:
         """Shutdown transports and sockets."""
+        assert self.running_event is not None
+        self.running_event.clear()
         for transport in itertools.chain(self.senders, self.readers):
             transport.close()
 
@@ -466,6 +468,11 @@
 
         self.start()
 
+    @property
+    def started(self) -> bool:
+        """Check if the instance has started."""
+        return bool(not self.done and self.engine.running_event and 
self.engine.running_event.is_set())
+
     def start(self) -> None:
         """Start Zeroconf."""
         self.loop = get_running_loop()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_dns.py 
new/python-zeroconf-0.38.6/zeroconf/_dns.py
--- old/python-zeroconf-0.38.3/zeroconf/_dns.py 2022-02-01 00:23:46.000000000 
+0100
+++ new/python-zeroconf-0.38.6/zeroconf/_dns.py 2022-05-06 21:11:56.000000000 
+0200
@@ -401,7 +401,7 @@
 
     """A DNS service record"""
 
-    __slots__ = ('_hash', 'priority', 'weight', 'port', 'server')
+    __slots__ = ('_hash', 'priority', 'weight', 'port', 'server', 'server_key')
 
     def __init__(
         self,
@@ -420,6 +420,7 @@
         self.weight = weight
         self.port = port
         self.server = server
+        self.server_key = server.lower()
         self._hash = hash((self.key, type_, self.class_, priority, weight, 
port, server))
 
     def write(self, out: 'DNSOutgoing') -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_handlers.py 
new/python-zeroconf-0.38.6/zeroconf/_handlers.py
--- old/python-zeroconf-0.38.3/zeroconf/_handlers.py    2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_handlers.py    2022-05-06 
21:11:56.000000000 +0200
@@ -391,7 +391,7 @@
         for listener in self.listeners:
             listener.async_update_records(self.zc, now, records)
 
-    def async_updates_complete(self) -> None:
+    def async_updates_complete(self, notify: bool) -> None:
         """Used to notify listeners of new information that has updated
         a record.
 
@@ -401,7 +401,8 @@
         """
         for listener in self.listeners:
             listener.async_update_records_complete()
-        self.zc.async_notify_all()
+        if notify:
+            self.zc.async_notify_all()
 
     def async_updates_from_response(self, msg: DNSIncoming) -> None:
         """Deal with incoming response packets.  All answers
@@ -459,15 +460,16 @@
         # zc.get_service_info will see the cached value
         # but ONLY after all the record updates have been
         # processsed.
+        new = False
         if other_adds or address_adds:
-            self.cache.async_add_records(itertools.chain(address_adds, 
other_adds))
+            new = self.cache.async_add_records(itertools.chain(address_adds, 
other_adds))
         # Removes are processed last since
         # ServiceInfo could generate an un-needed query
         # because the data was not yet populated.
         if removes:
             self.cache.async_remove_records(removes)
         if updates:
-            self.async_updates_complete()
+            self.async_updates_complete(new)
 
     def _async_mark_unique_cached_records_older_than_1s_to_expire(
         self, unique_types: Set[Tuple[str, int, int]], answers: 
Iterable[DNSRecord], now: float
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_logger.py 
new/python-zeroconf-0.38.6/zeroconf/_logger.py
--- old/python-zeroconf-0.38.3/zeroconf/_logger.py      2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_logger.py      2022-05-06 
21:11:56.000000000 +0200
@@ -1,4 +1,5 @@
 """ Multicast DNS Service Discovery for Python, v0.14-wmcbrine
+        )
     Copyright 2003 Paul Scott-Murphy, 2014 William McBrine
 
     This module provides a framework for the use of DNS Service Discovery
@@ -56,9 +57,6 @@
         log_exc_info = False
         exc_info = sys.exc_info()
         exc_str = str(exc_info[1])
-        import pprint
-
-        pprint.pprint(cls._seen_logs)
         if exc_str not in cls._seen_logs:
             # log the trace only on the first time
             cls._seen_logs[exc_str] = exc_info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_services/browser.py 
new/python-zeroconf-0.38.6/zeroconf/_services/browser.py
--- old/python-zeroconf-0.38.3/zeroconf/_services/browser.py    2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_services/browser.py    2022-05-06 
21:11:56.000000000 +0200
@@ -441,7 +441,8 @@
 
     async def _async_start_query_sender(self) -> None:
         """Start scheduling queries."""
-        await self.zc.async_wait_for_start()
+        if not self.zc.started:
+            await self.zc.async_wait_for_start()
         self._async_send_ready_queries_schedule_next()
 
     def _cancel_send_timer(self) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.38.3/zeroconf/_services/info.py 
new/python-zeroconf-0.38.6/zeroconf/_services/info.py
--- old/python-zeroconf-0.38.3/zeroconf/_services/info.py       2022-02-01 
00:23:46.000000000 +0100
+++ new/python-zeroconf-0.38.6/zeroconf/_services/info.py       2022-05-06 
21:11:56.000000000 +0200
@@ -181,9 +181,9 @@
             except ValueError:
                 raise TypeError(
                     "Addresses must either be IPv4 or IPv6 strings, bytes, or 
integers;"
-                    f" got {address}. Hint: convert string addresses with 
socket.inet_pton"  # type: ignore
+                    f" got {address!r}. Hint: convert string addresses with 
socket.inet_pton"
                 )
-            if addr.version == 4:
+            if isinstance(addr, ipaddress.IPv4Address):
                 self._ipv4_addresses.append(addr)
             else:
                 self._ipv6_addresses.append(addr)
@@ -333,7 +333,7 @@
             except ValueError as ex:
                 log.warning("Encountered invalid address while processing %s: 
%s", record, ex)
                 return
-            if ip_addr.version == 4:
+            if isinstance(ip_addr, ipaddress.IPv4Address):
                 if ip_addr not in self._ipv4_addresses:
                     self._ipv4_addresses.insert(0, ip_addr)
                 return
@@ -467,6 +467,8 @@
         """Returns true if the service could be discovered on the
         network, and updates this object with details discovered.
         """
+        if not zc.started:
+            await zc.async_wait_for_start()
         if self.load_from_cache(zc):
             return True
 
@@ -475,7 +477,6 @@
         delay = _LISTENER_TIME
         next_ = now
         last = now + timeout
-        await zc.async_wait_for_start()
         try:
             zc.async_add_listener(self, None)
             while not self._is_complete:

++++++ python-zeroconf.obsinfo ++++++
--- /var/tmp/diff_new_pack.FTMIHM/_old  2022-06-07 11:57:27.832153152 +0200
+++ /var/tmp/diff_new_pack.FTMIHM/_new  2022-06-07 11:57:27.836153156 +0200
@@ -1,5 +1,5 @@
 name: python-zeroconf
-version: 0.38.3
-mtime: 1643671426
-commit: e42549cb70796d0577c97be96a09bca0056a5755
+version: 0.38.6
+mtime: 1651864316
+commit: 1aa7842ae0f914c10465ae977551698046406d55
 

Reply via email to