Some checks failed
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
import os
|
|
import re
|
|
|
|
models_dir = r"c:\dev\git\python\homelab-automation-api-v2\app\models"
|
|
|
|
def fix_file(filepath):
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
|
|
new_lines = []
|
|
# Make sure future annotations is ON to avoid runtime errors with piping if any remain,
|
|
# BUT wait, if I remove unions from Mapped, I don't need it as much for the scanner.
|
|
# However, keeping it on is usually better for modern code.
|
|
found_future = False
|
|
|
|
for line in lines:
|
|
if "from __future__ import annotations" in line:
|
|
new_lines.append("from __future__ import annotations\n")
|
|
found_future = True
|
|
continue
|
|
|
|
# Clean up existing double hashes if any
|
|
line = line.replace("# # from __future__", "# from __future__")
|
|
|
|
# Match Mapped[T | None] or Mapped[Optional[T]]
|
|
# We want to transform to Mapped[T]
|
|
# and ensure mapped_column has nullable=True
|
|
|
|
match = re.search(r'(.*?):\s*Mapped\[(?:Optional\[(.*?)\|?(.*?)\]|([^\|]*?)\s*\|\s*None)\]\s*=\s*mapped_column\((.*?)\)(.*)', line)
|
|
if match:
|
|
# We found one.
|
|
indent = match.group(1)
|
|
# Try to get T from various groups
|
|
t = match.group(2) or match.group(4)
|
|
if not t and match.group(3): # For Optional[T] if it captured wrong
|
|
t = match.group(2)
|
|
|
|
column_args = match.group(5)
|
|
rest = match.group(6)
|
|
|
|
# Ensure nullable=True
|
|
if "nullable=" not in column_args:
|
|
if column_args.strip():
|
|
column_args = f"{column_args}, nullable=True"
|
|
else:
|
|
column_args = "nullable=True"
|
|
elif "nullable=False" in column_args:
|
|
# Should not happen as we found a Union with None, but if so, override
|
|
column_args = column_args.replace("nullable=False", "nullable=True")
|
|
|
|
new_line = f"{indent}: Mapped[{t}] = mapped_column({column_args}){rest}\n"
|
|
new_lines.append(new_line)
|
|
else:
|
|
new_lines.append(line)
|
|
|
|
if not found_future:
|
|
new_lines.insert(0, "from __future__ import annotations\n")
|
|
|
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
f.writelines(new_lines)
|
|
|
|
for filename in os.listdir(models_dir):
|
|
if filename.endswith(".py") and filename != "__init__.py":
|
|
print(f"Fixing {filename}...")
|
|
fix_file(os.path.join(models_dir, filename))
|