computationalmodelling / nbval

A py.test plugin to validate Jupyter notebooks
Other
438 stars 50 forks source link

nbval and cov do not play nicely together #116

Open hameerabbasi opened 5 years ago

hameerabbasi commented 5 years ago

Steps to reproduce:

  1. Clone uarray: https://github.com/Quansight-Labs/uarray
  2. Create a conda env from .conda/environment.yml
  3. Install nbval
  4. Comment out the addopts line in pytest.ini
  5. Run pytest --cov --nbval .

Actual output

nbval stalls, then errors with a timeout error.

Expected output

nbval should test the notebooks without a timeout.

OS/environment:

macOS 10.14

conda list

``` # packages in environment at /Users/hameerabbasi/anaconda/envs/uarray: # # Name Version Build Channel alabaster 0.7.12 py37_0 appdirs 1.4.3 py37h28b3542_0 appnope 0.1.0 py37_0 asn1crypto 0.24.0 py37_0 atomicwrites 1.3.0 py37_1 attrs 19.1.0 py37_1 autopep8 1.4.3 py37_0 babel 2.6.0 py37_0 backcall 0.1.0 py37_0 blas 1.0 mkl bleach 3.1.0 py37_0 ca-certificates 2019.1.23 0 certifi 2019.3.9 py37_0 cffi 1.12.2 py37hb5b8e2f_1 chardet 3.0.4 py37_1 click 7.0 py37_0 coverage 4.5.3 py37h1de35cc_0 cryptography 2.6.1 py37ha12b0ac_0 decorator 4.4.0 py37_1 defusedxml 0.5.0 py37_1 doc8 0.8.0 py_1 conda-forge docutils 0.14 py37_0 entrypoints 0.3 py37_0 flake8 3.7.7 py37_0 gumath 0.2.0dev3 py37_243_gd686a36 xnd/label/dev idna 2.8 py37_0 imagesize 1.1.0 py37_0 intel-openmp 2019.3 199 ipykernel 5.1.0 py37h39e3cac_0 ipython 7.4.0 py37h39e3cac_0 ipython_genutils 0.2.0 py37_0 jedi 0.13.3 py37_0 jinja2 2.10 py37_0 jsonschema 3.0.1 py37_0 jupyter_client 5.2.4 py37_0 jupyter_core 4.4.0 py37_0 jupyterlab 0.35.4 py37hf63ae98_0 jupyterlab_server 0.2.0 py37_0 libcxx 4.0.1 hcfea43d_1 libcxxabi 4.0.1 hcfea43d_1 libedit 3.1.20181209 hb402a30_0 libffi 3.2.1 h475c297_4 libgfortran 3.0.1 h93005f0_2 libgumath 0.2.0dev3 py37_243_gd686a36 xnd/label/dev libndtypes 0.2.0dev3 py37_228_gcb364d0 xnd/label/dev libsodium 1.0.16 h3efe00b_0 libxnd 0.2.0dev3 py37_229_g5fdc53b xnd/label/dev markupsafe 1.1.1 py37h1de35cc_0 mccabe 0.6.1 py37_1 mistune 0.8.4 py37h1de35cc_0 mkl 2019.3 199 mkl_fft 1.0.10 py37h5e564d8_0 mkl_random 1.0.2 py37h27c97d8_0 more-itertools 6.0.0 py37_0 mypy 0.670 py_0 mypy-extensions 0.4.1 pypi_0 pypi mypy_extensions 0.4.1 py37_0 nbconvert 5.4.1 py37_3 nbformat 4.4.0 py37_0 nbval 0.9.1 py_0 conda-forge ncurses 6.1 h0a44026_1 ndtypes 0.2.0dev3 py37_228_gcb364d0 xnd/label/dev ninja 1.9.0 py37h04f5b5a_0 notebook 5.7.8 py37_0 numpy 1.16.2 py37hacdab7b_0 numpy-base 1.16.2 py37h6575580_0 openssl 1.1.1b h1de35cc_1 packaging 19.0 py37_0 pandoc 2.2.3.2 0 pandocfilters 1.4.2 py37_1 parso 0.3.4 py37_0 pbr 5.1.3 py_0 pexpect 4.6.0 py37_0 pickleshare 0.7.5 py37_0 pip 19.0.3 py37_0 pluggy 0.9.0 py37_0 prometheus_client 0.6.0 py37_0 prompt_toolkit 2.0.9 py37_0 psutil 5.4.8 py37h1de35cc_0 ptyprocess 0.6.0 py37_0 py 1.8.0 py37_0 pycodestyle 2.5.0 py37_0 pycparser 2.19 py37_0 pyflakes 2.1.1 py37_0 pygments 2.3.1 py37_0 pyopenssl 19.0.0 py37_0 pyparsing 2.3.1 py37_0 pyrsistent 0.14.11 py37h1de35cc_0 pysocks 1.6.8 py37_0 pytest 4.3.1 py37_0 pytest-cov 2.6.1 py37_0 pytest-flake8 1.0.4 py37_0 conda-forge pytest-mypy 0.3.2 pypi_0 pypi python 3.7.3 h359304d_0 python-dateutil 2.8.0 py37_0 pytorch-cpu 1.0.1 py37h0a44026_0 conda-forge pytz 2018.9 py37_0 pyzmq 18.0.0 py37h0a44026_0 readline 7.0 h1de35cc_5 requests 2.21.0 py37_0 restructuredtext_lint 1.3.0 py_0 conda-forge rope 0.12.0 py37_0 scipy 1.2.1 py37h1410ff5_0 send2trash 1.5.0 py37_0 setuptools 40.8.0 py37_0 six 1.12.0 py37_0 snowballstemmer 1.2.1 py37_0 sphinx 1.8.5 py37_0 sphinx_rtd_theme 0.4.3 py_0 sphinxcontrib 1.0 py37_1 sphinxcontrib-websupport 1.1.0 py37_1 sqlite 3.27.2 ha441bb4_0 stevedore 1.30.1 py_0 conda-forge terminado 0.8.1 py37_1 testpath 0.4.2 py37_0 tk 8.6.8 ha441bb4_0 toml 0.10.0 py37h28b3542_0 tornado 6.0.2 py37h1de35cc_0 traitlets 4.3.2 py37_0 typed-ast 1.3.1 pypi_0 pypi typing 3.6.4 py37_0 uarray 0.4+205.g2e0e01a.dirty dev_0 urllib3 1.24.1 py37_0 wcwidth 0.1.7 py37_0 webencodings 0.5.1 py37_1 wheel 0.33.1 py37_0 xnd 0.2.0dev3 py37_229_g5fdc53b xnd/label/dev xz 5.2.4 h1de35cc_4 zeromq 4.3.1 h0a44026_3 zlib 1.2.11 h1de35cc_3 ```

