test_myst_doc.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """Convert a jupytext-compliant format in to a python script
  2. and execute it with parsed arguments.
  3. Any cell with 'remove-cell-ci' tag in metadata will not be included
  4. in the converted python script.
  5. """
  6. import argparse
  7. import subprocess
  8. import sys
  9. import tempfile
  10. from pathlib import Path
  11. import jupytext
  12. parser = argparse.ArgumentParser(description=__doc__)
  13. parser.add_argument(
  14. "--path",
  15. help="path to the jupytext-compatible file",
  16. )
  17. parser.add_argument(
  18. "--find-recursively",
  19. action="store_true",
  20. help="if true, will attempt to find path recursively in cwd",
  21. )
  22. parser.add_argument(
  23. "--no-postprocess",
  24. action="store_true",
  25. help="if true, will not postprocess the notebook",
  26. )
  27. def filter_out_cells_with_remove_cell_ci_tag(cells: list):
  28. """Filters out cells which contain the 'remove-cell-ci' tag in metadata"""
  29. def should_keep_cell(cell):
  30. tags = cell.metadata.get("tags")
  31. if tags:
  32. # Both - and _ for consistent behavior with built-in tags
  33. return "remove_cell_ci" not in tags and "remove-cell-ci" not in tags
  34. return True
  35. return [cell for cell in cells if should_keep_cell(cell)]
  36. def postprocess_notebook(notebook):
  37. notebook.cells = filter_out_cells_with_remove_cell_ci_tag(notebook.cells)
  38. return notebook
  39. DISPLAY_FUNCTION = """
  40. def display(*args, **kwargs):
  41. print(*args, **kwargs)
  42. """
  43. if __name__ == "__main__":
  44. args, remainder = parser.parse_known_args()
  45. path = Path(args.path)
  46. cwd = Path.cwd()
  47. if args.find_recursively and not path.exists():
  48. path = next((p for p in cwd.rglob("*") if str(p).endswith(args.path)), None)
  49. assert path and path.exists()
  50. with open(path, "r") as f:
  51. notebook = jupytext.read(f)
  52. if not args.no_postprocess:
  53. notebook = postprocess_notebook(notebook)
  54. name = ""
  55. with tempfile.NamedTemporaryFile("w", delete=False) as f:
  56. # Define the display function, which is available in notebooks,
  57. # but not in normal Python scripts.
  58. f.write(DISPLAY_FUNCTION)
  59. jupytext.write(notebook, f, fmt="py:percent")
  60. name = f.name
  61. remainder.insert(0, name)
  62. remainder.insert(0, sys.executable)
  63. # Run the notebook
  64. subprocess.run(remainder, check=True)