nbval
nbval copied to clipboard
nbval cannot identify notebook kernel name
These 2 lines
from pytelescope import basetypes as bt
from astropy import units as u
import without errors in the notebook, but running nbval like so:
pytest --nbval test_basetypes.ipynb
throws this myriad of errors (below, in the "details" section), I guess something isn't installed properly?
Using nbval 0.9.1 from conda-forge and these pytest modules are installed:
$ conda list pytest (py37)
# packages in environment at /Users/klay6683/miniconda3/envs/py37:
#
# Name Version Build Channel
pytest 3.8.2 py37_1000 conda-forge
pytest-arraydiff 0.2 py_0 conda-forge
pytest-astropy 0.4.0 py_0 conda-forge
pytest-cache 1.0 py37_1
pytest-cov 2.6.0 py_0 conda-forge
pytest-doctestplus 0.1.3 py_0 conda-forge
pytest-openfiles 0.3.0 py_0 conda-forge
pytest-pep8 1.0.6 py_1 conda-forge
pytest-remotedata 0.3.0 py_0 conda-forge
on a macOS 10.13.6
test_basetypes.ipynb EE [100%]
==================================== ERRORS ==================================== _____________ ERROR at setup of tests/test_basetypes.ipynb::Cell 0 _____________
self = <CallInfo when='setup' exception: No such kernel named conda-env-py37-py>
func = <function call_runtest_hook.
def __init__(self, func, when, treat_keyboard_interrupt_as_exception=False):
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
self.when = when
self.start = time()
try:
self.result = func()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:201:
lambda: ihook(item=item, **kwds), when=when, treat_keyboard_interrupt_as_exception=item.config.getvalue("usepdb"), )
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:183:
self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': <IPyNbCell 'Cell 0'>}, notincall = set()
def __call__(self, *args, **kwargs):
if args:
raise TypeError("hook calling supports only keyword arguments")
assert not self.is_historic()
if self.argnames:
notincall = set(self.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._nonwrappers + self._wrappers, kwargs)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/hooks.py:258:
self = <_pytest.config.PytestPluginManager object at 0x1051379e8> hook = <_HookCaller 'pytest_runtest_setup'> methods = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] kwargs = {'item': <IPyNbCell 'Cell 0'>}
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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/manager.py:67:
hook = <_HookCaller 'pytest_runtest_setup'> methods = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] kwargs = {'item': <IPyNbCell 'Cell 0'>}
self._inner_hookexec = lambda hook, methods, kwargs: \
hook.multicall(
methods, kwargs,
firstresult=hook.spec_opts.get('firstresult'),
)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/manager.py:61:
hook_impls = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] caller_kwargs = {'item': <IPyNbCell 'Cell 0'>}, 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()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:201:
self = <pluggy.callers._Result object at 0x11354a080>
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])
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:76:
hook_impls = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] caller_kwargs = {'item': <IPyNbCell 'Cell 0'>}, 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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:180:
item = <IPyNbCell 'Cell 0'>
def pytest_runtest_setup(item):
_update_current_test_var(item, "setup")
item.session._setupstate.prepare(item)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:104:
self = <_pytest.runner.SetupState object at 0x112dcf0f0> colitem = <IPyNbCell 'Cell 0'>
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()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:370:
self = <IPyNbFile 'test_basetypes.ipynb'>
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))
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/plugin.py:232:
self = <nbval.kernel.RunningKernel object at 0x113978a20> kernel_name = 'conda-env-py37-py' cwd = '/Users/klay6683/Dropbox/src/pytelescope/tests'
def __init__(self, kernel_name, cwd=None):
"""
Initialise a new kernel
specify that matplotlib is inline and connect the stderr.
Stores the active kernel process and its manager.
"""
self.km, self.kc = start_new_kernel(
kernel_name=kernel_name,
stderr=open(os.devnull, 'w'),
cwd=cwd,
)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:88:
startup_timeout = 60, kernel_name = 'conda-env-py37-py' kwargs = {'cwd': '/Users/klay6683/Dropbox/src/pytelescope/tests', 'stderr': <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>} km = <jupyter_client.manager.KernelManager object at 0x1139789e8>
def start_new_kernel(startup_timeout=60, kernel_name='python', **kwargs):
"""Start a new kernel, and return its Manager and Client"""
logger.debug('Starting new kernel: "%s"' % kernel_name)
km = KernelManager(kernel_name=kernel_name,
kernel_spec_manager=NbvalKernelspecManager())
km.start_kernel(**kwargs)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:53:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8> kw = {'cwd': '/Users/klay6683/Dropbox/src/pytelescope/tests', 'stderr': <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>} extra_arguments = []
def start_kernel(self, **kw):
"""Starts a kernel on this host in a separate process.
If random ports (port=0) are being used, this method must be called
before the channels are created.
Parameters
----------
`**kw` : optional
keyword arguments that are passed down to build the kernel_cmd
and launching the kernel (e.g. Popen kwargs).
"""
if self.transport == 'tcp' and not is_local_ip(self.ip):
raise RuntimeError("Can only launch a kernel on a local interface. "
"This one is not: %s."
"Make sure that the '*_address' attributes are "
"configured properly. "
"Currently valid addresses are: %s" % (self.ip, local_ips())
)
# write connection file / get default ports
self.write_connection_file()
# save kwargs for use in restart
self._launch_args = kw.copy()
# build the Popen cmd
extra_arguments = kw.pop('extra_arguments', [])
kernel_cmd = self.format_kernel_cmd(extra_arguments=extra_arguments)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:246:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8> extra_arguments = []
def format_kernel_cmd(self, extra_arguments=None):
"""replace templated args (e.g. {connection_file})"""
extra_arguments = extra_arguments or []
if self.kernel_cmd:
cmd = self.kernel_cmd + extra_arguments
else:
cmd = self.kernel_spec.argv + extra_arguments
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:170:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8>
@property
def kernel_spec(self):
if self._kernel_spec is None and self.kernel_name is not '':
self._kernel_spec = self.kernel_spec_manager.get_kernel_spec(self.kernel_name)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:82:
self = <nbval.kernel.NbvalKernelspecManager object at 0x113978828> kernel_name = 'conda-env-py37-py'
def get_kernel_spec(self, kernel_name):
"""Returns a :class:`KernelSpec` instance for the given kernel_name.
Raises :exc:`NoSuchKernel` if the given kernel name is not found.
"""
if kernel_name == CURRENT_ENV_KERNEL_NAME:
return self.kernel_spec_class(
resource_dir=ipykernel.kernelspec.RESOURCES,
**ipykernel.kernelspec.get_kernel_dict())
else:
return super(NbvalKernelspecManager, self).get_kernel_spec(kernel_name)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:45:
self = <nbval.kernel.NbvalKernelspecManager object at 0x113978828> kernel_name = 'conda-env-py37-py'
def get_kernel_spec(self, kernel_name):
"""Returns a :class:`KernelSpec` instance for the given kernel_name.
Raises :exc:`NoSuchKernel` if the given kernel name is not found.
"""
if not _is_valid_kernel_name(kernel_name):
self.log.warning("Kernelspec name %r is invalid: %s", kernel_name,
_kernel_name_description)
resource_dir = self._find_spec_directory(kernel_name.lower())
if resource_dir is None:
raise NoSuchKernel(kernel_name)
E jupyter_client.kernelspec.NoSuchKernel: No such kernel named conda-env-py37-py
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/kernelspec.py:236: NoSuchKernel _____________ ERROR at setup of tests/test_basetypes.ipynb::Cell 1 _____________
self = <CallInfo when='setup' exception: No such kernel named conda-env-py37-py>
func = <function call_runtest_hook.
def __init__(self, func, when, treat_keyboard_interrupt_as_exception=False):
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
self.when = when
self.start = time()
try:
self.result = func()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:201:
lambda: ihook(item=item, **kwds), when=when, treat_keyboard_interrupt_as_exception=item.config.getvalue("usepdb"), )
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:183:
self = <_HookCaller 'pytest_runtest_setup'>, args = () kwargs = {'item': <IPyNbCell 'Cell 1'>}, notincall = set()
def __call__(self, *args, **kwargs):
if args:
raise TypeError("hook calling supports only keyword arguments")
assert not self.is_historic()
if self.argnames:
notincall = set(self.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._nonwrappers + self._wrappers, kwargs)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/hooks.py:258:
self = <_pytest.config.PytestPluginManager object at 0x1051379e8> hook = <_HookCaller 'pytest_runtest_setup'> methods = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] kwargs = {'item': <IPyNbCell 'Cell 1'>}
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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/manager.py:67:
hook = <_HookCaller 'pytest_runtest_setup'> methods = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] kwargs = {'item': <IPyNbCell 'Cell 1'>}
self._inner_hookexec = lambda hook, methods, kwargs: \
hook.multicall(
methods, kwargs,
firstresult=hook.spec_opts.get('firstresult'),
)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/manager.py:61:
hook_impls = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] caller_kwargs = {'item': <IPyNbCell 'Cell 1'>}, 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()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:201:
self = <pluggy.callers._Result object at 0x113de11d0>
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])
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:76:
hook_impls = [<HookImpl plugin_name='nose', plugin=<module '_pytest.nose' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/... '_pytest.skipping' from '/Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/skipping.py'>>, ...] caller_kwargs = {'item': <IPyNbCell 'Cell 1'>}, 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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/pluggy/callers.py:180:
item = <IPyNbCell 'Cell 1'>
def pytest_runtest_setup(item):
_update_current_test_var(item, "setup")
item.session._setupstate.prepare(item)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:104:
self = <_pytest.runner.SetupState object at 0x112dcf0f0> colitem = <IPyNbCell 'Cell 1'>
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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:366:
tp = <class 'jupyter_client.kernelspec.NoSuchKernel'>, 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)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/six.py:692:
self = <_pytest.runner.SetupState object at 0x112dcf0f0> colitem = <IPyNbCell 'Cell 0'>
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()
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/_pytest/runner.py:370:
self = <IPyNbFile 'test_basetypes.ipynb'>
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))
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/plugin.py:232:
self = <nbval.kernel.RunningKernel object at 0x113978a20> kernel_name = 'conda-env-py37-py' cwd = '/Users/klay6683/Dropbox/src/pytelescope/tests'
def __init__(self, kernel_name, cwd=None):
"""
Initialise a new kernel
specify that matplotlib is inline and connect the stderr.
Stores the active kernel process and its manager.
"""
self.km, self.kc = start_new_kernel(
kernel_name=kernel_name,
stderr=open(os.devnull, 'w'),
cwd=cwd,
)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:88:
startup_timeout = 60, kernel_name = 'conda-env-py37-py' kwargs = {'cwd': '/Users/klay6683/Dropbox/src/pytelescope/tests', 'stderr': <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>} km = <jupyter_client.manager.KernelManager object at 0x1139789e8>
def start_new_kernel(startup_timeout=60, kernel_name='python', **kwargs):
"""Start a new kernel, and return its Manager and Client"""
logger.debug('Starting new kernel: "%s"' % kernel_name)
km = KernelManager(kernel_name=kernel_name,
kernel_spec_manager=NbvalKernelspecManager())
km.start_kernel(**kwargs)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:53:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8> kw = {'cwd': '/Users/klay6683/Dropbox/src/pytelescope/tests', 'stderr': <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>} extra_arguments = []
def start_kernel(self, **kw):
"""Starts a kernel on this host in a separate process.
If random ports (port=0) are being used, this method must be called
before the channels are created.
Parameters
----------
`**kw` : optional
keyword arguments that are passed down to build the kernel_cmd
and launching the kernel (e.g. Popen kwargs).
"""
if self.transport == 'tcp' and not is_local_ip(self.ip):
raise RuntimeError("Can only launch a kernel on a local interface. "
"This one is not: %s."
"Make sure that the '*_address' attributes are "
"configured properly. "
"Currently valid addresses are: %s" % (self.ip, local_ips())
)
# write connection file / get default ports
self.write_connection_file()
# save kwargs for use in restart
self._launch_args = kw.copy()
# build the Popen cmd
extra_arguments = kw.pop('extra_arguments', [])
kernel_cmd = self.format_kernel_cmd(extra_arguments=extra_arguments)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:246:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8> extra_arguments = []
def format_kernel_cmd(self, extra_arguments=None):
"""replace templated args (e.g. {connection_file})"""
extra_arguments = extra_arguments or []
if self.kernel_cmd:
cmd = self.kernel_cmd + extra_arguments
else:
cmd = self.kernel_spec.argv + extra_arguments
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:170:
self = <jupyter_client.manager.KernelManager object at 0x1139789e8>
@property
def kernel_spec(self):
if self._kernel_spec is None and self.kernel_name is not '':
self._kernel_spec = self.kernel_spec_manager.get_kernel_spec(self.kernel_name)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:82:
self = <nbval.kernel.NbvalKernelspecManager object at 0x113978828> kernel_name = 'conda-env-py37-py'
def get_kernel_spec(self, kernel_name):
"""Returns a :class:`KernelSpec` instance for the given kernel_name.
Raises :exc:`NoSuchKernel` if the given kernel name is not found.
"""
if kernel_name == CURRENT_ENV_KERNEL_NAME:
return self.kernel_spec_class(
resource_dir=ipykernel.kernelspec.RESOURCES,
**ipykernel.kernelspec.get_kernel_dict())
else:
return super(NbvalKernelspecManager, self).get_kernel_spec(kernel_name)
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/nbval/kernel.py:45:
self = <nbval.kernel.NbvalKernelspecManager object at 0x113978828> kernel_name = 'conda-env-py37-py'
def get_kernel_spec(self, kernel_name):
"""Returns a :class:`KernelSpec` instance for the given kernel_name.
Raises :exc:`NoSuchKernel` if the given kernel name is not found.
"""
if not _is_valid_kernel_name(kernel_name):
self.log.warning("Kernelspec name %r is invalid: %s", kernel_name,
_kernel_name_description)
resource_dir = self._find_spec_directory(kernel_name.lower())
if resource_dir is None:
raise NoSuchKernel(kernel_name)
E jupyter_client.kernelspec.NoSuchKernel: No such kernel named conda-env-py37-py
../../../../miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/kernelspec.py:236: NoSuchKernel =============================== warnings summary =============================== /Users/klay6683/miniconda3/envs/py37/lib/python3.7/site-packages/jupyter_client/manager.py:72: DeprecationWarning: KernelManager._kernel_name_changed is deprecated in traitlets 4.1: use @observe and @unobserve instead. def _kernel_name_changed(self, name, old, new):
-- Docs: https://docs.pytest.org/en/latest/warnings.html ===================== 1 warnings, 2 error in 0.46 seconds ======================
The actual error is that the notebook is saved with a kernel name that cannot be found. This should be solvable by adding the --current-env flag. The other question is whether a better error message can be given from nbval, as I assume this is a likely enough exception that a more helpful error is warranted.
And just to make it clear, there are actually only two exceptions here, but it prints the full stack trace of the error (with context) for each exception, making the log rather verbose.
sorry, I don't know what the --current-env is or what it is supposed to do. I scanned your docs but it isn't mentioned? I made sure that the notebook was run with an available kernel and that the same conda env is active when I run pytest so I don't understand why a certain kernel is not being found? It should just be the same as is currently active?
Hmm, we should probably add the flag to the docs then. For now, here is the text from py.test --help:
--current-env Force test execution to use a python kernel in the same enviornment that py.test was launched from.
The error you are seeing is E jupyter_client.kernelspec.NoSuchKernel: No such kernel named conda-env-py37-py. I don't know enough about conda kernel setup to debug it further than that. Maybe @takluyver knows more?
PS: Does it work if you use the --current-env flag?
oh, I see, it's an py.test flag? yes, it seems to be working with it! (now only all those failing tests ;)) I just never heard of this flag, because using pytest within my conda envs never required using it, that's why I am a bit perplexed why the nbval plugin requires it? I'm still using the same executable that is embedded in that currently active env? I guess the plugin should look up the current $CONDA_PREFIX which is dynamically pointing to the current env?
$ echo $CONDA_PREFIX (py37)
/Users/klay6683/miniconda3/envs/py37
But, actually, simply looking up the path ( if it's a path issue at all) should suffice:
$ echo $PATH (py37)
/Users/klay6683/miniconda3/envs/py37/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /Library/TeX/texbin /usr/local/sbin
b/c that's just the point of conda, to dynamically change it based on the currently active env.
The current way it works takes its logic from the question: How would you test a non-python notebook (e.g. julia)? The current way is to look at the kernel name that the notebook was saved with, and try to use that. The --current-env flag is a flag that nbval adds to pytest, but it only makes sense for Python notebooks.
If there is another default logic that could consistently be applied, I'd be open to consider it :+1:
The problem is caused by how the name of the conda env is stored in the jupyter notebook. They don't match if the kernel registration was done by a popular tool like nb_conda_kernels.
In my case, my conda env is py37, but the notebook searches for a conda env conda-env-py37-py.
I hope that the code that searches for the appropriate env could somehow be improved?
I hope that the code that searches for the appropriate env could somehow be improved?
I would hope so too, but I'm not proficient enough in that part of the Jupyter stack to figure that out. Any contributors who want to help out here would be very welcome!
i think this is less jupyter stack than realizing that any jupyter kernel name has not necessarily anything to do with the conda env name. but this is also a prob of pytest throwing thousands of errors without being more helpful of simply saying, "so i tried the current env but either there's no python or your package isn't installed, now what?" I'll think about this a bit more when I have my next test-dev round, possibly in a hackathon at the end of June.