hameerabbasi commented 5 years ago
Full output:

```bash ============================= test session starts ============================== platform darwin -- Python 3.7.3, pytest-4.3.1, py-1.8.0, pluggy-0.9.0 rootdir: /Users/hameerabbasi/Quansight/uarray, inifile: pytest.ini plugins: mypy-0.3.2, flake8-1.0.4, cov-2.6.1, nbval-0.9.1 collected 69 items notebooks/01_user_facing.ipynb EEEEEE [ 8%] notebooks/02_basic_dev_tutorial.ipynb ^C ==================================== ERRORS ==================================== ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 0 ___________ cls = func = . at 0x7fd2e97fee18> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 1 ___________ cls = func = . at 0x7fd2fb1b79d8> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:394: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) ../../anaconda/envs/uarray/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 2 ___________ cls = func = . at 0x7fd2fb18f400> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:394: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) ../../anaconda/envs/uarray/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 3 ___________ cls = func = . at 0x7fd2f947d8c8> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:394: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) ../../anaconda/envs/uarray/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 4 ___________ cls = func = . at 0x7fd318653f28> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:394: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) ../../anaconda/envs/uarray/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ___________ ERROR at setup of notebooks/01_user_facing.ipynb::Cell 5 ___________ cls = func = . at 0x7fd2e9815400> when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:226: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:198: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7fd2f801fc18> hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [>, >, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [>, >, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) ../../anaconda/envs/uarray/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:394: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) ../../anaconda/envs/uarray/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x7fd2f807a438> colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() ../../anaconda/envs/uarray/lib/python3.7/site-packages/_pytest/runner.py:398: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x7fd2f868c470> kernel = floc = local('/Users/hameerabbasi/Quansight/uarray/notebooks/01_user_facing.ipynb') output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = parent_id = 'bd9664d3-cf832aedeafd439954386d8b', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub' timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) ../../anaconda/envs/uarray/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty ../../anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty =============================== warnings summary =============================== notebooks/01_user_facing.ipynb::Cell 0 /Users/hameerabbasi/anaconda/envs/uarray/lib/python3.7/site-packages/jupyter_client/manager.py:62: DeprecationWarning: KernelManager._kernel_spec_manager_changed is deprecated in traitlets 4.1: use @observe and @unobserve instead. def _kernel_spec_manager_changed(self): -- Docs: https://docs.pytest.org/en/latest/warnings.html ---------- coverage: platform darwin, python 3.7.3-final-0 ----------- Name Stmts Miss Branch BrPart Cover ---------------------------------------------------------------- uarray/__init__.py 5 0 0 0 100% uarray/backend.py 179 95 54 4 38% uarray/tests/test_backend.py 37 25 0 0 32% ---------------------------------------------------------------- TOTAL 221 120 54 4 38% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! KeyboardInterrupt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! zmq/backend/cython/checkrc.pxd:12: KeyboardInterrupt (to show a full traceback on KeyboardInterrupt use --fulltrace) ===================== 1 warnings, 6 error in 64.87 seconds ===================== ```

