1818
1919def extract_lines (file_path : Path , start_line : int , end_line : int ) -> str :
2020 """Extract lines from a file.
21-
21+
2222 Args:
2323 file_path: Path to the file
2424 start_line: Starting line number (1-based)
2525 end_line: Ending line number (1-based, inclusive)
26-
26+
2727 Returns:
2828 The extracted lines
2929 """
@@ -32,38 +32,38 @@ def extract_lines(file_path: Path, start_line: int, end_line: int) -> str:
3232 # Convert to 0-based indexing
3333 start_idx = max (0 , start_line - 1 )
3434 end_idx = min (len (lines ), end_line )
35- return ' \n ' .join (lines [start_idx :end_idx ])
35+ return " \n " .join (lines [start_idx :end_idx ])
3636
3737
3838def get_github_url (file_path : str , start_line : int , end_line : int ) -> str :
3939 """Generate a GitHub URL for the file with line highlighting.
40-
40+
4141 Args:
4242 file_path: Path to the file relative to repo root
4343 start_line: Starting line number
4444 end_line: Ending line number
45-
45+
4646 Returns:
4747 GitHub URL with line highlighting
4848 """
4949 base_url = "https://github.com/modelcontextprotocol/python-sdk/blob/main"
5050 url = f"{ base_url } /{ file_path } "
51-
51+
5252 if start_line == end_line :
5353 url += f"#L{ start_line } "
5454 else :
5555 url += f"#L{ start_line } -L{ end_line } "
56-
56+
5757 return url
5858
5959
6060def process_snippet_block (match : re .Match , check_mode : bool = False ) -> str :
6161 """Process a single snippet-source block.
62-
62+
6363 Args:
6464 match: The regex match object
6565 check_mode: If True, return original if no changes needed
66-
66+
6767 Returns:
6868 The updated block content
6969 """
@@ -72,89 +72,82 @@ def process_snippet_block(match: re.Match, check_mode: bool = False) -> str:
7272 file_path = match .group (2 )
7373 start_line = int (match .group (3 ))
7474 end_line = int (match .group (4 ))
75-
75+
7676 try :
7777 # Read and extract the code
7878 file = Path (file_path )
7979 if not file .exists ():
8080 print (f"Warning: File not found: { file_path } " )
8181 return full_match
82-
82+
8383 code = extract_lines (file , start_line , end_line )
84-
84+
8585 # Generate GitHub URL
8686 github_url = get_github_url (file_path , start_line , end_line )
87-
87+
8888 # Build the replacement block
8989 replacement = f"""{ indent } <!-- snippet-source { file_path } #L{ start_line } -L{ end_line } -->
9090{ indent } ```python
9191{ code }
9292{ indent } ```
9393{ indent } _Full example: [{ file_path } ]({ github_url } )_
9494{ indent } <!-- /snippet-source -->"""
95-
95+
9696 # In check mode, only check if code has changed
9797 if check_mode :
9898 # Extract existing code from the match
9999 existing_content = match .group (5 )
100100 if existing_content is not None :
101- existing_lines = existing_content .strip ().split (' \n ' )
101+ existing_lines = existing_content .strip ().split (" \n " )
102102 # Find code between ```python and ```
103103 code_lines = []
104104 in_code = False
105105 for line in existing_lines :
106- if line .strip () == ' ```python' :
106+ if line .strip () == " ```python" :
107107 in_code = True
108- elif line .strip () == ' ```' :
108+ elif line .strip () == " ```" :
109109 break
110110 elif in_code :
111111 code_lines .append (line )
112- existing_code = ' \n ' .join (code_lines ).strip ()
112+ existing_code = " \n " .join (code_lines ).strip ()
113113 if existing_code == code .strip ():
114114 return full_match
115-
115+
116116 return replacement
117-
117+
118118 except Exception as e :
119119 print (f"Error processing { file_path } #L{ start_line } -L{ end_line } : { e } " )
120120 return full_match
121121
122122
123123def update_readme_snippets (readme_path : Path = Path ("README.md" ), check_mode : bool = False ) -> bool :
124124 """Update code snippets in README.md with live code from source files.
125-
125+
126126 Args:
127127 readme_path: Path to the README file
128128 check_mode: If True, only check if updates are needed without modifying
129-
129+
130130 Returns:
131131 True if file is up to date or was updated, False if check failed
132132 """
133133 if not readme_path .exists ():
134134 print (f"Error: README file not found: { readme_path } " )
135135 return False
136-
136+
137137 content = readme_path .read_text ()
138138 original_content = content
139-
139+
140140 # Pattern to match snippet-source blocks with line ranges
141141 # Matches: <!-- snippet-source path/to/file.py#L10-L20 -->
142142 # ... any content ...
143143 # <!-- /snippet-source -->
144- pattern = (
145- r'^(\s*)<!-- snippet-source ([^#]+)#L(\d+)-L(\d+) -->\n'
146- r'(.*?)'
147- r'^\1<!-- /snippet-source -->'
148- )
149-
144+ pattern = r"^(\s*)<!-- snippet-source ([^#]+)#L(\d+)-L(\d+) -->\n" r"(.*?)" r"^\1<!-- /snippet-source -->"
145+
150146 # Process all snippet-source blocks
151147 updated_content = re .sub (
152- pattern ,
153- lambda m : process_snippet_block (m , check_mode ),
154- content ,
155- flags = re .MULTILINE | re .DOTALL
148+ pattern , lambda m : process_snippet_block (m , check_mode ), content , flags = re .MULTILINE | re .DOTALL
156149 )
157-
150+
158151 if check_mode :
159152 if updated_content != original_content :
160153 print (
@@ -176,27 +169,19 @@ def update_readme_snippets(readme_path: Path = Path("README.md"), check_mode: bo
176169
177170def main ():
178171 """Main entry point."""
179- parser = argparse .ArgumentParser (
180- description = 'Update README code snippets from source files'
181- )
182- parser .add_argument (
183- '--check' ,
184- action = 'store_true' ,
185- help = 'Check mode - verify snippets are up to date without modifying'
186- )
172+ parser = argparse .ArgumentParser (description = "Update README code snippets from source files" )
187173 parser .add_argument (
188- '--readme' ,
189- default = 'README.md' ,
190- help = 'Path to README file (default: README.md)'
174+ "--check" , action = "store_true" , help = "Check mode - verify snippets are up to date without modifying"
191175 )
192-
176+ parser .add_argument ("--readme" , default = "README.md" , help = "Path to README file (default: README.md)" )
177+
193178 args = parser .parse_args ()
194-
179+
195180 success = update_readme_snippets (Path (args .readme ), check_mode = args .check )
196-
181+
197182 if not success :
198183 sys .exit (1 )
199184
200185
201186if __name__ == "__main__" :
202- main ()
187+ main ()
0 commit comments