Changes between Version 1 and Version 2 of Ticket #35735


Ignore:
Timestamp:
Sep 5, 2024, 12:41:44 PM (2 weeks ago)
Author:
Fabian Braun
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #35735

    • Property Summary For python 3.10+ class property may not be accessible by Django's template systemFor python 3.9+ class property may not be accessible by Django's template system
    • Property Type UncategorizedBug
  • Ticket #35735 – Description

    v1 v2  
    1 Prior to python 3.10 class properties were always available through the template system. If you had a class
     1Before python 3.9 class properties were always available through the template system. If you had a class
    22{{{
    33class MyClass:
    44    in_template = True
    55}}}
    6 you could access the class property in the template through {{ context_value.in_template }}.
     6you could access the class property in the template through (if it was returned by a callable) `{{ get_my_class.in_template }}`.
    77
    8 The template system first checks if the class is subscriptable (i.e. tries context_value["in_template"]), will fail with that and then will get the in_template property.
     8The template system first checks if the class is subscriptable (i.e. tries `context_value["in_template"]`), will fail and then will get the in_template property.
    99
    10 As of Python 3.10 some classes actually are subscriptable and trying to get the item will not fail: Typing shortcuts introduced syntax like `list[int]`. This effectively hides class properties from the template system.
     10As of python 3.9 some classes actually are subscriptable and trying to get the item will not fail: Typing shortcuts introduced syntax like `list[int]`. This hides class properties from the template system.
    1111
    1212Here's a test (that might go into tests/template_tests/syntax_tests/tests_basic.py) which passes on Python 3.9 and fails on Python 3.10+:
     
    1717            in_template = True
    1818
    19             def __init__(self, non_trivial_init):
    20                 # This prevents the template system from turning the class into an instance
    21                 return super().__init__()
     19        def get_my_class():
     20            return MyClass
    2221
    23         output = self.engine.render_to_string("basic-syntax19b", {"klass": MyClass})
     22        # Pass the callable to return the class, or it would be resolved by the template
     23        # engine
     24        output = self.engine.render_to_string(
     25            "basic-syntax19b",
     26            {"klass": get_my_class}
     27        )
    2428        self.assertEqual(output, "True")
    25 
    2629}}}
    2730
    28 I'd be happy to propose a fix.
     31I'd be happy to propose a fix that will not call a classes' `__class_getitem__` method.
    2932
    3033Thanks to [https://github.com/benzkji Ben Stähli] and [https://github.com/last-partizan Serhii Tereshchenko] for figuring out this issue.
Back to Top