[Django] #35735: For python 3.10+ class property may not be accessible by Django's template system

7 views
Skip to first unread message

Django

unread,
Sep 5, 2024, 10:35:03 AM9/5/24
to django-...@googlegroups.com
#35735: For python 3.10+ class property may not be accessible by Django's template
system
------------------------------+-------------------------------------------
Reporter: Fabian Braun | Type: Uncategorized
Status: new | Component: Template system
Version: 5.0 | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+-------------------------------------------
Prior to python 3.10 class properties were always available through the
template system. If you had a class
{{{
class MyClass:
in_template = True
}}}
you could access the class property in the template through {{
context_value.in_template }}.

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.

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.

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+:
{{{
@setup({"basic-syntax19b": "{{ dict.klass.in_template }}"})
def test_access_class_property(self):
class MyClass(list):
in_template = True

def __init__(self, non_trivial_init):
# This prevents the template system from turning the class
into an instance
return super().__init__()

output = self.engine.render_to_string("basic-syntax19b", {"dict":
dict(klass=MyClass)})
self.assertEqual(output, "True")

}}}

I'd be happy to propose a fix.
--
Ticket URL: <https://code.djangoproject.com/ticket/35735>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 5, 2024, 11:35:30 AM9/5/24
to django-...@googlegroups.com
#35735: For python 3.10+ class property may not be accessible by Django's template
system
---------------------------------+----------------------------------------
Reporter: Fabian Braun | Owner: Fabian Braun
Type: Uncategorized | Status: assigned
Component: Template system | Version: 5.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+----------------------------------------
Changes (by Fabian Braun):

* owner: (none) => Fabian Braun
* status: new => assigned


Old description:
New description:

Prior to python 3.10 class properties were always available through the
template system. If you had a class
{{{
class MyClass:
in_template = True
}}}
you could access the class property in the template through {{
context_value.in_template }}.

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.

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.

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+:
{{{
@setup({"basic-syntax19b": "{{ klass.in_template }}"})
def test_access_class_property(self):
class MyClass(list):
in_template = True

def __init__(self, non_trivial_init):
# This prevents the template system from turning the class
into an instance
return super().__init__()

output = self.engine.render_to_string("basic-syntax19b", {"klass":
MyClass})
self.assertEqual(output, "True")

}}}

I'd be happy to propose a fix.

Thanks to [https://github.com/benzkji Ben Stähli] and [https://github.com
/last-partizan Serhii Tereshchenko] for figuring out this issue.

References:

* https://github.com/django-cms/django-cms/issues/7948

--
--
Ticket URL: <https://code.djangoproject.com/ticket/35735#comment:1>
Reply all
Reply to author
Forward
0 new messages