importnb test specification¶
this notebook is written to test many of the features of importnb.
these features in this notebook test:
- basic finding and loading
- filtering magics, classes and functions
- lazy loading
- the command line interface
from __future__ import annotations
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Any
from importnb import get_ipython
if TYPE_CHECKING:
from argparse import ArgumentParser
IS_MAIN = __name__ == "__main__"
IS_PYTEST = "pytest" in sys.argv or "pytest" in sys.argv[0]
IS_DOIT = "doit" in sys.modules
IS_WIN = sys.platform == "win32"
IS_IPYTHON = get_ipython() is not None
WHERE = Path(__file__).as_posix() if "__file__" in locals() else ""
a sentinel for execution¶
the SLUG below is used to measure that a module has been executed,
we specifically use this expression to measure the lazy importing system.
SLUG = "i was printed from {WHERE} \
and my name is {__name__}"
print(SLUG.format(**locals()))
implicit markdown docstrings¶
there is a strict separation of code and non-code in notebooks.
to encourage more/better documentation importnb will use a markdown
cell preceeding a function as a docstring.
as a result, the function_with_a_markdown docstring will have this markdown cell for a value.
def function_with_a_markdown_docstring() -> None:
return # function_with_a_markdown has a docstring defined by the preceeding markdown cell
the same convention holds for classes and async functions.
class class_with_a_markdown_docstring: ... # my docstring is the cell above.
this is not a docstring for class_with_a_string because it defines its own.
class class_with_a_python_docstring:
"""when a class defines its own docstring the preceeding cell is ignored."""
cell magics¶
%%python
print("i'm only show when cell magics are active.")
if IS_IPYTHON:
MAGIC_SLUG = "i'm only show when cell magics are active."
if IS_WIN:
MAGIC_SLUG += "\n"
else:
MAGIC_SLUG = f"this was printed from the module named {__name__}"
print(MAGIC_SLUG)
notebooks as scripts¶
the main block is a python convention we can apply in notebooks imported by importnb.
def get_parser() -> ArgumentParser:
from argparse import REMAINDER, ArgumentParser
parser = ArgumentParser(add_help=True)
parser.add_argument("--", nargs=REMAINDER, dest="args")
return parser
def main(argv: list[str] | None = None) -> int:
parser = get_parser()
print("the parser namespace is", parser.parse_args(argv))
return 0
if IS_MAIN and WHERE and not (IS_PYTEST or IS_DOIT):
# run this notebook like it is a cli
main(sys.argv[1:])
this the docstring for the echo task that echos hello.
def task_echo() -> dict[str, Any]:
return dict(actions=["echo hello"])
data loaders¶
data loaders can import other file formats. we can hide loading logic underneath import statements.
if IS_IPYTHON and not WHERE:
from IPython.display import display
from importnb import loaders
display(loaders.Json.load_file("Untitled42.ipynb"))