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 2021-10-27 22:21:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-zeroconf (Old)
 and      /work/SRC/openSUSE:Factory/.python-zeroconf.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-zeroconf"

Wed Oct 27 22:21:03 2021 rev:26 rq:927595 version:0.36.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-zeroconf/python-zeroconf.changes  
2021-10-19 23:04:37.857294842 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-zeroconf.new.1890/python-zeroconf.changes    
    2021-10-27 22:21:15.771200419 +0200
@@ -1,0 +2,6 @@
+Tue Oct 26 20:31:03 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.36.9:
+  * Ensure ServiceInfo orders newest addresses first 
+
+-------------------------------------------------------------------

Old:
----
  python-zeroconf-0.36.8.obscpio

New:
----
  python-zeroconf-0.36.9.obscpio

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

Other differences:
------------------
++++++ python-zeroconf.spec ++++++
--- /var/tmp/diff_new_pack.SWfphL/_old  2021-10-27 22:21:16.335200708 +0200
+++ /var/tmp/diff_new_pack.SWfphL/_new  2021-10-27 22:21:16.339200710 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-zeroconf
-Version:        0.36.8
+Version:        0.36.9
 Release:        0
 Summary:        Pure Python Multicast DNS Service Discovery Library 
(Bonjour/Avahi compatible)
 License:        LGPL-2.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.SWfphL/_old  2021-10-27 22:21:16.367200724 +0200
+++ /var/tmp/diff_new_pack.SWfphL/_new  2021-10-27 22:21:16.367200724 +0200
@@ -2,8 +2,8 @@
   <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.36.8</param>
-    <param name="version">0.36.8</param>
+    <param name="revision">0.36.9</param>
+    <param name="version">0.36.9</param>
   </service>
   <service name="set_version" mode="disabled"/>
   <service mode="buildtime" name="tar" />

++++++ python-zeroconf-0.36.8.obscpio -> python-zeroconf-0.36.9.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/README.rst 
new/python-zeroconf-0.36.9/README.rst
--- old/python-zeroconf-0.36.8/README.rst       2021-10-11 01:04:21.000000000 
+0200
+++ new/python-zeroconf-0.36.9/README.rst       2021-10-23 01:14:47.000000000 
+0200
@@ -138,6 +138,14 @@
 Changelog
 =========
 