saulshanabrook commented 5 years ago

I am getting this same error as well. I tried downgrading notebook from 5.7.8 to 5.7.0 to see if that would help, but to no avail...

vidartf commented 5 years ago

@saulshanabrook Are you getting the same error with the same notebooks, or with different ones?

saulshanabrook commented 5 years ago

@vidartf Different notebooks. In https://github.com/quansight-labs/metadsl

vidartf commented 5 years ago

Are either one of you able to produce a minimal working example? Its hard to debug behavior in a completely unknown repository.

saulshanabrook commented 5 years ago

I was able to reproduce this in an minimal conda environment created like this:

conda create -n tmp -c conda-forge jupyterlab
conda activate tmp
pip install pytest pytest-cov nbval
# Create notebook file `Untitled.ipynb`
pytest --cov --nbval Untitled.ipynb
Output: ```python ========================================================= test session starts ========================================================= platform darwin -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0 rootdir: /Users/saul/p/tmp plugins: cov-2.7.1, nbval-0.9.1 collected 2 items Untitled.ipynb EE [100%]Coverage.py warning: No data was collected. (no-data-collected) WARNING: Failed to generate report: No data to report. /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pytest_cov/plugin.py:229: PytestWarning: Failed to generate report: No data to report. self.cov_controller.finish() =============================================================== ERRORS ================================================================ ______________________________________________ ERROR at setup of Untitled.ipynb::Cell 0 _______________________________________________ cls = , func = . at 0x10a1ed730>, when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = (), kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x106ab4128>, hook = <_HookCaller 'pytest_runtest_setup'> methods = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x10a1e8f28>, colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:361: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x10794a0f0>, kernel = floc = local('/Users/saul/p/tmp/Untitled.ipynb'), output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , parent_id = '38a50b57-0eb629018ade829489b5c38f', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub', timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ______________________________________________ ERROR at setup of Untitled.ipynb::Cell 1 _______________________________________________ cls = , func = . at 0x10a21ba60>, when = 'setup' reraise = (, ) @classmethod def from_call(cls, func, when, reraise=None): #: context of invocation: one of "setup", "call", #: "teardown", "memocollect" start = time() excinfo = None try: > result = func() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: ihook(item=item, **kwds), when=when, reraise=reraise ) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_HookCaller 'pytest_runtest_setup'>, args = (), kwargs = {'item': }, notincall = set() def __call__(self, *args, **kwargs): if args: raise TypeError("hook calling supports only keyword arguments") assert not self.is_historic() if self.spec and self.spec.argnames: notincall = ( set(self.spec.argnames) - set(["__multicall__"]) - set(kwargs.keys()) ) if notincall: warnings.warn( "Argument(s) {} which are declared in the hookspec " "can not be found in this hook call".format(tuple(notincall)), stacklevel=2, ) > return self._hookexec(self, self.get_hookimpls(), kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/hooks.py:289: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x106ab4128>, hook = <_HookCaller 'pytest_runtest_setup'> methods = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] kwargs = {'item': } def _hookexec(self, hook, methods, kwargs): # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook, methods, kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/manager.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook = <_HookCaller 'pytest_runtest_setup'> methods = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] kwargs = {'item': } self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, > firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, ) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/manager.py:62: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException: excinfo = sys.exc_info() finally: if firstresult: # first result hooks return a single value outcome = _Result(results[0] if results else None, excinfo) else: outcome = _Result(results, excinfo) # run all wrapper post-yield blocks for gen in reversed(teardowns): try: gen.send(outcome) _raise_wrapfail(gen, "has second yield") except StopIteration: pass > return outcome.get_result() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:208: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def get_result(self): """Get the result(s) for this hook call. If the hook was marked as a ``firstresult`` only a single value will be returned otherwise a list of results. """ __tracebackhide__ = True if self._excinfo is None: return self._result else: ex = self._excinfo if _py3: > raise ex[1].with_traceback(ex[2]) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:80: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_impls = [ _state='suspended' _in_suspended=''> _current_item=>>, ...] caller_kwargs = {'item': }, firstresult = False def _multicall(hook_impls, caller_kwargs, firstresult=False): """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from _HookCaller.__call__(). """ __tracebackhide__ = True results = [] excinfo = None try: # run impl and wrapper setup functions in a loop teardowns = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError: for argname in hook_impl.argnames: if argname not in caller_kwargs: raise HookCallError( "hook call must provide argument %r" % (argname,) ) if hook_impl.hookwrapper: try: gen = hook_impl.function(*args) next(gen) # first yield teardowns.append(gen) except StopIteration: _raise_wrapfail(gen, "did not yield") else: > res = hook_impl.function(*args) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/pluggy/callers.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_setup(item): _update_current_test_var(item, "setup") > item.session._setupstate.prepare(item) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x10a1e8f28>, colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): > six.reraise(*col._prepare_exc) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:357: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tp = , value = None, tb = None def reraise(tp, value, tb=None): try: if value is None: value = tp() if value.__traceback__ is not tb: > raise value.with_traceback(tb) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/six.py:692: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.runner.SetupState object at 0x10a1e8f28>, colitem = def prepare(self, colitem): """ setup objects along the collector chain to the test-method and teardown previously setup objects.""" needed_collectors = colitem.listchain() self._teardown_towards(needed_collectors) # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: > col.setup() /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/_pytest/runner.py:361: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def setup(self): """ Called by pytest to setup the collector cells in . Here we start a kernel and setup the sanitize patterns. """ if self.parent.config.option.current_env: kernel_name = CURRENT_ENV_KERNEL_NAME else: kernel_name = self.nb.metadata.get( 'kernelspec', {}).get('name', 'python') self.kernel = RunningKernel(kernel_name, str(self.fspath.dirname)) self.setup_sanitize_files() if getattr(self.parent.config.option, 'cov_source', None): > setup_coverage(self.parent.config, self.kernel, getattr(self, "fspath", None)) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/plugin.py:235: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ config = <_pytest.config.Config object at 0x10794a0f0>, kernel = floc = local('/Users/saul/p/tmp/Untitled.ipynb'), output_loc = None def setup_coverage(config, kernel, floc, output_loc=None): """Start coverage reporting in kernel. Currently supported kernel languages are: - Python """ language = kernel.language if language.startswith('python'): # Get the pytest-cov coverage object cov = get_cov(config) if cov: # If present, copy the data file location used by pytest-cov data_file = os.path.abspath(cov.config.data_file) else: # Fall back on output_loc and current dir if not data_file = os.path.abspath(os.path.join(output_loc or os.getcwd(), '.coverage')) # Get options from pytest-cov's command line arguments: source = config.option.cov_source config_file = config.option.cov_config if isinstance(config_file, str) and os.path.isfile(config_file): config_file = os.path.abspath(config_file) # Copy the suffix of plugin if available suffix = _make_suffix(cov) if suffix is True: # Cannot merge data with autogen suffix, so turn off warning # for missing data in pytest-cov collector cov._warn_no_data = False # Build setup command and execute in kernel: cmd = _python_setup % (data_file, source, config_file, suffix) msg_id = kernel.kc.execute(cmd, stop_on_error=False) > kernel.await_idle(msg_id, 60) # A minute should be plenty to enable coverage /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/cover.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , parent_id = '38a50b57-0eb629018ade829489b5c38f', timeout = 60 def await_idle(self, parent_id, timeout): """Poll the iopub stream until an idle message is received for the given parent ID""" while True: # Get a message from the kernel iopub channel > msg = self.get_message(timeout=timeout, stream='iopub') # raises Empty on timeout! /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/kernel.py:170: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , stream = 'iopub', timeout = 60 def get_message(self, stream, timeout=None): """ Function is used to get a message from the iopub channel. Timeout is None by default When timeout is reached """ try: if stream == 'iopub': > msg = self.kc.get_iopub_msg(timeout=timeout) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/nbval/kernel.py:123: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , args = (), kwargs = {'timeout': 60} def get_iopub_msg(self, *args, **kwargs): """Get a message from the iopub channel""" > return self.iopub_channel.get_msg(*args, **kwargs) /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/jupyter_client/client.py:81: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , block = True, timeout = 60000 def get_msg(self, block=True, timeout=None): """ Gets a message if there is one that is ready. """ if block: if timeout is not None: timeout *= 1000 # seconds to ms ready = self.socket.poll(timeout) else: ready = self.socket.poll(timeout=0) if ready: return self._recv() else: > raise Empty E _queue.Empty /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/jupyter_client/blocking/channels.py:57: Empty ========================================================== warnings summary =========================================================== Untitled.ipynb::Cell 0 /usr/local/miniconda3/envs/tmp/lib/python3.7/site-packages/jupyter_client/manager.py:62: DeprecationWarning: KernelManager._kernel_spec_manager_changed is deprecated in traitlets 4.1: use @observe and @unobserve instead. def _kernel_spec_manager_changed(self): -- Docs: https://docs.pytest.org/en/latest/warnings.html ---------- coverage: platform darwin, python 3.7.3-final-0 ----------- Name Stmts Miss Cover --------------------------- ================================================ 1 warnings, 2 error in 62.50 seconds ================================================= ```
Environment: ```bash $ pip freeze appnope==0.1.0 atomicwrites==1.3.0 attrs==19.1.0 backcall==0.1.0 bleach==3.1.0 certifi==2019.3.9 coverage==4.5.3 decorator==4.4.0 defusedxml==0.5.0 entrypoints==0.3 flake8==3.6.0 ipykernel==5.1.0 ipython==7.5.0 ipython-genutils==0.2.0 jedi==0.13.3 Jinja2==2.10.1 jsonschema==3.0.1 jupyter-client==5.2.4 jupyter-core==4.4.0 jupyterlab==0.35.6 jupyterlab-server==0.2.0 MarkupSafe==1.1.1 mccabe==0.6.1 mistune==0.8.4 more-itertools==7.0.0 mypy-extensions==0.4.1 nbconvert==5.5.0 nbformat==4.4.0 nbval==0.9.1 notebook==5.7.8 pandocfilters==1.4.2 parso==0.4.0 pexpect==4.7.0 pickleshare==0.7.5 pluggy==0.11.0 prometheus-client==0.6.0 prompt-toolkit==2.0.9 ptyprocess==0.6.0 py==1.8.0 pycodestyle==2.4.0 pyflakes==2.0.0 Pygments==2.4.0 pyrsistent==0.15.2 pytest==4.5.0 pytest-cov==2.7.1 python-dateutil==2.8.0 pyzmq==18.0.1 Send2Trash==1.5.0 six==1.12.0 terminado==0.8.2 testpath==0.4.2 tornado==6.0.2 traitlets==4.3.2 wcwidth==0.1.7 webencodings==0.5.1 $ conda info active environment : tmp active env location : /usr/local/miniconda3/envs/tmp shell level : 1 user config file : /Users/saul/.condarc populated config files : conda version : 4.6.12 conda-build version : not installed python version : 3.6.8.final.0 base environment : /usr/local/miniconda3 (writable) channel URLs : https://repo.anaconda.com/pkgs/main/osx-64 https://repo.anaconda.com/pkgs/main/noarch https://repo.anaconda.com/pkgs/free/osx-64 https://repo.anaconda.com/pkgs/free/noarch https://repo.anaconda.com/pkgs/r/osx-64 https://repo.anaconda.com/pkgs/r/noarch package cache : /usr/local/miniconda3/pkgs /Users/saul/.conda/pkgs envs directories : /usr/local/miniconda3/envs /Users/saul/.conda/envs platform : osx-64 user-agent : conda/4.6.12 requests/2.18.4 CPython/3.6.8 Darwin/17.7.0 OSX/10.13.6 UID:GID : 501:20 netrc file : /Users/saul/.netrc offline mode : False $ cat Untitled.ipynb { "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 } ```
vidartf commented 5 years ago

