Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration guide for 0.4 #4765

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 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
18 changes: 18 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ jobs:
source ${{ github.workspace }}/python/.venv/bin/activate
poe --directory ${{ matrix.package }} docs-check-examples
working-directory: ./python

markdown-code-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: uv sync --locked --all-extras
working-directory: ./python
- name: Run task
run: |
source ${{ github.workspace }}/python/.venv/bin/activate
poe markdown-code-lint
working-directory: ./python

check-proto-changes-python:
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

This directory works as a single `uv` workspace containing all project packages. See [`packages`](./packages/) to discover all project packages.

## Migrating from 0.2.x?

Please refer to the [migration guide](./migration_guide.md) for how to migrate your code from 0.2.x to 0.4.x.

## Development

**TL;DR**, run all checks with:
Expand Down
82 changes: 82 additions & 0 deletions python/check_md_code_blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Check code blocks in Markdown files for syntax errors."""

import argparse
import logging
import tempfile
from typing import List, Tuple

from pygments import highlight # type: ignore
from pygments.formatters import TerminalFormatter
from pygments.lexers import PythonLexer
from sphinx.util.console import darkgreen, darkred, faint, red, teal # type: ignore[attr-defined]

logger = logging.getLogger(__name__)
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.INFO)

def extract_python_code_blocks(markdown_file_path: str) -> List[Tuple[str, int]]:
"""Extract Python code blocks from a Markdown file."""
with open(markdown_file_path, "r", encoding="utf-8") as file:
lines = file.readlines()

code_blocks: List[Tuple[str, int]] = []
in_code_block = False
current_block : List[str] = []
ekzhu marked this conversation as resolved.
Show resolved Hide resolved

for i, line in enumerate(lines):
if line.strip().startswith("```python"):
in_code_block = True
current_block = []
elif line.strip().startswith("```"):
in_code_block = False
code_blocks.append(("\n".join(current_block), i - len(current_block) + 1))
elif in_code_block:
current_block.append(line)

return code_blocks

def check_code_blocks(markdown_file_paths: List[str]) -> None:
"""Check Python code blocks in a Markdown file for syntax errors."""
files_with_errors = []

for markdown_file_path in markdown_file_paths:
code_blocks = extract_python_code_blocks(markdown_file_path)
had_errors = False
for code_block, line_no in code_blocks:
markdown_file_path_with_line_no = f"{markdown_file_path}:{line_no}"
logger.info("Checking a code block in %s...", markdown_file_path_with_line_no)

# Skip blocks that don't import autogen_agentchat, autogen_core, or autogen_ext
if all(all(import_code not in code_block for import_code in [f"import {module}", f"from {module}"]) for module in ["autogen_agentchat", "autogen_core", "autogen_ext"]):
logger.info(" " + darkgreen("OK[ignored]"))
continue

with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp_file:
temp_file.write(code_block.encode("utf-8"))
temp_file.flush()

# Run pyright on the temporary file using subprocess.run
import subprocess

result = subprocess.run(["pyright", temp_file.name], capture_output=True, text=True)
if result.returncode != 0:
logger.info(" " + darkred("FAIL"))
highlighted_code = highlight(code_block, PythonLexer(), TerminalFormatter()) # type: ignore
output = f"{faint('========================================================')}\n{red('Error')}: Pyright found issues in {teal(markdown_file_path_with_line_no)}:\n{faint('--------------------------------------------------------')}\n{highlighted_code}\n{faint('--------------------------------------------------------')}\n\n{teal('pyright output:')}\n{red(result.stdout)}{faint('========================================================')}\n"
logger.info(output)
had_errors = True
else:
logger.info(" " + darkgreen("OK"))

if had_errors:
files_with_errors.append(markdown_file_path)

if files_with_errors:
raise RuntimeError(f"Syntax errors found in the following files: {'\n'.join(files_with_errors)}\n")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Check code blocks in Markdown files for syntax errors.")
# Argument is a list of markdown files containing glob patterns
parser.add_argument("markdown_files", nargs="+", help="Markdown files to check.")
args = parser.parse_args()
check_code_blocks(args.markdown_files)
Loading
Loading