diff --git a/RELEASE.md b/RELEASE.md index bb07f5c7a8..30e9da0443 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,6 +8,7 @@ * Allowed the use of nulls in `parameters.yml`. * Fixed an issue where `%reload_kedro` wasn't reloading all user modules. * Fixed `pandas_to_spark` and `spark_to_pandas` decorators to work with functions with kwargs. +* Fixed a bug where `kedro jupyter notebook` and `kedro jupyter lab` would run a different Jupyter installation to the one in the local environment. ## Breaking changes to the API * Renamed entry point for running pip-installed projects to `run_package()` instead of `main()` in `src//run.py`. diff --git a/kedro/cli/utils.py b/kedro/cli/utils.py index a731509676..0e03cdf34f 100644 --- a/kedro/cli/utils.py +++ b/kedro/cli/utils.py @@ -34,7 +34,7 @@ import sys from itertools import chain from pathlib import Path -from typing import Any, Dict, Iterable, Sequence, Tuple, Union +from typing import Any, Dict, Iterable, List, Sequence, Tuple, Union from warnings import warn import click @@ -45,7 +45,7 @@ NODE_TAG = "node" -def call(cmd, **kwargs): # pragma: no cover +def call(cmd: List[str], **kwargs): # pragma: no cover """Run a subprocess command and exit if it fails.""" print(" ".join(shlex.quote(c) for c in cmd)) res = subprocess.run(cmd, **kwargs).returncode @@ -53,7 +53,7 @@ def call(cmd, **kwargs): # pragma: no cover sys.exit(res) -def python_call(module, arguments, **kwargs): # pragma: no cover +def python_call(module: str, arguments: Iterable[str], **kwargs): # pragma: no cover """Run a subprocess command that invokes a Python module.""" call([sys.executable, "-m", module] + list(arguments), **kwargs) diff --git a/kedro/template/{{ cookiecutter.repo_name }}/kedro_cli.py b/kedro/template/{{ cookiecutter.repo_name }}/kedro_cli.py index a6b30a26e9..6ecaf49d33 100755 --- a/kedro/template/{{ cookiecutter.repo_name }}/kedro_cli.py +++ b/kedro/template/{{ cookiecutter.repo_name }}/kedro_cli.py @@ -326,7 +326,7 @@ def activate_nbstripout(): def _build_jupyter_command( base: str, ip: str, all_kernels: bool, args: Iterable[str] ) -> List[str]: - cmd = [base, "--ip=" + ip] + cmd = [base, "--ip", ip] if not all_kernels: project_name = "{{ cookiecutter.project_name }}" @@ -355,11 +355,10 @@ def jupyter_notebook(ip, all_kernels, args): if "-h" not in args and "--help" not in args: ipython_message(all_kernels) - call( - _build_jupyter_command( - "jupyter-notebook", ip=ip, all_kernels=all_kernels, args=args - ) + arguments = _build_jupyter_command( + "notebook", ip=ip, all_kernels=all_kernels, args=args ) + python_call("jupyter", arguments) @forward_command(jupyter, "lab", forward_help=True) @@ -370,9 +369,8 @@ def jupyter_lab(ip, all_kernels, args): if "-h" not in args and "--help" not in args: ipython_message(all_kernels) - call( - _build_jupyter_command("jupyter-lab", ip=ip, all_kernels=all_kernels, args=args) - ) + arguments = _build_jupyter_command("lab", ip=ip, all_kernels=all_kernels, args=args) + python_call("jupyter", arguments) @jupyter.command("convert") diff --git a/tests/template/test_kedro_cli.py b/tests/template/test_kedro_cli.py index 938765942b..09da94c3be 100644 --- a/tests/template/test_kedro_cli.py +++ b/tests/template/test_kedro_cli.py @@ -378,28 +378,34 @@ def test_requirements_file_doesnt_exist( class TestJupyterNotebookCommand: - def test_default_kernel(self, call_mock, fake_kedro_cli, fake_ipython_message): + def test_default_kernel( + self, python_call_mock, fake_kedro_cli, fake_ipython_message + ): result = CliRunner().invoke( - fake_kedro_cli.cli, ["jupyter", "notebook", "--ip=0.0.0.0"] + fake_kedro_cli.cli, ["jupyter", "notebook", "--ip", "0.0.0.0"] ) assert not result.exit_code, result.stdout fake_ipython_message.assert_called_once_with(False) - call_mock.assert_called_once_with( + python_call_mock.assert_called_once_with( + "jupyter", [ - "jupyter-notebook", - "--ip=0.0.0.0", + "notebook", + "--ip", + "0.0.0.0", "--NotebookApp.kernel_spec_manager_class=kedro.cli.jupyter.SingleKernelSpecManager", "--KernelSpecManager.default_kernel_name='TestProject'", - ] + ], ) - def test_all_kernels(self, call_mock, fake_kedro_cli, fake_ipython_message): + def test_all_kernels(self, python_call_mock, fake_kedro_cli, fake_ipython_message): result = CliRunner().invoke( fake_kedro_cli.cli, ["jupyter", "notebook", "--all-kernels"] ) assert not result.exit_code, result.stdout fake_ipython_message.assert_called_once_with(True) - call_mock.assert_called_once_with(["jupyter-notebook", "--ip=127.0.0.1"]) + python_call_mock.assert_called_once_with( + "jupyter", ["notebook", "--ip", "127.0.0.1"] + ) @pytest.mark.parametrize("help_flag", ["-h", "--help"]) def test_help(self, help_flag, fake_kedro_cli, fake_ipython_message): @@ -411,32 +417,40 @@ def test_help(self, help_flag, fake_kedro_cli, fake_ipython_message): class TestJupyterLabCommand: - def test_default_kernel(self, call_mock, fake_kedro_cli, fake_ipython_message): + def test_default_kernel( + self, python_call_mock, fake_kedro_cli, fake_ipython_message + ): result = CliRunner().invoke( - fake_kedro_cli.cli, ["jupyter", "lab", "--ip=0.0.0.0"] + fake_kedro_cli.cli, ["jupyter", "lab", "--ip", "0.0.0.0"] ) assert not result.exit_code, result.stdout fake_ipython_message.assert_called_once_with(False) - call_mock.assert_called_once_with( + python_call_mock.assert_called_once_with( + "jupyter", [ - "jupyter-lab", - "--ip=0.0.0.0", + "lab", + "--ip", + "0.0.0.0", "--NotebookApp.kernel_spec_manager_class=kedro.cli.jupyter.SingleKernelSpecManager", "--KernelSpecManager.default_kernel_name='TestProject'", - ] + ], ) - def test_all_kernels(self, call_mock, fake_kedro_cli, fake_ipython_message): + def test_all_kernels(self, python_call_mock, fake_kedro_cli, fake_ipython_message): result = CliRunner().invoke( fake_kedro_cli.cli, ["jupyter", "lab", "--all-kernels"] ) assert not result.exit_code, result.stdout fake_ipython_message.assert_called_once_with(True) - call_mock.assert_called_once_with(["jupyter-lab", "--ip=127.0.0.1"]) + python_call_mock.assert_called_once_with( + "jupyter", ["lab", "--ip", "127.0.0.1"] + ) @pytest.mark.parametrize("help_flag", ["-h", "--help"]) def test_help(self, help_flag, fake_kedro_cli, fake_ipython_message): - result = CliRunner().invoke(fake_kedro_cli.cli, ["jupyter", "lab", help_flag]) + result = CliRunner().invoke( + fake_kedro_cli.cli, [sys.executable, "-m", "jupyter", "lab", help_flag] + ) assert not result.exit_code, result.stdout fake_ipython_message.assert_not_called()