diff --git a/.travis.yml b/.travis.yml index c01068d..67c2d20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,4 +29,4 @@ script: - if [ $TRAVIS_PYTHON_VERSION != '2.6' ]; then flake8 --ignore=E501,E128 zerorpc bin; fi - - nosetests -v + - pytest -v diff --git a/doc/protocol.md b/doc/protocol.md index 37a6417..cfc83d2 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -207,7 +207,7 @@ exception is raised), we use the ERR event. - Name of the error (it should be the exception class name, or another meaningful keyword). - Human representation of the error (preferably in english). - - If possible a pretty printed traceback of the call stack when the error occured. + - If possible a pretty printed traceback of the call stack when the error occurred. > A future version of the protocol will probably add a structured version of the > traceback, allowing machine-to-machine stack walking and better cross-language diff --git a/setup.py b/setup.py index 610e68b..b07ebcb 100644 --- a/setup.py +++ b/setup.py @@ -64,8 +64,8 @@ url='https://github.com/0rpc/zerorpc-python', packages=['zerorpc'], install_requires=requirements, - tests_require=['nose'], - test_suite='nose.collector', + tests_require=['pytest'], + test_suite='pytest.collector', zip_safe=False, entry_points={'console_scripts': ['zerorpc = zerorpc.cli:main']}, license='MIT', diff --git a/tests/test_buffered_channel.py b/tests/test_buffered_channel.py index 76d0fe3..20b8173 100644 --- a/tests/test_buffered_channel.py +++ b/tests/test_buffered_channel.py @@ -27,7 +27,7 @@ from __future__ import absolute_import from builtins import range -from nose.tools import assert_raises +import pytest import gevent import sys @@ -61,9 +61,9 @@ def test_close_server_bufchan(): print('CLOSE SERVER SOCKET!!!') server_bufchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_bufchan.recv) + pytest.raises(zerorpc.LostRemote, client_bufchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_bufchan.recv() print('CLIENT LOST SERVER :)') client_bufchan.close() @@ -96,9 +96,9 @@ def test_close_client_bufchan(): print('CLOSE CLIENT SOCKET!!!') client_bufchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_bufchan.recv) + pytest.raises(zerorpc.LostRemote, client_bufchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_bufchan.recv() print('SERVER LOST CLIENT :)') server_bufchan.close() @@ -129,9 +129,9 @@ def test_heartbeat_can_open_channel_server_close(): print('CLOSE SERVER SOCKET!!!') server_bufchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_bufchan.recv) + pytest.raises(zerorpc.LostRemote, client_bufchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_bufchan.recv() print('CLIENT LOST SERVER :)') client_bufchan.close() @@ -170,9 +170,9 @@ def server_fn(): client_bufchan.close() client.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, server_coro.get) + pytest.raises(zerorpc.LostRemote, server_coro.get) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): server_coro.get() print('SERVER LOST CLIENT :)') server.close() @@ -244,9 +244,9 @@ def client_do(): assert list(event.args) == [x + x * x] client_bufchan.emit('add', (x, x * x)) if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_bufchan.recv) + pytest.raises(zerorpc.LostRemote, client_bufchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_bufchan.recv() client_bufchan.close() @@ -308,9 +308,9 @@ def server_do(): server_bufchan.emit('OK', (sum(event.args),)) if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, server_bufchan.recv) + pytest.raises(zerorpc.LostRemote, server_bufchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): server_bufchan.recv() server_bufchan.close() @@ -343,9 +343,9 @@ def _do_with_assert_raises(): event = client_bufchan.recv(timeout=TIME_FACTOR * 3) assert event.name == 'OK' assert list(event.args) == [x] - assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises) + pytest.raises(zerorpc.TimeoutExpired, _do_with_assert_raises) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): for x in range(10): client_bufchan.emit('sleep', (x,)) event = client_bufchan.recv(timeout=TIME_FACTOR * 3) @@ -369,9 +369,9 @@ def _do_with_assert_raises(): assert event.name == 'sleep' gevent.sleep(TIME_FACTOR * event.args[0]) server_bufchan.emit('OK', event.args) - assert_raises(zerorpc.LostRemote, _do_with_assert_raises) + pytest.raises(zerorpc.LostRemote, _do_with_assert_raises) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): for x in range(20): event = server_bufchan.recv() assert event.name == 'sleep' @@ -422,9 +422,9 @@ def server_do(): def _do_with_assert_raises(): for x in range(200): server_bufchan.emit('coucou', x, timeout=0) # will fail when x == 1 - assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises) + pytest.raises(zerorpc.TimeoutExpired, _do_with_assert_raises) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): for x in range(200): server_bufchan.emit('coucou', x, timeout=0) # will fail when x == 1 server_bufchan.emit('coucou', 1) # block until receiver is ready @@ -432,9 +432,9 @@ def _do_with_assert_raises(): def _do_with_assert_raises(): for x in range(2, 200): server_bufchan.emit('coucou', x, timeout=0) # will fail when x == 100 - assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises) + pytest.raises(zerorpc.TimeoutExpired, _do_with_assert_raises) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): for x in range(2, 200): server_bufchan.emit('coucou', x, timeout=0) # will fail when x == 100 for x in range(read_cnt.value, 200): diff --git a/tests/test_client_async.py b/tests/test_client_async.py index 3acbd3b..ced4b1f 100644 --- a/tests/test_client_async.py +++ b/tests/test_client_async.py @@ -25,7 +25,7 @@ from __future__ import print_function from __future__ import absolute_import -from nose.tools import assert_raises +import pytest import gevent import sys @@ -53,14 +53,14 @@ def add(self, a, b): client = zerorpc.Client(timeout=TIME_FACTOR * 2) client.connect(endpoint) - async_result = client.add(1, 4, async=True) + async_result = client.add(1, 4, async_=True) if sys.version_info < (2, 7): def _do_with_assert_raises(): print(async_result.get()) - assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises) + pytest.raises(zerorpc.TimeoutExpired, _do_with_assert_raises) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): print(async_result.get()) client.close() srv.close() @@ -84,8 +84,8 @@ def add(self, a, b): client = zerorpc.Client() client.connect(endpoint) - async_result = client.lolita(async=True) + async_result = client.lolita(async_=True) assert async_result.get() == 42 - async_result = client.add(1, 4, async=True) + async_result = client.add(1, 4, async_=True) assert async_result.get() == 5 diff --git a/tests/test_heartbeat.py b/tests/test_heartbeat.py index 75b1d29..14c66fd 100644 --- a/tests/test_heartbeat.py +++ b/tests/test_heartbeat.py @@ -27,7 +27,7 @@ from __future__ import absolute_import from builtins import range -from nose.tools import assert_raises +import pytest import gevent import sys @@ -59,9 +59,9 @@ def test_close_server_hbchan(): print('CLOSE SERVER SOCKET!!!') server_hbchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_hbchan.recv) + pytest.raises(zerorpc.LostRemote, client_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_hbchan.recv() print('CLIENT LOST SERVER :)') client_hbchan.close() @@ -92,9 +92,9 @@ def test_close_client_hbchan(): print('CLOSE CLIENT SOCKET!!!') client_hbchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, server_hbchan.recv) + pytest.raises(zerorpc.LostRemote, server_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): server_hbchan.recv() print('SERVER LOST CLIENT :)') server_hbchan.close() @@ -123,9 +123,9 @@ def test_heartbeat_can_open_channel_server_close(): print('CLOSE SERVER SOCKET!!!') server_hbchan.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_hbchan.recv) + pytest.raises(zerorpc.LostRemote, client_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_hbchan.recv() print('CLIENT LOST SERVER :)') client_hbchan.close() @@ -155,9 +155,9 @@ def test_heartbeat_can_open_channel_client_close(): client_hbchan.close() client.close() if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, server_hbchan.recv) + pytest.raises(zerorpc.LostRemote, server_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): server_hbchan.recv() print('SERVER LOST CLIENT :)') server_hbchan.close() @@ -227,9 +227,9 @@ def client_do(): assert list(event.args) == [x + x * x] client_hbchan.emit('add', (x, x * x)) if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, client_hbchan.recv) + pytest.raises(zerorpc.LostRemote, client_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): client_hbchan.recv() client_hbchan.close() @@ -287,9 +287,9 @@ def server_do(): server_hbchan.emit('OK', (sum(event.args),)) if sys.version_info < (2, 7): - assert_raises(zerorpc.LostRemote, server_hbchan.recv) + pytest.raises(zerorpc.LostRemote, server_hbchan.recv) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): server_hbchan.recv() server_hbchan.close() @@ -322,9 +322,9 @@ def _do_with_assert_raises(): event = client_hbchan.recv(timeout=TIME_FACTOR * 3) assert event.name == 'OK' assert list(event.args) == [x] - assert_raises(zerorpc.TimeoutExpired, _do_with_assert_raises) + pytest.raises(zerorpc.TimeoutExpired, _do_with_assert_raises) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): for x in range(10): client_hbchan.emit('sleep', (x,)) event = client_hbchan.recv(timeout=TIME_FACTOR * 3) @@ -346,9 +346,9 @@ def _do_with_assert_raises(): assert event.name == 'sleep' gevent.sleep(TIME_FACTOR * event.args[0]) server_hbchan.emit('OK', event.args) - assert_raises(zerorpc.LostRemote, _do_with_assert_raises) + pytest.raises(zerorpc.LostRemote, _do_with_assert_raises) else: - with assert_raises(zerorpc.LostRemote): + with pytest.raises(zerorpc.LostRemote): for x in range(20): event = server_hbchan.recv() assert event.name == 'sleep' diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 754f8cb..3163a3a 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -28,7 +28,7 @@ from builtins import str from future.utils import tobytes -from nose.tools import assert_raises +import pytest import gevent import gevent.local import random @@ -101,9 +101,9 @@ def hello(self): srv = Srv(heartbeat=TIME_FACTOR * 1, context=c) if sys.version_info < (2, 7): - assert_raises(zmq.ZMQError, srv.bind, 'some_service') + pytest.raises(zmq.ZMQError, srv.bind, 'some_service') else: - with assert_raises(zmq.ZMQError): + with pytest.raises(zmq.ZMQError): srv.bind('some_service') cnt = c.register_middleware(Resolver()) diff --git a/tests/test_reqstream.py b/tests/test_reqstream.py index 5d48b4d..71e1511 100644 --- a/tests/test_reqstream.py +++ b/tests/test_reqstream.py @@ -28,11 +28,17 @@ from builtins import range import gevent -import collections import zerorpc from .testutils import teardown, random_ipc_endpoint, TIME_FACTOR +try: + # Try collections.abc for 3.4+ + from collections.abc import Iterator +except ImportError: + # Fallback to collections for Python 2 + from collections import Iterator + def test_rcp_streaming(): endpoint = random_ipc_endpoint() @@ -58,7 +64,7 @@ def xrange(self, max): assert list(r) == list(range(10)) r = client.xrange(10) - assert isinstance(r, collections.Iterator) + assert isinstance(r, Iterator) l = [] print('wait 4s for fun') gevent.sleep(TIME_FACTOR * 4) diff --git a/tests/test_server.py b/tests/test_server.py index 2a266ce..86997a9 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -27,7 +27,7 @@ from __future__ import absolute_import from builtins import range -from nose.tools import assert_raises +import pytest import gevent import sys @@ -114,9 +114,9 @@ def add(self, a, b): client.connect(endpoint) if sys.version_info < (2, 7): - assert_raises(zerorpc.TimeoutExpired, client.add, 1, 4) + pytest.raises(zerorpc.TimeoutExpired, client.add, 1, 4) else: - with assert_raises(zerorpc.TimeoutExpired): + with pytest.raises(zerorpc.TimeoutExpired): print(client.add(1, 4)) client.close() srv.close() @@ -140,9 +140,9 @@ def raise_something(self, a): if sys.version_info < (2, 7): def _do_with_assert_raises(): print(client.raise_something(42)) - assert_raises(zerorpc.RemoteError, _do_with_assert_raises) + pytest.raises(zerorpc.RemoteError, _do_with_assert_raises) else: - with assert_raises(zerorpc.RemoteError): + with pytest.raises(zerorpc.RemoteError): print(client.raise_something(42)) assert client.raise_something(list(range(5))) == 4 client.close() @@ -167,9 +167,9 @@ def raise_error(self): if sys.version_info < (2, 7): def _do_with_assert_raises(): print(client.raise_error()) - assert_raises(zerorpc.RemoteError, _do_with_assert_raises) + pytest.raises(zerorpc.RemoteError, _do_with_assert_raises) else: - with assert_raises(zerorpc.RemoteError): + with pytest.raises(zerorpc.RemoteError): print(client.raise_error()) try: client.raise_error() diff --git a/tests/testutils.py b/tests/testutils.py index 2a0110c..85b6a96 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -26,7 +26,7 @@ from builtins import str import functools -import nose.exc +import pytest import random import os @@ -52,7 +52,7 @@ def skip(reason): def _skip(test): @functools.wraps(test) def wrap(): - raise nose.exc.SkipTest(reason) + raise pytest.SkipTest(reason) return wrap return _skip diff --git a/tox.ini b/tox.ini index 3490b2c..96bace8 100644 --- a/tox.ini +++ b/tox.ini @@ -4,10 +4,10 @@ envlist = py26,py27,py34,py35 [testenv] deps = flake8 - nose + pytest commands = flake8 zerorpc bin - nosetests -v + pytest -v passenv = ZPC_TEST_TIME_FACTOR [flake8] diff --git a/zerorpc/cli.py b/zerorpc/cli.py index 2907c25..3fd6350 100644 --- a/zerorpc/cli.py +++ b/zerorpc/cli.py @@ -33,11 +33,17 @@ import inspect import os import logging -import collections from pprint import pprint import zerorpc +try: + # Try collections.abc for 3.4+ + from collections.abc import Iterator +except ImportError: + # Fallback to collections for Python 2 + from collections import Iterator + parser = argparse.ArgumentParser( description='Make a zerorpc call to a remote service.' @@ -267,7 +273,7 @@ def run_client(args): else: call_args = args.params results = client(args.command, *call_args) - if not isinstance(results, collections.Iterator): + if not isinstance(results, Iterator): if args.print_json: json.dump(results, sys.stdout) else: diff --git a/zerorpc/core.py b/zerorpc/core.py index 9fa63e3..ec2e008 100644 --- a/zerorpc/core.py +++ b/zerorpc/core.py @@ -266,7 +266,10 @@ def __call__(self, method, *args, **kargs): self._context.hook_client_before_request(request_event) bufchan.emit_event(request_event) - if kargs.get('async', False) is False: + # In python 3.7, "async" is a reserved keyword, clients should now use + # "async_": support both for the time being + if (kargs.get('async', False) is False and + kargs.get('async_', False) is False): return self._process_response(request_event, bufchan, timeout) async_result = gevent.event.AsyncResult() @@ -403,7 +406,7 @@ def fork_task_context(functor, context=None): - task1 is created to handle this event this task will be linked to the initial event context. zerorpc.Server does that for you. - task1 make use of some zerorpc.Client instances, the initial - event context is transfered on every call. + event context is transferred on every call. - task1 spawn a new task2. - task2 make use of some zerorpc.Client instances, it's a fresh @@ -412,7 +415,7 @@ def fork_task_context(functor, context=None): - task1 spawn a new fork_task_context(task3). - task3 make use of some zerorpc.Client instances, the initial - event context is transfered on every call. + event context is transferred on every call. A real use case is a distributed tracer. Each time a new event is created, a trace_id is injected in it or copied from the current task diff --git a/zerorpc/gevent_zmq.py b/zerorpc/gevent_zmq.py index 9430695..54420ae 100644 --- a/zerorpc/gevent_zmq.py +++ b/zerorpc/gevent_zmq.py @@ -27,6 +27,13 @@ # We want to act like zmq from zmq import * # noqa +try: + # Try to import enums for pyzmq >= 23.0.0 + from zmq.constants import * # noqa +except ImportError: + pass + + # Explicit import to please flake8 from zmq import ZMQError