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