Programmer-RD-AI commented on code in PR #56180:
URL: https://github.com/apache/airflow/pull/56180#discussion_r2385376228


##########
dev/i18n/check_translations_completeness.py:
##########
@@ -581,11 +614,87 @@ def natural_key_sort(obj):
             return obj
 
         lang_data = natural_key_sort(lang_data)
-        lang_path.parent.mkdir(parents=True, exist_ok=True)
-        with open(lang_path, "w", encoding="utf-8") as f:
-            json.dump(lang_data, f, ensure_ascii=False, indent=2)
-            f.write("\n")  # Ensure newline at the end of the file
-        console.print(f"[green]Added missing translations to 
{lang_path}[/green]")
+
+        if dry_run:
+            console.print(f"[blue][DRY RUN] Would add missing translations to 
{lang_path}[/blue]")
+        else:
+            lang_path.parent.mkdir(parents=True, exist_ok=True)
+            with open(lang_path, "w", encoding="utf-8") as f:
+                json.dump(lang_data, f, ensure_ascii=False, indent=2)
+                f.write("\n")  # Ensure newline at the end of the file
+            console.print(f"[green]Added missing translations to 
{lang_path}[/green]")

Review Comment:
   You could simplify this branch by doing an early return inside the if 
dry_run. That way, you can print the dry-run message and exit immediately, 
instead of wrapping the actual write logic in an else.
   
   It makes the control flow flatter and easier to read:
   
   ```python
   if dry_run:
       console.print(f"[blue][DRY RUN] Would add missing translations to 
{lang_path}[/blue]")
       return
   
   lang_path.parent.mkdir(parents=True, exist_ok=True)
   with open(lang_path, "w", encoding="utf-8") as f:
       json.dump(lang_data, f, ensure_ascii=False, indent=2)
       f.write("\n")
   console.print(f"[green]Added missing translations to {lang_path}[/green]")
   ```
   
   Totally optional, but this makes the structure a bit cleaner and avoids the 
extra else.



##########
dev/i18n/check_translations_completeness.py:
##########
@@ -581,11 +614,87 @@ def natural_key_sort(obj):
             return obj
 
         lang_data = natural_key_sort(lang_data)
-        lang_path.parent.mkdir(parents=True, exist_ok=True)
-        with open(lang_path, "w", encoding="utf-8") as f:
-            json.dump(lang_data, f, ensure_ascii=False, indent=2)
-            f.write("\n")  # Ensure newline at the end of the file
-        console.print(f"[green]Added missing translations to 
{lang_path}[/green]")
+
+        if dry_run:
+            console.print(f"[blue][DRY RUN] Would add missing translations to 
{lang_path}[/blue]")
+        else:
+            lang_path.parent.mkdir(parents=True, exist_ok=True)
+            with open(lang_path, "w", encoding="utf-8") as f:
+                json.dump(lang_data, f, ensure_ascii=False, indent=2)
+                f.write("\n")  # Ensure newline at the end of the file
+            console.print(f"[green]Added missing translations to 
{lang_path}[/green]")
+
+
+def remove_extra_translations(
+    language: str, summary: dict[str, LocaleSummary], console: Console, 
dry_run: bool = False
+):
+    """
+    Remove extra translations that are not present in English.
+
+    This removes keys that exist in the target language but not in English.
+    """
+    for filename, diff in summary.items():
+        extra_keys = set(diff.extra_keys.get(language, []))
+        if not extra_keys:
+            continue
+
+        lang_path = LOCALES_DIR / language / filename
+        if not lang_path.exists():
+            continue
+
+        try:
+            lang_data = load_json(lang_path)
+        except Exception as e:
+            console.print(f"[red]Failed to load {language} file {lang_path}: 
{e}[/red]")
+            continue
+
+        # Helper to recursively remove extra keys
+        def remove_keys(data, prefix=""):
+            keys_to_remove = []
+            for k, v in data.items():
+                full_key = f"{prefix}.{k}" if prefix else k
+                if full_key in extra_keys:
+                    keys_to_remove.append(k)
+                    if dry_run:
+                        console.print(f"[blue][DRY RUN] Would remove extra 
key: {full_key}[/blue]")
+                    else:
+                        console.print(f"[yellow]Removed extra key: 
{full_key}[/yellow]")
+                elif isinstance(v, dict):
+                    remove_keys(v, full_key)
+                    # Remove empty nested dicts after recursive cleanup
+                    if not v:
+                        keys_to_remove.append(k)
+                        if dry_run:
+                            console.print(
+                                f"[blue][DRY RUN] Would remove empty nested 
dict: {full_key}[/blue]"
+                            )
+                        else:
+                            console.print(f"[yellow]Removed empty nested dict: 
{full_key}[/yellow]")
+
+            if not dry_run:
+                for k in keys_to_remove:
+                    del data[k]
+
+        remove_keys(lang_data)
+
+        # Only write if there were changes
+        if extra_keys:
+            if dry_run:
+                console.print(f"[blue][DRY RUN] Would remove extra 
translations from {lang_path}[/blue]")
+            else:
+
+                def natural_key_sort(obj):
+                    if isinstance(obj, dict):
+                        return {
+                            k: natural_key_sort(obj[k]) for k in sorted(obj, 
key=lambda x: (x.lower(), x))
+                        }
+                    return obj
+
+                lang_data = natural_key_sort(lang_data)
+                with open(lang_path, "w", encoding="utf-8") as f:
+                    json.dump(lang_data, f, ensure_ascii=False, indent=2)
+                    f.write("\n")  # Ensure newline at the end of the file
+                console.print(f"[green]Removed extra translations from 
{lang_path}[/green]")

Review Comment:
   Instead of wrapping the entire write block under if extra_keys:, you could 
do an early return when extra_keys is empty.
   
   That way the function exits immediately in the no-op case, and the rest of 
the logic doesn’t need an extra nesting level. For example:
   
   ```python
   if not extra_keys:
       return
   
   if dry_run:
       console.print(f"[blue][DRY RUN] Would remove extra translations from 
{lang_path}[/blue]")
       return
   
   lang_data = _natural_key_sort(lang_data)
   with open(lang_path, "w", encoding="utf-8") as f:
       json.dump(lang_data, f, ensure_ascii=False, indent=2)
       f.write("\n")
   console.print(f"[green]Removed extra translations from {lang_path}[/green]")
   ```
   
   This makes the control flow flatter and a bit easier to follow.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to