Index: pytest-shutil-1.8.0/pytest_shutil/cmdline.py =================================================================== --- pytest-shutil-1.8.0.orig/pytest_shutil/cmdline.py +++ pytest-shutil-1.8.0/pytest_shutil/cmdline.py @@ -10,12 +10,6 @@ from contextlib import contextmanager from tempfile import mkdtemp -try: # Python 2 - str_type = basestring -except NameError: # Python 3 - str_type = str - - def get_log(): return logging.getLogger(__name__) Index: pytest-shutil-1.8.0/pytest_shutil/run.py =================================================================== --- pytest-shutil-1.8.0.orig/pytest_shutil/run.py +++ pytest-shutil-1.8.0/pytest_shutil/run.py @@ -3,36 +3,20 @@ """ import sys import os +import pickle import importlib.util import logging from functools import update_wrapper import inspect import textwrap -from contextlib import closing +from contextlib import closing, ExitStack import subprocess - -try: - from unittest.mock import patch -except ImportError: - # python 2 - from mock import patch +from unittest.mock import patch import execnet -from six.moves import cPickle # @UnresolvedImport from . import cmdline -try: - # Python 3 - from contextlib import ExitStack -except ImportError: - from contextlib2 import ExitStack - -try: # Python 2 - str_type = basestring -except NameError: # Python 3 - str_type = str - log = logging.getLogger(__name__) @@ -68,7 +52,7 @@ def run(cmd, stdin=None, capture_stdout= (out, _) = p.communicate(stdin) - if out is not None and not isinstance(out, str_type): + if out is not None and not isinstance(out, str): try: out = out.decode('utf-8') except: @@ -143,22 +127,20 @@ def _make_pickleable(fn): # return a pickleable function followed by a tuple of initial arguments # could use partial but this is more efficient try: - cPickle.dumps(fn, protocol=0) - except (TypeError, cPickle.PickleError, AttributeError): + pickle.dumps(fn, protocol=0) + except (TypeError, pickle.PickleError, AttributeError): pass else: return fn, () if inspect.ismethod(fn): name, self_ = fn.__name__, fn.__self__ - if self_ is None: # Python 2 unbound method - self_ = fn.im_class return _invoke_method, (self_, name) elif inspect.isfunction(fn) and fn.__module__ in sys.modules: cls, name = _find_class_from_staticmethod(fn) if (cls, name) != (None, None): try: - cPickle.dumps((cls, name), protocol=0) - except cPickle.PicklingError: + pickle.dumps((cls, name), protocol=0) + except pickle.PicklingError: pass else: return _invoke_method, (cls, name) @@ -176,9 +158,9 @@ def _run_in_subprocess_redirect_stdout(f def _run_in_subprocess_remote_fn(channel): - from six.moves import cPickle # @UnresolvedImport @Reimport # NOQA - fn, args, kwargs = cPickle.loads(channel.receive(None)) - channel.send(cPickle.dumps(fn(*args, **kwargs), protocol=0)) + import pickle + fn, args, kwargs = pickle.loads(channel.receive(None)) + channel.send(pickle.dumps(fn(*args, **kwargs), protocol=0)) def run_in_subprocess(fn, python=sys.executable, cd=None, timeout=None): @@ -204,12 +186,12 @@ def run_in_subprocess(fn, python=sys.exe stack.callback(gw.exit) if fix_stdout: with closing(gw.remote_exec(_run_in_subprocess_remote_fn)) as chan: - chan.send(cPickle.dumps((_run_in_subprocess_redirect_stdout, (fd,), {}), protocol=0)) + chan.send(pickle.dumps((_run_in_subprocess_redirect_stdout, (fd,), {}), protocol=0)) chan.receive(None) with closing(gw.remote_exec(_run_in_subprocess_remote_fn)) as chan: payload = (pkl_fn, tuple(i for t in (preargs, args) for i in t), kwargs) - chan.send(cPickle.dumps(payload, protocol=0)) - return cPickle.loads(chan.receive(timeout)) + chan.send(pickle.dumps(payload, protocol=0)) + return pickle.loads(chan.receive(timeout)) return inner if isinstance(fn, str) else update_wrapper(inner, fn) Index: pytest-shutil-1.8.0/pytest_shutil/workspace.py =================================================================== --- pytest-shutil-1.8.0.orig/pytest_shutil/workspace.py +++ pytest-shutil-1.8.0/pytest_shutil/workspace.py @@ -1,6 +1,5 @@ """ Temporary directory fixtures """ -from __future__ import absolute_import import os import tempfile import shutil Index: pytest-shutil-1.8.0/setup.py =================================================================== --- pytest-shutil-1.8.0.orig/setup.py +++ pytest-shutil-1.8.0/setup.py @@ -17,7 +17,7 @@ classifiers = [ 'Programming Language :: Python :: 3.7', ] -install_requires = ['six', +install_requires = [ 'execnet', 'pytest', 'termcolor' Index: pytest-shutil-1.8.0/tests/integration/test_run_integration.py =================================================================== --- pytest-shutil-1.8.0.orig/tests/integration/test_run_integration.py +++ pytest-shutil-1.8.0/tests/integration/test_run_integration.py @@ -6,13 +6,9 @@ import pytest import execnet import inspect import textwrap +from unittest import mock from uuid import uuid4 -try: - from unittest import mock -except ImportError: - import mock - from pytest_shutil import run, workspace from pytest_shutil.env import no_cov Index: pytest-shutil-1.8.0/tests/unit/test_run.py =================================================================== --- pytest-shutil-1.8.0.orig/tests/unit/test_run.py +++ pytest-shutil-1.8.0/tests/unit/test_run.py @@ -1,17 +1,11 @@ +import pickle import sys from uuid import uuid4 from subprocess import PIPE, STDOUT +from unittest.mock import Mock, patch, sentinel, DEFAULT, call import pytest -try: - from unittest.mock import Mock, patch, sentinel, DEFAULT, call -except ImportError: - # python 2 - from mock import Mock, patch, sentinel, DEFAULT, call - -from six.moves import cPickle - from pytest_shutil import run ARG = str(uuid4()) @@ -50,41 +44,41 @@ def test_run_as_main(): def test_run_in_subprocess(): - with patch.multiple('pytest_shutil.run', cPickle=DEFAULT, execnet=DEFAULT) as mocks: + with patch.multiple('pytest_shutil.run', pickle=DEFAULT, execnet=DEFAULT) as mocks: fn = Mock(__name__='fn') res = run.run_in_subprocess(fn, python='sentinel.python')(sentinel.arg, kw=sentinel.kw) mocks['execnet'].makegateway.assert_called_once_with('popen//python=sentinel.python') gw = mocks['execnet'].makegateway.return_value ((remote_fn,), _) = gw.remote_exec.call_args chan = gw.remote_exec.return_value - mocks['cPickle'].dumps.assert_called_with((fn, (sentinel.arg,), {'kw': sentinel.kw}), protocol=0) - chan.send.assert_called_with(mocks['cPickle'].dumps.return_value) + mocks['pickle'].dumps.assert_called_with((fn, (sentinel.arg,), {'kw': sentinel.kw}), protocol=0) + chan.send.assert_called_with(mocks['pickle'].dumps.return_value) chan.receive.assert_has_calls([call(None) for _i in range(gw.remote_exec.call_count)]) - mocks['cPickle'].loads.assert_called_once_with(chan.receive.return_value) - assert res is mocks['cPickle'].loads.return_value + mocks['pickle'].loads.assert_called_once_with(chan.receive.return_value) + assert res is mocks['pickle'].loads.return_value chan.close.assert_has_calls([call() for _i in range(gw.remote_exec.call_count)]) gw.exit.assert_called_once_with() - with patch('six.moves.cPickle') as cPickle: + with patch('pickle.loads') as loads, patch('pickle.dumps') as dumps: channel, fn = Mock(), Mock() - cPickle.loads.return_value = (fn, (sentinel.arg,), {'kw': sentinel.kw}) + loads.return_value = (fn, (sentinel.arg,), {'kw': sentinel.kw}) remote_fn(channel) channel.receive.assert_called_once_with(None) - cPickle.loads.assert_called_once_with(channel.receive.return_value) + loads.assert_called_once_with(channel.receive.return_value) fn.assert_called_once_with(sentinel.arg, kw=sentinel.kw) - cPickle.dumps.assert_called_once_with(fn.return_value, protocol=0) - channel.send.assert_called_once_with(cPickle.dumps.return_value) + dumps.assert_called_once_with(fn.return_value, protocol=0) + channel.send.assert_called_once_with(dumps.return_value) def test_run_in_runcd(): - with patch.multiple('pytest_shutil.run', cPickle=DEFAULT, execnet=DEFAULT) as mocks: + with patch.multiple('pytest_shutil.run', pickle=DEFAULT, execnet=DEFAULT) as mocks: run.run_in_subprocess(Mock(__name__='fn'), python='sentinel.python', cd='sentinel.cd')(sentinel.arg, kw=sentinel.kw) mocks['execnet'].makegateway.assert_called_once_with('popen//python=sentinel.python//chdir=sentinel.cd') def test_run_in_runtimeout(): - with patch.multiple('pytest_shutil.run', cPickle=DEFAULT, execnet=DEFAULT) as mocks: + with patch.multiple('pytest_shutil.run', pickle=DEFAULT, execnet=DEFAULT) as mocks: run.run_in_subprocess(Mock(__name__='fn'), python='sentinel.python', timeout=sentinel.timeout)(sentinel.arg, kw=sentinel.kw) gw = mocks['execnet'].makegateway.return_value @@ -100,15 +94,15 @@ def test_run_in_runpickleable_function() with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) with patch.object(run, fn.__name__, fn, create=True): run.run_in_subprocess(fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (fn, (ARG,), {'kw': KW}) + assert pickle.loads(s) == (fn, (ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps(((ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps(((ARG,), {'kw': KW}), protocol=0)) def test_run_in_runstr(): @@ -118,14 +112,14 @@ def test_run_in_runstr(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) run.run_in_subprocess(source, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) + assert pickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps(((ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps(((ARG,), {'kw': KW}), protocol=0)) def test_run_in_runnested_function(): @@ -137,14 +131,14 @@ def test_run_in_runnested_function(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) run.run_in_subprocess(fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) + assert pickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps(((ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps(((ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -157,23 +151,18 @@ def test_run_in_runbound_method(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) c = C() with patch.object(run, C.__name__, C, create=True): run.run_in_subprocess(c.fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - if sys.version_info < (3, 0, 0): - # Bound methods are not pickleable in Python 2. - assert cPickle.loads(s) == (run._invoke_method, (c, 'fn', ARG,), {'kw': KW}) - else: - # Bound methods are pickleable in Python 3. - assert cPickle.loads(s) == (c.fn, (ARG,), {'kw': KW}) + assert pickle.loads(s) == (c.fn, (ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps((c, (ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps((c, (ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -182,7 +171,7 @@ def test_run_in_runbound_method_on_unpic def fn(self, *args, **kwargs): return self, args, kwargs with patch('pytest_shutil.run.execnet'): - with pytest.raises(cPickle.PicklingError): + with pytest.raises(pickle.PicklingError): run.run_in_subprocess(C().fn, python='sentinel.python')(ARG, kw=KW) @@ -196,16 +185,16 @@ def test_run_in_rununbound_method(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) c = C() with patch.object(run, C.__name__, C, create=True): run.run_in_subprocess(C.fn, python='sentinel.python')(c, ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (run._invoke_method, (C, 'fn', c, ARG,), {'kw': KW}) + assert pickle.loads(s) == (run._invoke_method, (C, 'fn', c, ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps((c, (ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps((c, (ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -214,7 +203,7 @@ def test_run_in_rununbound_method_on_unp def fn(self, *args, **kwargs): return self, args, kwargs with patch('pytest_shutil.run.execnet'): - with pytest.raises(cPickle.PicklingError): + with pytest.raises(pickle.PicklingError): run.run_in_subprocess(C.fn, python='sentinel.python')(C(), ARG, kw=KW) @@ -229,15 +218,15 @@ def test_run_in_runstaticmethod(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) with patch.object(run, C.__name__, C, create=True): run.run_in_subprocess(C.fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (run._invoke_method, (C, 'fn', ARG,), {'kw': KW}) + assert pickle.loads(s) == (run._invoke_method, (C, 'fn', ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps(((ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps(((ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -255,15 +244,15 @@ def fn(*args, **kwargs): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) with patch.object(run, C.__name__, C, create=True): run.run_in_subprocess(C.fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - assert cPickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) + assert pickle.loads(s) == (run._evaluate_fn_source, (source, ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps(((ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps(((ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -277,21 +266,16 @@ def test_run_in_runclassmethod(): with patch('pytest_shutil.run.execnet') as execnet: gw = execnet.makegateway.return_value chan = gw.remote_exec.return_value - chan.receive.return_value = cPickle.dumps(sentinel.ret) + chan.receive.return_value = pickle.dumps(sentinel.ret) c = C() with patch.object(run, C.__name__, C, create=True): run.run_in_subprocess(c.fn, python='sentinel.python')(ARG, kw=KW) ((s,), _) = chan.send.call_args - if sys.version_info < (3, 0, 0): - # Class methods are not pickleable in Python 2. - assert cPickle.loads(s) == (run._invoke_method, (C, 'fn', ARG), {'kw': KW}) - else: - # Class methods are pickleable in Python 3. - assert cPickle.loads(s) == (c.fn, (ARG,), {'kw': KW}) + assert pickle.loads(s) == (c.fn, (ARG,), {'kw': KW}) ((remote_fn,), _) = gw.remote_exec.call_args ((chan.receive.return_value,), _) = chan.send.call_args remote_fn(chan) - chan.send.assert_called_with(cPickle.dumps((C, (ARG,), {'kw': KW}), protocol=0)) + chan.send.assert_called_with(pickle.dumps((C, (ARG,), {'kw': KW}), protocol=0)) @pytest.mark.xfail(sys.version_info >= (3,5), reason="python3.5 api changes") @@ -301,5 +285,5 @@ def test_run_in_runclassmethod_on_unpick def fn(cls, *args, **kwargs): return cls, args, kwargs with patch('pytest_shutil.run.execnet'): - with pytest.raises(cPickle.PicklingError): + with pytest.raises(pickle.PicklingError): run.run_in_subprocess(C.fn, python='sentinel.python')(ARG, kw=KW)