Changes between Version 1 and Version 2 of Ticket #35735
- Timestamp:
- Sep 5, 2024, 12:41:44 PM (3 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Ticket #35735
- Property Summary For python 3.10+ class property may not be accessible by Django's template system → For python 3.9+ class property may not be accessible by Django's template system
- Property Type Uncategorized → Bug
-
Ticket #35735 – Description
v1 v2 1 Prior to python 3.10class properties were always available through the template system. If you had a class1 Before python 3.9 class properties were always available through the template system. If you had a class 2 2 {{{ 3 3 class MyClass: 4 4 in_template = True 5 5 }}} 6 you could access the class property in the template through {{ context_value.in_template }}.6 you could access the class property in the template through (if it was returned by a callable) `{{ get_my_class.in_template }}`. 7 7 8 The template system first checks if the class is subscriptable (i.e. tries context_value["in_template"]), will fail with thatand then will get the in_template property.8 The 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. 9 9 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 effectivelyhides class properties from the template system.10 As 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. 11 11 12 12 Here'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+: … … 17 17 in_template = True 18 18 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 22 21 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 ) 24 28 self.assertEqual(output, "True") 25 26 29 }}} 27 30 28 I'd be happy to propose a fix .31 I'd be happy to propose a fix that will not call a classes' `__class_getitem__` method. 29 32 30 33 Thanks to [https://github.com/benzkji Ben Stähli] and [https://github.com/last-partizan Serhii Tereshchenko] for figuring out this issue.