| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7bd0436 commit 3d5787b
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ install: | |||
| 13 | 13 | - if [[ "${TRAVIS_PYTHON_VERSION}" != "pypy"* ]] ; then pip install mypy ; fi | |
| 14 | 14 | - if [[ "${TRAVIS_PYTHON_VERSION}" != *"3.5"* ]] ; then pip install black ; fi | |
| 15 | 15 | script: | |
| 16 | - - make ci | ||
| 16 | + # no IPv6 support in Travis :( | ||
| 17 | + - make TEST_ARGS='-a "!IPv6"' ci | ||
| 17 | 18 | after_success: | |
| 18 | 19 | - coveralls | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | MAX_LINE_LENGTH=110 | |
| 3 | 3 | PYTHON_IMPLEMENTATION:=$(shell python -c "import sys;import platform;sys.stdout.write(platform.python_implementation())") | |
| 4 | 4 | PYTHON_VERSION:=$(shell python -c "import sys;sys.stdout.write('%d.%d' % sys.version_info[:2])") | |
| 5 | + TEST_ARGS= | ||
| 5 | 6 | ||
| 6 | 7 | LINT_TARGETS:=flake8 | |
| 7 | 8 | ||
@@ -39,10 +40,10 @@ mypy: | |||
| 39 | 40 | mypy examples/*.py test_zeroconf.py zeroconf.py | |
| 40 | 41 | ||
| 41 | 42 | test: | |
| 42 | - nosetests -v | ||
| 43 | + nosetests -v $(TEST_ARGS) | ||
| 43 | 44 | ||
| 44 | 45 | test_coverage: | |
| 45 | - nosetests -v --with-coverage --cover-package=zeroconf | ||
| 46 | + nosetests -v --with-coverage --cover-package=zeroconf $(TEST_ARGS) | ||
| 46 | 47 | ||
| 47 | 48 | autopep8: | |
| 48 | 49 | autopep8 --max-line-length=$(MAX_LINE_LENGTH) -i examples *.py | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,18 @@ Status | |||
| 61 | 61 | There are some people using this package. I don't actively use it and as such | |
| 62 | 62 | any help I can offer with regard to any issues is very limited. | |
| 63 | 63 | ||
| 64 | + IPv6 support | ||
| 65 | + ------------ | ||
| 66 | + | ||
| 67 | + IPv6 support is relatively new and currently limited, specifically: | ||
| 68 | + * `InterfaceChoice.All` is an alias for `InterfaceChoice.Default` on non-POSIX | ||
| 69 | + systems. | ||
| 70 | + * On Windows specific interfaces can only be requested as interface indexes, | ||
| 71 | + not as IP addresses. | ||
| 72 | + * Dual-stack IPv6 sockets are used, which may not be supported everywhere (some | ||
| 73 | + BSD variants do not have them). | ||
| 74 | + * Listening on localhost (`::1`) does not work. Help with understanding why is | ||
| 75 | + appreciated. | ||
| 64 | 76 | ||
| 65 | 77 | How to get python-zeroconf? | |
| 66 | 78 | =========================== | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,13 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | 3 | """ Example of browsing for a service (in this case, HTTP) """ | |
| 4 | 4 | ||
| 5 | + import argparse | ||
| 5 | 6 | import logging | |
| 6 | 7 | import socket | |
| 7 | - import sys | ||
| 8 | 8 | from time import sleep | |
| 9 | 9 | from typing import cast | |
| 10 | 10 | ||
| 11 | - from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf | ||
| 11 | + from zeroconf import IpVersion, ServiceBrowser, ServiceStateChange, Zeroconf | ||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | def on_service_state_change( | |
@@ -36,11 +36,24 @@ def on_service_state_change( | |||
| 36 | 36 | ||
| 37 | 37 | if __name__ == '__main__': | |
| 38 | 38 | logging.basicConfig(level=logging.DEBUG) | |
| 39 | - if len(sys.argv) > 1: | ||
| 40 | - assert sys.argv[1:] == ['--debug'] | ||
| 39 | + | ||
| 40 | + parser = argparse.ArgumentParser() | ||
| 41 | + parser.add_argument('--debug', action='store_true') | ||
| 42 | + version_group = parser.add_mutually_exclusive_group() | ||
| 43 | + version_group.add_argument('--v6', action='store_true') | ||
| 44 | + version_group.add_argument('--v6-only', action='store_true') | ||
| 45 | + args = parser.parse_args() | ||
| 46 | + | ||
| 47 | + if args.debug: | ||
| 41 | 48 | logging.getLogger('zeroconf').setLevel(logging.DEBUG) | |
| 49 | + if args.v6: | ||
| 50 | + ip_version = IpVersion.All | ||
| 51 | + elif args.v6_only: | ||
| 52 | + ip_version = IpVersion.V6Only | ||
| 53 | + else: | ||
| 54 | + ip_version = IpVersion.V4Only | ||
| 42 | 55 | ||
| 43 | - zeroconf = Zeroconf() | ||
| 56 | + zeroconf = Zeroconf(ip_version=ip_version) | ||
| 44 | 57 | print("\nBrowsing services, press Ctrl-C to exit...\n") | |
| 45 | 58 | browser = ServiceBrowser(zeroconf, "_http._tcp.local.", handlers=[on_service_state_change]) | |
| 46 | 59 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,18 +2,31 @@ | |||
| 2 | 2 | ||
| 3 | 3 | """ Example of announcing a service (in this case, a fake HTTP server) """ | |
| 4 | 4 | ||
| 5 | + import argparse | ||
| 5 | 6 | import logging | |
| 6 | 7 | import socket | |
| 7 | - import sys | ||
| 8 | 8 | from time import sleep | |
| 9 | 9 | ||
| 10 | - from zeroconf import ServiceInfo, Zeroconf | ||
| 10 | + from zeroconf import IpVersion, ServiceInfo, Zeroconf | ||
| 11 | 11 | ||
| 12 | 12 | if __name__ == '__main__': | |
| 13 | 13 | logging.basicConfig(level=logging.DEBUG) | |
| 14 | - if len(sys.argv) > 1: | ||
| 15 | - assert sys.argv[1:] == ['--debug'] | ||
| 14 | + | ||
| 15 | + parser = argparse.ArgumentParser() | ||
| 16 | + parser.add_argument('--debug', action='store_true') | ||
| 17 | + version_group = parser.add_mutually_exclusive_group() | ||
| 18 | + version_group.add_argument('--v6', action='store_true') | ||
| 19 | + version_group.add_argument('--v6-only', action='store_true') | ||
| 20 | + args = parser.parse_args() | ||
| 21 | + | ||
| 22 | + if args.debug: | ||
| 16 | 23 | logging.getLogger('zeroconf').setLevel(logging.DEBUG) | |
| 24 | + if args.v6: | ||
| 25 | + ip_version = IpVersion.All | ||
| 26 | + elif args.v6_only: | ||
| 27 | + ip_version = IpVersion.V6Only | ||
| 28 | + else: | ||
| 29 | + ip_version = IpVersion.V4Only | ||
| 17 | 30 | ||
| 18 | 31 | desc = {'path': '/~paulsm/'} | |
| 19 | 32 | ||
@@ -26,7 +39,7 @@ | |||
| 26 | 39 | server="ash-2.local.", | |
| 27 | 40 | ) | |
| 28 | 41 | ||
| 29 | - zeroconf = Zeroconf() | ||
| 42 | + zeroconf = Zeroconf(ip_version=ip_version) | ||
| 30 | 43 | print("Registration of a service, press Ctrl-C to exit...") | |
| 31 | 44 | zeroconf.register_service(info) | |
| 32 | 45 | try: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,7 @@ | |||
| 14 | 14 | from typing import Dict, Optional # noqa # used in type hints | |
| 15 | 15 | from typing import cast | |
| 16 | 16 | ||
| 17 | + from nose.plugins.attrib import attr | ||
| 17 | 18 | ||
| 18 | 19 | import zeroconf as r | |
| 19 | 20 | from zeroconf import ( | |
@@ -440,6 +441,22 @@ def test_launch_and_close(self): | |||
| 440 | 441 | rv = r.Zeroconf(interfaces=r.InterfaceChoice.Default) | |
| 441 | 442 | rv.close() | |
| 442 | 443 | ||
| 444 | + @unittest.skipIf(not socket.has_ipv6, 'Requires IPv6') | ||
| 445 | + @attr('IPv6') | ||
| 446 | + def test_launch_and_close_v4_v6(self): | ||
| 447 | + rv = r.Zeroconf(interfaces=r.InterfaceChoice.All, ip_version=r.IpVersion.All) | ||
| 448 | + rv.close() | ||
| 449 | + rv = r.Zeroconf(interfaces=r.InterfaceChoice.Default, ip_version=r.IpVersion.All) | ||
| 450 | + rv.close() | ||
| 451 | + | ||
| 452 | + @unittest.skipIf(not socket.has_ipv6, 'Requires IPv6') | ||
| 453 | + @attr('IPv6') | ||
| 454 | + def test_launch_and_close_v6_only(self): | ||
| 455 | + rv = r.Zeroconf(interfaces=r.InterfaceChoice.All, ip_version=r.IpVersion.V6Only) | ||
| 456 | + rv.close() | ||
| 457 | + rv = r.Zeroconf(interfaces=r.InterfaceChoice.Default, ip_version=r.IpVersion.V6Only) | ||
| 458 | + rv.close() | ||
| 459 | + | ||
| 443 | 460 | ||
| 444 | 461 | class Exceptions(unittest.TestCase): | |
| 445 | 462 | ||
@@ -672,6 +689,30 @@ def test_integration_with_listener(self): | |||
| 672 | 689 | finally: | |
| 673 | 690 | zeroconf_registrar.close() | |
| 674 | 691 | ||
| 692 | + @unittest.skipIf(not socket.has_ipv6, 'Requires IPv6') | ||
| 693 | + @attr('IPv6') | ||
| 694 | + def test_integration_with_listener_ipv6(self): | ||
| 695 | + | ||
| 696 | + type_ = "_test-srvc-type._tcp.local." | ||
| 697 | + name = "xxxyyy" | ||
| 698 | + registration_name = "%s.%s" % (name, type_) | ||
| 699 | + | ||
| 700 | + zeroconf_registrar = Zeroconf(ip_version=r.IpVersion.V6Only) | ||
| 701 | + desc = {'path': '/~paulsm/'} | ||
| 702 | + info = ServiceInfo( | ||
| 703 | + type_, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local." | ||
| 704 | + ) | ||
| 705 | + zeroconf_registrar.register_service(info) | ||
| 706 | + | ||
| 707 | + try: | ||
| 708 | + service_types = ZeroconfServiceTypes.find(ip_version=r.IpVersion.V6Only, timeout=0.5) | ||
| 709 | + assert type_ in service_types, service_types | ||
| 710 | + service_types = ZeroconfServiceTypes.find(zc=zeroconf_registrar, timeout=0.5) | ||
| 711 | + assert type_ in service_types, service_types | ||
| 712 | + | ||
| 713 | + finally: | ||
| 714 | + zeroconf_registrar.close() | ||
| 715 | + | ||
| 675 | 716 | def test_integration_with_subtype_and_listener(self): | |
| 676 | 717 | subtype_ = "_subtype._sub" | |
| 677 | 718 | type_ = "_type._tcp.local." | |
| Back | FazBrowse Home | New Git URL |
0 commit comments