Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Jul 30, 2025

Fixed a critical issue where template variables that shadow Python built-in function names (like dir, span, object, etc.) were being corrupted during formatting, causing templates to break.

Problem

When formatting Jinja templates, variables that happened to match Python built-in names were being removed:

<!-- Input -->
{% set dir = "example" %}
{% set foo = dir %}

<!-- Output (broken) -->
{% set dir = "example" %}
{% set foo =  %}

This made templates non-functional as the variable reference was completely removed.

Root Cause

The issue was in src/djlint/formatter/indent.py in the format_data function. When processing {% set %} tags, djLint was:

  1. Attempting to parse the right-hand side as JSON
  2. When that failed, falling back to using Python's eval() on template variables
  3. For variables like dir, eval("dir") returned the built-in dir function object
  4. The string representation of this object was processed incorrectly, ultimately causing the variable to be removed

Solution

Modified the format_data function to be more conservative about what it evaluates:

  • Only evaluate Python literals (lists, dicts, numbers, strings) that don't look like simple identifiers
  • Skip evaluation for simple identifiers that are likely template variables
  • Preserve template variables as-is instead of trying to "format" them
# Before: Would eval any content that wasn't "object"
evaluated = str(eval(contents)) if contents != "object" else contents

# After: Only eval if it's not a simple identifier
if (contents.strip() and 
    not contents.strip().isidentifier() and
    not contents.strip().startswith(('_', 'object'))):
    evaluated = str(eval(contents))
else:
    contents = contents.strip()  # Don't eval identifiers

Additional Protection

Added inside_template_block() checks in compress.py and attributes.py to prevent HTML tag processing from affecting template content.

Testing

Added comprehensive test cases covering:

  • Template variables that shadow HTML tag names (dir, span, button)
  • Template variables that shadow Python built-ins (object, dir)
  • Mixed scenarios with both template variables and HTML tags
  • Verification that Python literals can still be formatted properly

The fix is minimal, surgical, and maintains backward compatibility while preventing the dangerous evaluation of template variables.

Fixes #828.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copy link

netlify bot commented Jul 30, 2025

Deploy Preview for djlint failed.

Name Link
🔨 Latest commit a1a2091
🔍 Latest deploy log https://app.netlify.com/projects/djlint/deploys/688a6e297aff3d0007f6c4ce

@Copilot Copilot AI changed the title [WIP] [BUG] [Formatter] Shadowing built-in function breaks template Fix template variable shadowing built-in function names breaking templates Jul 30, 2025
@Copilot Copilot AI requested a review from monosans July 30, 2025 19:12
Copilot finished work on behalf of monosans July 30, 2025 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] [Formatter] Shadowing built-in function breaks template
2 participants