Skip to content

Instantly share code, notes, and snippets.

@daylanKifky
Created December 2, 2024 14:16
Show Gist options
  • Save daylanKifky/fa7dd458dad94c8916c5a85fb13b9f29 to your computer and use it in GitHub Desktop.
Save daylanKifky/fa7dd458dad94c8916c5a85fb13b9f29 to your computer and use it in GitHub Desktop.
Apply PEP604 annotation style to repository
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