Weird, I cannot reproduce. Diff from pip freeze:

- appnope==0.1.0
+colorama==0.4.1
- mccabe==0.6.1
- mypy-extensions==0.4.1
- pexpect==4.7.0
- ptyprocess==0.6.0
- pycodestyle==2.4.0
- pyflakes==2.0.0
+wincertstore==0.2

The package diff is mostly platform-based (I assume). Speaking of platform, I see that both of you are on OSX. Are you able to reproduce this on other platforms? I'm running on Windows here.

NikZak commented 4 years ago

Anyone solved this issue yet or maybe found a workaround?

casperdcl commented 3 years ago

Specifying a module to cover means it won't hang, but also it won't actually pick up coverage:

pytest --cov=mymod --cov-report=term --nbval tests/test_mymod.ipynb
...
tests/test_mymod::ipynb::Cell 0 PASSED
Coverage.py warning: Module mymod was never imported. (module-not-imported)
Coverage.py warning: No data was collected. (no-data-collected)
WARNING: Failed to generate report: No data to report.
PytestWarning: Failed to generate report: No data to report.
...

EDIT: this seems to be because nbval can't handle when test_mymod.ipynb is in a different directory from mymod (i.e. a workaround is mv tests/test_mymod.ipynb ./)

Note that with normal python files (*.py) coverage is picked up fine by comparison.