Created
December 2, 2024 14:16
-
-
Save daylanKifky/fa7dd458dad94c8916c5a85fb13b9f29 to your computer and use it in GitHub Desktop.
Apply PEP604 annotation style to repository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import ast | |
import pathlib | |
from typing import Union, List | |
class TypeHintTransformer(ast.NodeTransformer): | |
def visit_Subscript(self, node: ast.Subscript) -> ast.Subscript: | |
# Only transform Union type hints in actual code (not in strings/comments) | |
if (isinstance(node.value, ast.Name) and | |
node.value.id == 'Union' and | |
not isinstance(node.parent, (ast.Str, ast.Constant))): | |
if isinstance(node.slice, ast.Tuple): | |
# Convert Union[X, Y] to X | Y | |
first = node.slice.elts[0] | |
result = first | |
for typ in node.slice.elts[1:]: | |
result = ast.BinOp(left=result, op=ast.BitOr(), right=typ) | |
return result | |
# Don't modify other subscripts | |
return self.generic_visit(node) | |
def convert_file(file_path: pathlib.Path) -> None: | |
"""Convert type hints in a single file to PEP 604 format.""" | |
with open(file_path) as f: | |
lines = f.readlines() | |
union_pattern = re.compile(r'Union\[(.*?)\]') | |
def replace_union(match): | |
types = match.group(1).split(', ') | |
return ' | '.join(types) | |
modified = False | |
new_lines = [] | |
for line in lines: | |
if 'Union[' in line: | |
new_line = union_pattern.sub(replace_union, line) | |
if new_line != line: | |
modified = True | |
new_lines.append(new_line) | |
else: | |
new_lines.append(line) | |
if modified: | |
with open(file_path, 'w') as f: | |
f.writelines(new_lines) | |
print(f"Converted Union types in {file_path}") | |
def convert_repository(repo_path: Union[str, pathlib.Path]) -> None: | |
"""Convert all Python files in a repository to use PEP 604 type hints.""" | |
repo_path = pathlib.Path(repo_path) | |
python_files = repo_path.rglob("*.py") | |
for file_path in python_files: | |
convert_file(file_path) | |
if __name__ == "__main__": | |
import sys | |
if len(sys.argv) != 2: | |
print("Usage: python script.py <repository_path>") | |
sys.exit(1) | |
repo_path = sys.argv[1] | |
convert_repository(repo_path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment