imrichardwu commented on code in PR #61878:
URL: https://github.com/apache/airflow/pull/61878#discussion_r2810362960


##########
airflow-core/src/airflow/serialization/helpers.py:
##########
@@ -31,6 +31,94 @@
     from airflow.timetables.base import Timetable as CoreTimetable
 
 
+def _truncate_rendered_value(rendered: str, max_length: int) -> str:
+    if max_length <= 0:
+        return ""
+
+    prefix = "Truncated. You can change this behaviour in 
[core]max_templated_field_length. "
+    suffix = "..."
+    value = str(rendered)
+
+    # Always prioritize showing the truncation message first
+    trunc_only = f"{prefix}{suffix}"
+    trunc_only_len = len(trunc_only)
+
+    # If max_length is too small to even show the message, return it anyway
+    # (message takes priority over the constraint)
+    if max_length < trunc_only_len:
+        return trunc_only
+
+    # Check if value already has outer quotes - if so, preserve them and don't 
add extra quotes
+    has_outer_quotes = (value.startswith('"') and value.endswith('"')) or (
+        value.startswith("'") and value.endswith("'")
+    )
+
+    if has_outer_quotes:
+        # Value already has quotes - preserve the opening quote, truncate 
inner content
+        quote_char = value[0]
+        inner_value = value[1:-1]  # Strip outer quotes
+        # Calculate overhead: prefix + opening quote + suffix (no closing 
quote)
+        overhead = len(prefix) + 1 + len(suffix)
+        available = max_length - overhead
+
+        MIN_CONTENT_LENGTH = 7
+        if available < MIN_CONTENT_LENGTH:
+            return trunc_only
+
+        # Get content and trim trailing spaces
+        content = inner_value[:available].rstrip()
+
+        # Build result with opening quote, content, and suffix (no closing 
quote)
+        result = f"{prefix}{quote_char}{content}{suffix}"
+
+        # Ensure result < max_length, with a buffer when possible
+        # For values with outer quotes, use a larger buffer (3) since we don't 
add closing quotes
+        target_length = max_length - 3
+        while len(result) > target_length and len(content) > 0:
+            content = content[:-1].rstrip()
+            result = f"{prefix}{quote_char}{content}{suffix}"
+
+        return result
+    # Value doesn't have outer quotes - add quotes around content
+    # Choose quote character: use double quotes if value contains single 
quotes,
+    # otherwise use single quotes
+    if "'" in value and '"' not in value:
+        quote_char = '"'
+    else:
+        quote_char = "'"
+
+    # Calculate overhead: prefix + quotes around content + suffix
+    # Format: prefix + quote_char + content + quote_char + suffix
+    overhead = len(prefix) + 2 + len(suffix)  # 2 for the quotes around content
+    available = max_length - overhead
+
+    # Only show content if there's meaningful space for it
+    # Require at least enough space to show a few characters of content 
meaningfully
+    # This prevents showing just 1-2 characters which isn't very useful
+    MIN_CONTENT_LENGTH = 7
+    if available < MIN_CONTENT_LENGTH:
+        return trunc_only
+
+    # Get content and trim trailing spaces
+    content = value[:available].rstrip()
+
+    # Build the result and ensure it doesn't exceed max_length
+    result = f"{prefix}{quote_char}{content}{quote_char}{suffix}"
+
+    # Trim content to ensure result < max_length, with a small buffer when 
possible
+    # Trim until result is at least 1 char under max_length to leave a buffer
+    target_length = max_length - 1
+    while len(result) > target_length and len(content) > 0:
+        content = content[:-1].rstrip()
+        result = f"{prefix}{quote_char}{content}{quote_char}{suffix}"
+
+    return result
+
+
+def _safe_truncate_rendered_value(rendered: Any, max_length: int) -> str:
+    return _truncate_rendered_value(str(rendered), max_length)

Review Comment:
   I had already reviewed everything the reviewers commented on and ensured 
that my code addressed all gaps. Also, my pr only took a bit of code from the 
old pr's, as it did have some issues, as you noted.



-- 
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