Hello community, here is the log from the commit of package python-portend for openSUSE:Factory checked in at 2019-06-24 21:45:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-portend (Old) and /work/SRC/openSUSE:Factory/.python-portend.new.4615 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-portend" Mon Jun 24 21:45:27 2019 rev:4 rq:710575 version:2.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-portend/python-portend.changes 2019-04-09 20:16:34.541577387 +0200 +++ /work/SRC/openSUSE:Factory/.python-portend.new.4615/python-portend.changes 2019-06-24 21:45:28.563741925 +0200 @@ -1,0 +2,6 @@ +Tue Jun 18 12:46:11 UTC 2019 - [email protected] + +- version update to 2.5 + * #10: Fix race condition in ``occupied`` and ``free`` + +------------------------------------------------------------------- Old: ---- portend-2.4.tar.gz New: ---- portend-2.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-portend.spec ++++++ --- /var/tmp/diff_new_pack.ajcGlS/_old 2019-06-24 21:45:30.375743291 +0200 +++ /var/tmp/diff_new_pack.ajcGlS/_new 2019-06-24 21:45:30.415743322 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-portend -Version: 2.4 +Version: 2.5 Release: 0 Summary: TCP port monitoring utilities License: MIT ++++++ portend-2.4.tar.gz -> portend-2.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/.flake8 new/portend-2.5/.flake8 --- old/portend-2.4/.flake8 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/.flake8 2019-06-11 02:56:58.000000000 +0200 @@ -1,10 +1,9 @@ [flake8] +max-line-length = 88 ignore = - # Allow tabs for indentation - W191 - # Workaround for https://github.com/PyCQA/pycodestyle/issues/836 - E117 # W503 violates spec https://github.com/PyCQA/pycodestyle/issues/513 W503 # W504 has issues https://github.com/OCA/maintainer-quality-tools/issues/545 W504 + # Black creates whitespace before colon + E203 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/.pre-commit-config.yaml new/portend-2.5/.pre-commit-config.yaml --- old/portend-2.4/.pre-commit-config.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/portend-2.5/.pre-commit-config.yaml 2019-06-11 02:56:58.000000000 +0200 @@ -0,0 +1,5 @@ +repos: +- repo: https://github.com/ambv/black + rev: 18.9b0 + hooks: + - id: black diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/CHANGES.rst new/portend-2.5/CHANGES.rst --- old/portend-2.4/CHANGES.rst 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/CHANGES.rst 2019-06-11 02:56:58.000000000 +0200 @@ -1,3 +1,8 @@ +2.5 +=== + +#10: Fix race condition in ``occupied`` and ``free``. + 2.4 === diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/PKG-INFO new/portend-2.5/PKG-INFO --- old/portend-2.4/PKG-INFO 2019-04-04 21:45:34.000000000 +0200 +++ new/portend-2.5/PKG-INFO 2019-06-11 02:57:16.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: portend -Version: 2.4 +Version: 2.5 Summary: TCP port monitoring and discovery Home-page: https://github.com/jaraco/portend Author: Jason R. Coombs @@ -14,6 +14,10 @@ .. image:: https://img.shields.io/travis/jaraco/portend/master.svg :target: https://travis-ci.org/jaraco/portend + .. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + :alt: Code style: Black + .. image:: https://img.shields.io/appveyor/ci/jaraco/portend/master.svg :target: https://ci.appveyor.com/project/jaraco/portend/branch/master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/README.rst new/portend-2.5/README.rst --- old/portend-2.4/README.rst 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/README.rst 2019-06-11 02:56:58.000000000 +0200 @@ -6,6 +6,10 @@ .. image:: https://img.shields.io/travis/jaraco/portend/master.svg :target: https://travis-ci.org/jaraco/portend +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + :alt: Code style: Black + .. image:: https://img.shields.io/appveyor/ci/jaraco/portend/master.svg :target: https://ci.appveyor.com/project/jaraco/portend/branch/master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/docs/conf.py new/portend-2.5/docs/conf.py --- old/portend-2.4/docs/conf.py 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/docs/conf.py 2019-06-11 02:56:58.000000000 +0200 @@ -1,25 +1,25 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -extensions = ["sphinx.ext.autodoc", "jaraco.packaging.sphinx", "rst.linker"] +extensions = ['sphinx.ext.autodoc', 'jaraco.packaging.sphinx', 'rst.linker'] master_doc = "index" link_files = { - "../CHANGES.rst": dict( - using=dict(GH="https://github.com"), + '../CHANGES.rst': dict( + using=dict(GH='https://github.com'), replace=[ dict( - pattern=r"(Issue #|\B#)(?P<issue>\d+)", - url="{package_url}/issues/{issue}", + pattern=r'(Issue #|\B#)(?P<issue>\d+)', + url='{package_url}/issues/{issue}', ), dict( - pattern=r"^(?m)((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n", - with_scm="{text}\n{rev[timestamp]:%d %b %Y}\n", + pattern=r'^(?m)((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n', + with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n', ), dict( - pattern=r"PEP[- ](?P<pep_number>\d+)", - url="https://www.python.org/dev/peps/pep-{pep_number:0>4}/", + pattern=r'PEP[- ](?P<pep_number>\d+)', + url='https://www.python.org/dev/peps/pep-{pep_number:0>4}/', ), ], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/portend.egg-info/PKG-INFO new/portend-2.5/portend.egg-info/PKG-INFO --- old/portend-2.4/portend.egg-info/PKG-INFO 2019-04-04 21:45:33.000000000 +0200 +++ new/portend-2.5/portend.egg-info/PKG-INFO 2019-06-11 02:57:16.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: portend -Version: 2.4 +Version: 2.5 Summary: TCP port monitoring and discovery Home-page: https://github.com/jaraco/portend Author: Jason R. Coombs @@ -14,6 +14,10 @@ .. image:: https://img.shields.io/travis/jaraco/portend/master.svg :target: https://travis-ci.org/jaraco/portend + .. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + :alt: Code style: Black + .. image:: https://img.shields.io/appveyor/ci/jaraco/portend/master.svg :target: https://ci.appveyor.com/project/jaraco/portend/branch/master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/portend.egg-info/SOURCES.txt new/portend-2.5/portend.egg-info/SOURCES.txt --- old/portend-2.4/portend.egg-info/SOURCES.txt 2019-04-04 21:45:33.000000000 +0200 +++ new/portend-2.5/portend.egg-info/SOURCES.txt 2019-06-11 02:57:16.000000000 +0200 @@ -1,4 +1,5 @@ .flake8 +.pre-commit-config.yaml .readthedocs.yml .travis.yml CHANGES.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/portend.egg-info/requires.txt new/portend-2.5/portend.egg-info/requires.txt --- old/portend-2.4/portend.egg-info/requires.txt 2019-04-04 21:45:33.000000000 +0200 +++ new/portend-2.5/portend.egg-info/requires.txt 2019-06-11 02:57:16.000000000 +0200 @@ -9,3 +9,4 @@ pytest!=3.7.3,>=3.5 pytest-checkdocs pytest-flake8 +pytest-black-multipy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/portend.py new/portend-2.5/portend.py --- old/portend-2.4/portend.py 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/portend.py 2019-06-11 02:56:58.000000000 +0200 @@ -15,209 +15,208 @@ import platform try: - from collections import abc + from collections import abc except ImportError: - import collections as abc + import collections as abc from tempora import timing def client_host(server_host): - """Return the host on which a client can connect to the given listener.""" - if server_host == '0.0.0.0': - # 0.0.0.0 is INADDR_ANY, which should answer on localhost. - return '127.0.0.1' - if server_host in ('::', '::0', '::0.0.0.0'): - # :: is IN6ADDR_ANY, which should answer on localhost. - # ::0 and ::0.0.0.0 are non-canonical but common - # ways to write IN6ADDR_ANY. - return '::1' - return server_host + """Return the host on which a client can connect to the given listener.""" + if server_host == '0.0.0.0': + # 0.0.0.0 is INADDR_ANY, which should answer on localhost. + return '127.0.0.1' + if server_host in ('::', '::0', '::0.0.0.0'): + # :: is IN6ADDR_ANY, which should answer on localhost. + # ::0 and ::0.0.0.0 are non-canonical but common + # ways to write IN6ADDR_ANY. + return '::1' + return server_host class Checker(object): - def __init__(self, timeout=1.0): - self.timeout = timeout + def __init__(self, timeout=1.0): + self.timeout = timeout - def assert_free(self, host, port=None): - """ - Assert that the given addr is free - in that all attempts to connect fail within the timeout - or raise a PortNotFree exception. - - >>> free_port = find_available_local_port() - - >>> Checker().assert_free('localhost', free_port) - >>> Checker().assert_free('127.0.0.1', free_port) - >>> Checker().assert_free('::1', free_port) - - Also accepts an addr tuple - - >>> addr = '::1', free_port, 0, 0 - >>> Checker().assert_free(addr) - - Host might refer to a server bind address like '::', which - should use localhost to perform the check. - - >>> Checker().assert_free('::', free_port) - """ - if port is None and isinstance(host, abc.Sequence): - host, port = host[:2] - if platform.system() == 'Windows': - host = client_host(host) - info = socket.getaddrinfo( - host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, - ) - list(itertools.starmap(self._connect, info)) - - def _connect(self, af, socktype, proto, canonname, sa): - s = socket.socket(af, socktype, proto) - # fail fast with a small timeout - s.settimeout(self.timeout) - - with contextlib.closing(s): - try: - s.connect(sa) - except socket.error: - return - - # the connect succeeded, so the port isn't free - port, host = sa[:2] - tmpl = "Port {port} is in use on {host}." - raise PortNotFree(tmpl.format(**locals())) + def assert_free(self, host, port=None): + """ + Assert that the given addr is free + in that all attempts to connect fail within the timeout + or raise a PortNotFree exception. + + >>> free_port = find_available_local_port() + + >>> Checker().assert_free('localhost', free_port) + >>> Checker().assert_free('127.0.0.1', free_port) + >>> Checker().assert_free('::1', free_port) + + Also accepts an addr tuple + + >>> addr = '::1', free_port, 0, 0 + >>> Checker().assert_free(addr) + + Host might refer to a server bind address like '::', which + should use localhost to perform the check. + + >>> Checker().assert_free('::', free_port) + """ + if port is None and isinstance(host, abc.Sequence): + host, port = host[:2] + if platform.system() == 'Windows': + host = client_host(host) + info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) + list(itertools.starmap(self._connect, info)) + + def _connect(self, af, socktype, proto, canonname, sa): + s = socket.socket(af, socktype, proto) + # fail fast with a small timeout + s.settimeout(self.timeout) + + with contextlib.closing(s): + try: + s.connect(sa) + except socket.error: + return + + # the connect succeeded, so the port isn't free + port, host = sa[:2] + tmpl = "Port {port} is in use on {host}." + raise PortNotFree(tmpl.format(**locals())) class Timeout(IOError): - pass + pass class PortNotFree(IOError): - pass + pass def free(host, port, timeout=float('Inf')): - """ - Wait for the specified port to become free (dropping or rejecting - requests). Return when the port is free or raise a Timeout if timeout has - elapsed. - - Timeout may be specified in seconds or as a timedelta. - If timeout is None or ∞, the routine will run indefinitely. - - >>> free('localhost', find_available_local_port()) - """ - if not host: - raise ValueError("Host values of '' or None are not allowed.") - - timer = timing.Timer(timeout) - - while not timer.expired(): - try: - # Expect a free port, so use a small timeout - Checker(timeout=0.1).assert_free(host, port) - return - except PortNotFree: - # Politely wait. - time.sleep(0.1) - - raise Timeout("Port {port} not free on {host}.".format(**locals())) + """ + Wait for the specified port to become free (dropping or rejecting + requests). Return when the port is free or raise a Timeout if timeout has + elapsed. + + Timeout may be specified in seconds or as a timedelta. + If timeout is None or ∞, the routine will run indefinitely. + + >>> free('localhost', find_available_local_port()) + """ + if not host: + raise ValueError("Host values of '' or None are not allowed.") + + timer = timing.Timer(timeout) + + while True: + try: + # Expect a free port, so use a small timeout + Checker(timeout=0.1).assert_free(host, port) + return + except PortNotFree: + if timer.expired(): + raise Timeout("Port {port} not free on {host}.".format(**locals())) + # Politely wait. + time.sleep(0.1) wait_for_free_port = free def occupied(host, port, timeout=float('Inf')): - """ - Wait for the specified port to become occupied (accepting requests). - Return when the port is occupied or raise a Timeout if timeout has - elapsed. - - Timeout may be specified in seconds or as a timedelta. - If timeout is None or ∞, the routine will run indefinitely. - - >>> occupied('localhost', find_available_local_port(), .1) - Traceback (most recent call last): - ... - Timeout: Port ... not bound on localhost. - """ - if not host: - raise ValueError("Host values of '' or None are not allowed.") - - timer = timing.Timer(timeout) - - while not timer.expired(): - try: - Checker(timeout=.5).assert_free(host, port) - # Politely wait - time.sleep(0.1) - except PortNotFree: - # port is occupied - return - - raise Timeout("Port {port} not bound on {host}.".format(**locals())) + """ + Wait for the specified port to become occupied (accepting requests). + Return when the port is occupied or raise a Timeout if timeout has + elapsed. + + Timeout may be specified in seconds or as a timedelta. + If timeout is None or ∞, the routine will run indefinitely. + + >>> occupied('localhost', find_available_local_port(), .1) + Traceback (most recent call last): + ... + Timeout: Port ... not bound on localhost. + """ + if not host: + raise ValueError("Host values of '' or None are not allowed.") + + timer = timing.Timer(timeout) + + while True: + try: + Checker(timeout=0.5).assert_free(host, port) + if timer.expired(): + raise Timeout("Port {port} not bound on {host}.".format(**locals())) + # Politely wait + time.sleep(0.1) + except PortNotFree: + # port is occupied + return wait_for_occupied_port = occupied def find_available_local_port(): - """ - Find a free port on localhost. + """ + Find a free port on localhost. - >>> 0 < find_available_local_port() < 65536 - True - """ - infos = socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM) - family, proto, _, _, addr = next(iter(infos)) - sock = socket.socket(family, proto) - sock.bind(addr) - addr, port = sock.getsockname()[:2] - sock.close() - return port + >>> 0 < find_available_local_port() < 65536 + True + """ + infos = socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM) + family, proto, _, _, addr = next(iter(infos)) + sock = socket.socket(family, proto) + sock.bind(addr) + addr, port = sock.getsockname()[:2] + sock.close() + return port class HostPort(str): - """ - A simple representation of a host/port pair as a string + """ + A simple representation of a host/port pair as a string - >>> hp = HostPort('localhost:32768') + >>> hp = HostPort('localhost:32768') - >>> hp.host - 'localhost' + >>> hp.host + 'localhost' - >>> hp.port - 32768 - - >>> len(hp) - 15 - """ - - @property - def host(self): - host, sep, port = self.partition(':') - return host - - @property - def port(self): - host, sep, port = self.partition(':') - return int(port) + >>> hp.port + 32768 + + >>> len(hp) + 15 + """ + + @property + def host(self): + host, sep, port = self.partition(':') + return host + + @property + def port(self): + host, sep, port = self.partition(':') + return int(port) def _main(): - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser() + + def global_lookup(key): + return globals()[key] - def global_lookup(key): - return globals()[key] - parser.add_argument('target', metavar='host:port', type=HostPort) - parser.add_argument('func', metavar='state', type=global_lookup) - parser.add_argument('-t', '--timeout', default=None, type=float) - args = parser.parse_args() - try: - args.func(args.target.host, args.target.port, timeout=args.timeout) - except Timeout as timeout: - print(timeout, file=sys.stderr) - raise SystemExit(1) + parser.add_argument('target', metavar='host:port', type=HostPort) + parser.add_argument('func', metavar='state', type=global_lookup) + parser.add_argument('-t', '--timeout', default=None, type=float) + args = parser.parse_args() + try: + args.func(args.target.host, args.target.port, timeout=args.timeout) + except Timeout as timeout: + print(timeout, file=sys.stderr) + raise SystemExit(1) if __name__ == '__main__': - _main() + _main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/pyproject.toml new/portend-2.5/pyproject.toml --- old/portend-2.4/pyproject.toml 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/pyproject.toml 2019-06-11 02:56:58.000000000 +0200 @@ -1,3 +1,6 @@ [build-system] requires = ["setuptools>=34.4", "wheel", "setuptools_scm>=1.15"] build-backend = "setuptools.build_meta" + +[tool.black] +skip-string-normalization = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/pytest.ini new/portend-2.5/pytest.ini --- old/portend-2.4/pytest.ini 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/pytest.ini 2019-06-11 02:56:58.000000000 +0200 @@ -1,6 +1,6 @@ [pytest] norecursedirs=dist build .tox .eggs -addopts=--doctest-modules --flake8 +addopts=--doctest-modules --flake8 --black doctest_optionflags=ALLOW_UNICODE ELLIPSIS IGNORE_EXCEPTION_DETAIL filterwarnings= ignore:Possible nested set::pycodestyle:113 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/setup.cfg new/portend-2.5/setup.cfg --- old/portend-2.4/setup.cfg 2019-04-04 21:45:34.000000000 +0200 +++ new/portend-2.5/setup.cfg 2019-06-11 02:57:16.000000000 +0200 @@ -29,6 +29,7 @@ pytest >= 3.5, !=3.7.3 pytest-checkdocs pytest-flake8 + pytest-black-multipy docs = sphinx jaraco.packaging >= 3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/skeleton.md new/portend-2.5/skeleton.md --- old/portend-2.4/skeleton.md 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/skeleton.md 2019-06-11 02:56:58.000000000 +0200 @@ -50,7 +50,8 @@ - setuptools declarative configuration using setup.cfg - tox for running tests - A README.rst as reStructuredText with some popular badges, but with readthedocs and appveyor badges commented out -- A CHANGES.rst file intended for publishing release notes about the project. +- A CHANGES.rst file intended for publishing release notes about the project +- Use of [black](https://black.readthedocs.io/en/stable/) for code formatting (disabled on unsupported Python 3.5 and earlier) ## Packaging Conventions @@ -97,8 +98,8 @@ Relies a .flake8 file to correct some default behaviors: -- allow tabs for indentation (legacy for jaraco projects) -- disable mutually incompatible rules W503 and W504. +- disable mutually incompatible rules W503 and W504 +- support for black format ## Continuous Integration diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/test_portend.py new/portend-2.5/test_portend.py --- old/portend-2.4/test_portend.py 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/test_portend.py 2019-06-11 02:56:58.000000000 +0200 @@ -2,54 +2,68 @@ import contextlib import pytest +from tempora import timing import portend def socket_infos(): - """ - Generate addr infos for connections to localhost - """ - host = None # all available interfaces - port = portend.find_available_local_port() - family = socket.AF_UNSPEC - socktype = socket.SOCK_STREAM - proto = 0 - flags = socket.AI_PASSIVE - return socket.getaddrinfo(host, port, family, socktype, proto, flags) + """ + Generate addr infos for connections to localhost + """ + host = None # all available interfaces + port = portend.find_available_local_port() + family = socket.AF_UNSPEC + socktype = socket.SOCK_STREAM + proto = 0 + flags = socket.AI_PASSIVE + return socket.getaddrinfo(host, port, family, socktype, proto, flags) def id_for_info(info): - af, = info[:1] - return str(af) + af, = info[:1] + return str(af) def build_addr_infos(): - params = list(socket_infos()) - ids = list(map(id_for_info, params)) - return locals() + params = list(socket_infos()) + ids = list(map(id_for_info, params)) + return locals() @pytest.fixture(**build_addr_infos()) def listening_addr(request): - af, socktype, proto, canonname, sa = request.param - sock = socket.socket(af, socktype, proto) - sock.bind(sa) - sock.listen(5) - with contextlib.closing(sock): - yield sa + af, socktype, proto, canonname, sa = request.param + sock = socket.socket(af, socktype, proto) + sock.bind(sa) + sock.listen(5) + with contextlib.closing(sock): + yield sa @pytest.fixture(**build_addr_infos()) def nonlistening_addr(request): - af, socktype, proto, canonname, sa = request.param - return sa + af, socktype, proto, canonname, sa = request.param + return sa -class TestChecker: - def test_check_port_listening(self, listening_addr): - with pytest.raises(portend.PortNotFree): - portend.Checker().assert_free(listening_addr) [email protected] +def immediate_timeout(monkeypatch): + monkeypatch.setattr(timing.Timer, 'expired', lambda: True) + - def test_check_port_nonlistening(self, nonlistening_addr): - portend.Checker().assert_free(nonlistening_addr) +class TestChecker: + def test_check_port_listening(self, listening_addr): + with pytest.raises(portend.PortNotFree): + portend.Checker().assert_free(listening_addr) + + def test_check_port_nonlistening(self, nonlistening_addr): + portend.Checker().assert_free(nonlistening_addr) + + def test_free_with_immediate_timeout(self, nonlistening_addr, immediate_timeout): + host, port = nonlistening_addr[:2] + portend.free(host, port, timeout=1.0) + + def test_occupied_with_immediate_timeout(self, listening_addr, immediate_timeout): + host, port = listening_addr[:2] + portend.occupied(host, port, timeout=1.0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/portend-2.4/tox.ini new/portend-2.5/tox.ini --- old/portend-2.4/tox.ini 2019-04-04 21:45:13.000000000 +0200 +++ new/portend-2.5/tox.ini 2019-06-11 02:56:58.000000000 +0200 @@ -1,6 +1,8 @@ [tox] envlist = python -minversion = 2.4 +minversion = 3.2 +# https://github.com/jaraco/skeleton/issues/6 +tox_pip_extensions_ext_venv_update = true [testenv] deps = @@ -22,8 +24,7 @@ skip_install = True deps = pep517>=0.5 - # workaround for https://github.com/pypa/twine/issues/423 - git+https://github.com/pypa/twine + twine>=1.13 path.py commands = python -c "import path; path.Path('dist').rmtree_p()"
