Coverage for structured_tutorials/tutorial.py: 96%
25 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-06-10 14:54 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-06-10 14:54 +0200
1"""Tutorial-related functions."""
3import os
4import pathlib
5from collections.abc import Iterator
6from contextlib import contextmanager
7from pathlib import Path
9from yaml import safe_load
11from structured_tutorials.models import Tutorial
12from structured_tutorials.runners.local import LocalRunner
15@contextmanager
16def chdir(path: Path) -> Iterator[None]:
17 old_cwd = os.getcwd()
18 try:
19 os.chdir(path)
20 yield
21 finally:
22 os.chdir(old_cwd)
25def load_tutorial(path: pathlib.Path) -> Tutorial:
26 """Load a tutorial from a YAML file."""
27 with open(path) as stream:
28 tutorial_data = safe_load(stream)
29 tutorial = Tutorial.model_validate(tutorial_data, context={"path": path})
30 return tutorial
33def run_tutorial(tutorial: Tutorial) -> None:
34 """Run a loaded tutorial."""
35 if tutorial.config.type == "local": 35 ↛ 38line 35 didn't jump to line 38 because the condition on line 35 was always true
36 runner = LocalRunner(tutorial)
38 with chdir(tutorial.config.working_directory):
39 runner.run()