+0.36.9
+======
+
+* Ensure ServiceInfo orders newest addresess first (#1012) @bdraco
+
+  This change effectively restored the behavior before 1s cache flush
+  expire behavior described in rfc6762 section 10.2 was added for callers that 
rely on this.
+
 0.36.8
 ======
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/setup.cfg 
new/python-zeroconf-0.36.9/setup.cfg
--- old/python-zeroconf-0.36.8/setup.cfg        2021-10-11 01:04:21.000000000 
+0200
+++ new/python-zeroconf-0.36.9/setup.cfg        2021-10-23 01:14:47.000000000 
+0200
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.36.8
+current_version = 0.36.9
 commit = True
 tag = True
 tag_name = {new_version}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/tests/services/test_info.py 
new/python-zeroconf-0.36.9/tests/services/test_info.py
--- old/python-zeroconf-0.36.8/tests/services/test_info.py      2021-10-11 
01:04:21.000000000 +0200
+++ new/python-zeroconf-0.36.9/tests/services/test_info.py      2021-10-23 
01:14:47.000000000 +0200
@@ -560,7 +560,27 @@
 # This test uses asyncio because it needs to access the cache directly
 # which is not threadsafe
 @pytest.mark.asyncio
-async def test_multiple_a_addresses():
+async def test_multiple_a_addresses_newest_address_first():
+    """Test that info.addresses returns the newest seen address first."""
+    type_ = "_http._tcp.local."
+    registration_name = "multiarec.%s" % type_
+    desc = {'path': '/~paulsm/'}
+    aiozc = AsyncZeroconf(interfaces=['127.0.0.1'])
+    cache = aiozc.zeroconf.cache
+    host = "multahost.local."
+    record1 = r.DNSAddress(host, const._TYPE_A, const._CLASS_IN, 1000, 
b'\x7f\x00\x00\x01')
+    record2 = r.DNSAddress(host, const._TYPE_A, const._CLASS_IN, 1000, 
b'\x7f\x00\x00\x02')
+    cache.async_add_records([record1, record2])
+
+    # New kwarg way
+    info = ServiceInfo(type_, registration_name, 80, 0, 0, desc, host)
+    info.load_from_cache(aiozc.zeroconf)
+    assert info.addresses == [b'\x7f\x00\x00\x02', b'\x7f\x00\x00\x01']
+    await aiozc.async_close()
+
+
+@pytest.mark.asyncio
+async def test_invalid_a_addresses(caplog):
     type_ = "_http._tcp.local."
     registration_name = "multiarec.%s" % type_
     desc = {'path': '/~paulsm/'}
@@ -574,7 +594,9 @@
     # New kwarg way
     info = ServiceInfo(type_, registration_name, 80, 0, 0, desc, host)
     info.load_from_cache(aiozc.zeroconf)
-    assert set(info.addresses) == set([b'a', b'b'])
+    assert not info.addresses
+    assert "Encountered invalid address while processing record" in caplog.text
+
     await aiozc.async_close()
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/tests/test_exceptions.py 
new/python-zeroconf-0.36.9/tests/test_exceptions.py
--- old/python-zeroconf-0.36.8/tests/test_exceptions.py 2021-10-11 
01:04:21.000000000 +0200
+++ new/python-zeroconf-0.36.9/tests/test_exceptions.py 2021-10-23 
01:14:47.000000000 +0200
@@ -141,11 +141,11 @@
         name = "xxxyyy"
         registration_name = f"{name}.{type_}"
 
-        bad = ('127.0.0.1', '::1', 42)
+        bad = (b'127.0.0.1', b'::1')
         for addr in bad:
             self.assertRaisesRegex(
                 TypeError,
-                'Addresses must be bytes',
+                'Addresses must either ',
                 ServiceInfo,
                 type_,
                 registration_name,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/zeroconf/__init__.py 
new/python-zeroconf-0.36.9/zeroconf/__init__.py
--- old/python-zeroconf-0.36.8/zeroconf/__init__.py     2021-10-11 
01:04:21.000000000 +0200
+++ new/python-zeroconf-0.36.9/zeroconf/__init__.py     2021-10-23 
01:14:47.000000000 +0200
@@ -79,7 +79,7 @@
 
 __author__ = 'Paul Scott-Murphy, William McBrine'
 __maintainer__ = 'Jakub Stasiak <ja...@stasiak.at>'
-__version__ = '0.36.8'
+__version__ = '0.36.9'
 __license__ = 'LGPL'
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-zeroconf-0.36.8/zeroconf/_services/info.py 
new/python-zeroconf-0.36.9/zeroconf/_services/info.py
--- old/python-zeroconf-0.36.8/zeroconf/_services/info.py       2021-10-11 
01:04:21.000000000 +0200
+++ new/python-zeroconf-0.36.9/zeroconf/_services/info.py       2021-10-23 
01:14:47.000000000 +0200
@@ -27,6 +27,7 @@
 
 from .._dns import DNSAddress, DNSPointer, DNSQuestionType, DNSRecord, 
DNSService, DNSText
 from .._exceptions import BadTypeInNameException
+from .._logger import log
 from .._protocol.outgoing import DNSOutgoing
 from .._updates import RecordUpdate, RecordUpdateListener
 from .._utils.asyncio import get_running_loop, run_coro_with_timeout
@@ -124,19 +125,12 @@
         self.type = type_
         self._name = name
         self.key = name.lower()
+        self._ipv4_addresses: List[ipaddress.IPv4Address] = []
+        self._ipv6_addresses: List[ipaddress.IPv6Address] = []
         if addresses is not None:
-            self._addresses = addresses
+            self.addresses = addresses
         elif parsed_addresses is not None:
-            self._addresses = [_encode_address(a) for a in parsed_addresses]
-        else:
-            self._addresses = []
-        # This results in an ugly error when registering, better check now
-        invalid = [a for a in self._addresses if not isinstance(a, bytes) or 
len(a) not in (4, 16)]
-        if invalid:
-            raise TypeError(
-                'Addresses must be bytes, got %s. Hint: convert string 
addresses '
-                'with socket.inet_pton' % invalid
-            )
+            self.addresses = [_encode_address(a) for a in parsed_addresses]
         self.port = port
         self.weight = weight
         self.priority = priority
@@ -178,7 +172,21 @@
 
         This replaces all currently stored addresses, both IPv4 and IPv6.
         """
-        self._addresses = value
+        self._ipv4_addresses.clear()
+        self._ipv6_addresses.clear()
+
+        for address in value:
+            try:
+                addr = ipaddress.ip_address(address)
+            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
+                )
+            if addr.version == 4:
+                self._ipv4_addresses.append(addr)
+            else:
+                self._ipv6_addresses.append(addr)
 
     @property
     def properties(self) -> Dict:
@@ -194,10 +202,13 @@
     def addresses_by_version(self, version: IPVersion) -> List[bytes]:
         """List addresses matching IP version."""
         if version == IPVersion.V4Only:
-            return [addr for addr in self._addresses if not 
_is_v6_address(addr)]
+            return [addr.packed for addr in self._ipv4_addresses]
         if version == IPVersion.V6Only:
-            return list(filter(_is_v6_address, self._addresses))
-        return self._addresses
+            return [addr.packed for addr in self._ipv6_addresses]
+        return [
+            *(addr.packed for addr in self._ipv4_addresses),
+            *(addr.packed for addr in self._ipv6_addresses),
+        ]
 
     def parsed_addresses(self, version: IPVersion = IPVersion.All) -> 
List[str]:
         """List addresses in their parsed string form."""
@@ -220,7 +231,7 @@
 
         ll_addrs = list(filter(is_link_local, self.parsed_addresses(version)))
         other_addrs = list(filter(lambda addr: not is_link_local(addr), 
self.parsed_addresses(version)))
-        return ["{}%{}".format(addr, self.interface_index) for addr in 
ll_addrs] + other_addrs
+        return [f"{addr}%{self.interface_index}" for addr in ll_addrs] + 
other_addrs
 
     def _set_properties(self, properties: Dict) -> None:
         """Sets properties and text of this info from a dictionary"""
@@ -315,9 +326,20 @@
             return
 
         if isinstance(record, DNSAddress):
-            if record.key == self.server_key and record.address not in 
self._addresses:
-                self._addresses.append(record.address)
-                if record.type is _TYPE_AAAA and 
ipaddress.IPv6Address(record.address).is_link_local:
+            if record.key != self.server_key:
+                return
+            try:
+                ip_addr = ipaddress.ip_address(record.address)
+            except ValueError as ex:
+                log.warning("Encountered invalid address while processing %s: 
%s", record, ex)
+                return
+            if ip_addr.version == 4:
+                if ip_addr not in self._ipv4_addresses:
+                    self._ipv4_addresses.insert(0, ip_addr)
+                return
+            if ip_addr not in self._ipv6_addresses:
+                self._ipv6_addresses.insert(0, ip_addr)
+                if ip_addr.is_link_local:
                     self.interface_index = record.scope_id
             return
 
@@ -422,7 +444,7 @@
     @property
     def _is_complete(self) -> bool:
         """The ServiceInfo has all expected properties."""
-        return not (self.text is None or not self._addresses)
+        return bool(self.text is not None and (self._ipv4_addresses or 
self._ipv6_addresses))
 
     def request(
         self, zc: 'Zeroconf', timeout: float, question_type: 
Optional[DNSQuestionType] = None
@@ -494,10 +516,10 @@
 
     def __repr__(self) -> str:
         """String representation"""
-        return '%s(%s)' % (
+        return '{}({})'.format(
             type(self).__name__,
             ', '.join(
-                '%s=%r' % (name, getattr(self, name))
+                '{}={!r}'.format(name, getattr(self, name))
                 for name in (
                     'type',
                     'name',

++++++ python-zeroconf.obsinfo ++++++
--- /var/tmp/diff_new_pack.SWfphL/_old  2021-10-27 22:21:16.515200801 +0200
+++ /var/tmp/diff_new_pack.SWfphL/_new  2021-10-27 22:21:16.515200801 +0200
@@ -1,5 +1,5 @@
 name: python-zeroconf
-version: 0.36.8
-mtime: 1633907061
-commit: 61275efd05688a61d656b43125b01a5d588f1dba
+version: 0.36.9
+mtime: 1634944487
+commit: d92d3d030558c1b81b2e35f701b585f4b48fa99a
 

Reply via email to