Skip to content
Snippets Groups Projects
Commit 4632a23b authored by YOKOTA Hiroshi's avatar YOKOTA Hiroshi
Browse files

New upstream version 0.141.0

parent 37fd97ad
No related branches found
Tags upstream/0.141.0
No related merge requests found
This diff is collapsed.
Metadata-Version: 2.3
Name: zeroconf
Version: 0.140.1
Version: 0.141.0
Summary: A pure python implementation of multicast DNS service discovery
License: LGPL-2.1-or-later
Author: Paul Scott-Murphy
......
[tool.poetry]
name = "zeroconf"
version = "0.140.1"
version = "0.141.0"
description = "A pure python implementation of multicast DNS service discovery"
authors = ["Paul Scott-Murphy", "William McBrine", "Jakub Stasiak", "J. Nick Koston"]
license = "LGPL-2.1-or-later"
......
......@@ -22,7 +22,7 @@ extras_require = \
setup_kwargs = {
'name': 'zeroconf',
'version': '0.140.1',
'version': '0.141.0',
'description': 'A pure python implementation of multicast DNS service discovery',
'long_description': 'python-zeroconf\n===============\n\n.. image:: https://github.com/python-zeroconf/python-zeroconf/workflows/CI/badge.svg\n :target: https://github.com/python-zeroconf/python-zeroconf?query=workflow%3ACI+branch%3Amaster\n\n.. image:: https://img.shields.io/pypi/v/zeroconf.svg\n :target: https://pypi.python.org/pypi/zeroconf\n\n.. image:: https://codecov.io/gh/python-zeroconf/python-zeroconf/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/python-zeroconf/python-zeroconf\n\n.. image:: https://img.shields.io/endpoint?url=https://codspeed.io/badge.json\n :target: https://codspeed.io/python-zeroconf/python-zeroconf\n :alt: Codspeed.io status for python-zeroconf\n\n`Documentation <https://python-zeroconf.readthedocs.io/en/latest/>`_.\n\nThis is fork of pyzeroconf, Multicast DNS Service Discovery for Python,\noriginally by Paul Scott-Murphy (https://github.com/paulsm/pyzeroconf),\nmodified by William McBrine (https://github.com/wmcbrine/pyzeroconf).\n\nThe original William McBrine\'s fork note::\n\n This fork is used in all of my TiVo-related projects: HME for Python\n (and therefore HME/VLC), Network Remote, Remote Proxy, and pyTivo.\n Before this, I was tracking the changes for zeroconf.py in three\n separate repos. I figured I should have an authoritative source.\n\n Although I make changes based on my experience with TiVos, I expect that\n they\'re generally applicable. This version also includes patches found\n on the now-defunct (?) Launchpad repo of pyzeroconf, and elsewhere\n around the net -- not always well-documented, sorry.\n\nCompatible with:\n\n* Bonjour\n* Avahi\n\nCompared to some other Zeroconf/Bonjour/Avahi Python packages, python-zeroconf:\n\n* isn\'t tied to Bonjour or Avahi\n* doesn\'t use D-Bus\n* doesn\'t force you to use particular event loop or Twisted (asyncio is used under the hood but not required)\n* is pip-installable\n* has PyPI distribution\n* has an optional cython extension for performance (pure python is supported as well)\n\nPython compatibility\n--------------------\n\n* CPython 3.9+\n* PyPy 3.9+\n\nVersioning\n----------\n\nThis project uses semantic versioning.\n\nStatus\n------\n\nThis project is actively maintained.\n\nTraffic Reduction\n-----------------\n\nBefore version 0.32, most traffic reduction techniques described in https://datatracker.ietf.org/doc/html/rfc6762#section-7\nwhere not implemented which could lead to excessive network traffic. It is highly recommended that version 0.32 or later\nis used if this is a concern.\n\nIPv6 support\n------------\n\nIPv6 support is relatively new and currently limited, specifically:\n\n* `InterfaceChoice.All` is an alias for `InterfaceChoice.Default` on non-POSIX\n systems.\n* Dual-stack IPv6 sockets are used, which may not be supported everywhere (some\n BSD variants do not have them).\n* Listening on localhost (`::1`) does not work. Help with understanding why is\n appreciated.\n\nHow to get python-zeroconf?\n===========================\n\n* PyPI page https://pypi.org/project/zeroconf/\n* GitHub project https://github.com/python-zeroconf/python-zeroconf\n\nThe easiest way to install python-zeroconf is using pip::\n\n pip install zeroconf\n\n\n\nHow do I use it?\n================\n\nHere\'s an example of browsing for a service:\n\n.. code-block:: python\n\n from zeroconf import ServiceBrowser, ServiceListener, Zeroconf\n\n\n class MyListener(ServiceListener):\n\n def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:\n print(f"Service {name} updated")\n\n def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:\n print(f"Service {name} removed")\n\n def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:\n info = zc.get_service_info(type_, name)\n print(f"Service {name} added, service info: {info}")\n\n\n zeroconf = Zeroconf()\n listener = MyListener()\n browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)\n try:\n input("Press enter to exit...\\n\\n")\n finally:\n zeroconf.close()\n\n.. note::\n\n Discovery and service registration use *all* available network interfaces by default.\n If you want to customize that you need to specify ``interfaces`` argument when\n constructing ``Zeroconf`` object (see the code for details).\n\nIf you don\'t know the name of the service you need to browse for, try:\n\n.. code-block:: python\n\n from zeroconf import ZeroconfServiceTypes\n print(\'\\n\'.join(ZeroconfServiceTypes.find()))\n\nSee examples directory for more.\n\nChangelog\n=========\n\n`Changelog <CHANGELOG.md>`_\n\nLicense\n=======\n\nLGPL, see COPYING file for details.\n',
'author': 'Paul Scott-Murphy',
......
......@@ -83,7 +83,7 @@ from ._utils.time import ( # noqa # import needed for backwards compat
__author__ = "Paul Scott-Murphy, William McBrine"
__maintainer__ = "Jakub Stasiak <jakub@stasiak.at>"
__version__ = "0.140.1"
__version__ = "0.141.0"
__license__ = "LGPL"
......
......@@ -39,7 +39,7 @@ cdef class DNSCache:
@cython.locals(store=cython.dict)
cpdef DNSRecord async_get_unique(self, DNSRecord entry)
@cython.locals(record=DNSRecord)
@cython.locals(record=DNSRecord, when_record=tuple, when=double)
cpdef list async_expire(self, double now)
@cython.locals(records=cython.dict, record=DNSRecord)
......@@ -57,8 +57,10 @@ cdef class DNSCache:
@cython.locals(
store=cython.dict,
service_store=cython.dict,
service_record=DNSService,
when=object
when=object,
new=bint
)
cdef bint _async_add(self, DNSRecord record)
......
......@@ -86,7 +86,8 @@ class DNSCache:
# 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.
store = self.cache.setdefault(record.key, {})
if (store := self.cache.get(record.key)) is None:
store = self.cache[record.key] = {}
new = record not in store and not isinstance(record, DNSNsec)
store[record] = record
when = record.created + (record.ttl * 1000)
......@@ -97,7 +98,9 @@ class DNSCache:
if isinstance(record, DNSService):
service_record = record
self.service_cache.setdefault(record.server_key, {})[service_record] = service_record
if (service_store := self.service_cache.get(service_record.server_key)) is None:
service_store = self.service_cache[service_record.server_key] = {}
service_store[service_record] = service_record
return new
def async_add_records(self, entries: Iterable[DNSRecord]) -> bool:
......@@ -145,7 +148,8 @@ class DNSCache:
expired: List[DNSRecord] = []
# Find any expired records and add them to the to-delete list
while self._expire_heap:
when, record = self._expire_heap[0]
when_record = self._expire_heap[0]
when = when_record[0]
if when > now:
break
heappop(self._expire_heap)
......@@ -153,6 +157,7 @@ class DNSCache:
# with a different expiration time as it will be removed
# later when it reaches the top of the heap and its
# expiration time is met.
record = when_record[1]
if self._expirations.get(record) == when:
expired.append(record)
......
from pytest_codspeed import BenchmarkFixture
from zeroconf import DNSCache, DNSPointer, current_time_millis
from zeroconf.const import _CLASS_IN, _TYPE_PTR
def test_add_expire_1000_records(benchmark: BenchmarkFixture) -> None:
"""Benchmark for DNSCache to expire 10000 records."""
cache = DNSCache()
now = current_time_millis()
records = [
DNSPointer(
name=f"test{id}.local.",
type_=_TYPE_PTR,
class_=_CLASS_IN,
ttl=60,
alias=f"test{id}.local.",
created=now + id,
)
for id in range(1000)
]
@benchmark
def _expire_records() -> None:
cache.async_add_records(records)
cache.async_expire(now + 100_000)
def test_expire_no_records_to_expire(benchmark: BenchmarkFixture) -> None:
"""Benchmark for DNSCache with 1000 records none to expire."""
cache = DNSCache()
now = current_time_millis()
cache.async_add_records(
DNSPointer(
name=f"test{id}.local.",
type_=_TYPE_PTR,
class_=_CLASS_IN,
ttl=60,
alias=f"test{id}.local.",
created=now + id,
)
for id in range(1000)
)
cache.async_expire(now)
@benchmark
def _expire_records() -> None:
cache.async_expire(now)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment