Spaces:
Running
Running
File size: 4,600 Bytes
71a9077 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#!/usr/bin/env python3
"""
Script to detect empty cells in marimo notebooks.
An empty cell is defined as:
@app.cell
def _():
return
This script will:
1. Find all Python files in the repository
2. Check if they contain marimo app definitions
3. Look for empty cell patterns
4. Report any empty cells found
"""
import os
import re
import sys
from pathlib import Path
from typing import List, Tuple
def is_marimo_notebook(file_path: Path) -> bool:
"""Check if a Python file is a marimo notebook."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Look for marimo app defn
return 'marimo.App' in content and '@app.cell' in content
except (UnicodeDecodeError, IOError):
return False
def find_empty_cells(file_path: Path) -> List[Tuple[int, str]]:
"""Find empty cells in a marimo notebook."""
empty_cells = []
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
except (UnicodeDecodeError, IOError):
return empty_cells
i = 0
while i < len(lines):
line = lines[i].strip()
# if line starts with @app.cell decorator
if line.startswith('@app.cell'):
# look for the function definition on the next non-empty line
j = i + 1
while j < len(lines) and not lines[j].strip():
j += 1
if j < len(lines) and lines[j].strip() == 'def _():':
# found function definition, now look for return statement
k = j + 1
while k < len(lines) and not lines[k].strip():
k += 1
if k < len(lines) and lines[k].strip() == 'return':
# if any content after return (before next @app.cell or end of file)
has_content = False
m = k + 1
while m < len(lines):
line_content = lines[m].strip()
if line_content.startswith('@app.cell'):
break
if line_content and not line_content.startswith('#'):
has_content = True
break
m += 1
if not has_content:
empty_cells.append((i + 1, lines[i].strip()))
i = k + 1
else:
i += 1
else:
i += 1
return empty_cells
def main():
"""Main function to check for empty cells."""
print("π Checking for empty cells in marimo notebooks...")
python_files = []
for root, dirs, files in os.walk('.'):
# skip hidden directories and common build/cache
dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['__pycache__', 'node_modules', 'build', 'dist']]
for file in files:
if file.endswith('.py'):
python_files.append(Path(root) / file)
marimo_notebooks = []
for file_path in python_files:
if is_marimo_notebook(file_path):
marimo_notebooks.append(file_path)
print(f"π Found {len(marimo_notebooks)} marimo notebooks")
# each notebook checked for empty cells
total_empty_cells = 0
files_with_empty_cells = []
for notebook_path in marimo_notebooks:
empty_cells = find_empty_cells(notebook_path)
if empty_cells:
total_empty_cells += len(empty_cells)
files_with_empty_cells.append((notebook_path, empty_cells))
print(f"β {notebook_path}: {len(empty_cells)} empty cell(s)")
for line_num, line_content in empty_cells:
print(f" Line {line_num}: {line_content}")
if files_with_empty_cells:
print(f"\nπ₯ Found {total_empty_cells} empty cells in {len(files_with_empty_cells)} files")
print("\nEmpty cells should be removed or contain meaningful content.")
print("An empty cell looks like:")
print("@app.cell")
print("def _():")
print(" return")
print("\nConsider either:")
print("1. Removing the empty cell entirely")
print("2. Adding meaningful content to the cell")
print("3. Adding a comment explaining why the cell is empty")
sys.exit(1)
else:
print("β
No empty cells found!")
sys.exit(0)
if __name__ == "__main__":
main() |