Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/machinevisiontoolbox/base/imageio.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,17 +1053,23 @@ def _isnotebook() -> bool:
"""
Determine if code is being run from a Jupyter notebook

``_isnotebook`` is True if running Jupyter notebook, else False
``_isnotebook`` is True if running Jupyter notebook, JupyterLite, Google Colab,
or similar, else False

:references:

- https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-
is-executed-in-the-ipython-notebook/39662359#39662359
"""
# JupyterLite runs in the browser, and Colab's shell is google.colab._shell.Shell
# rather than a ZMQInteractiveShell; neither is recognised by the shell test below
if sys.platform == "emscripten" or "google.colab" in sys.modules:
return True

try:
shell = get_ipython().__class__.__name__ # type: ignore[name-defined]
if shell in ("Shell", "ZMQInteractiveShell"):
return True # Jupyter notebook or qtconsole or CoLab
if shell == "ZMQInteractiveShell":
return True # Jupyter notebook or qtconsole
elif shell == "TerminalInteractiveShell":
return False # Terminal running IPython
else:
Expand Down
62 changes: 62 additions & 0 deletions tests/test_isnotebook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""``_isnotebook`` decides how ``Camera`` reuses its image plane, so it has to
recognise every environment a notebook runs in. These use a fake ``get_ipython`` and
patched ``sys.modules`` / ``sys.platform``: no real Jupyter, Colab or JupyterLite
kernel is exercised."""

import builtins
import sys
import types

import pytest

from machinevisiontoolbox.base.imageio import _isnotebook


@pytest.fixture
def plain(monkeypatch):
"""Standard interpreter: no IPython, not Colab, not Pyodide"""
monkeypatch.delattr(builtins, "get_ipython", raising=False)
monkeypatch.delitem(sys.modules, "google.colab", raising=False)
monkeypatch.setattr(sys, "platform", "linux")
return monkeypatch


def _shell(monkeypatch, name):
shell = type(name, (), {})()
monkeypatch.setattr(builtins, "get_ipython", lambda: shell, raising=False)


def test_a_standard_interpreter_is_not_a_notebook(plain):
assert _isnotebook() is False


def test_a_jupyter_kernel_is_a_notebook(plain):
_shell(plain, "ZMQInteractiveShell")

assert _isnotebook() is True


def test_ipython_in_a_terminal_is_not_a_notebook(plain):
_shell(plain, "TerminalInteractiveShell")

assert _isnotebook() is False


def test_colab_is_a_notebook(plain):
plain.setitem(sys.modules, "google.colab", types.ModuleType("google.colab"))
_shell(plain, "Shell")

assert _isnotebook() is True


def test_jupyterlite_is_a_notebook_whatever_its_shell_is_called(plain):
plain.setattr(sys, "platform", "emscripten")
_shell(plain, "SomeOtherShell")

assert _isnotebook() is True


def test_an_unknown_shell_is_not_a_notebook(plain):
_shell(plain, "Shell") # not Colab: google.colab is not loaded

assert _isnotebook() is False
Loading