Opened 8 months ago
Closed 8 months ago
#36271 closed Bug (fixed)
{% extends %} tag causes AttributeError if origin is None and path is relative
| Reported by: | Yogya Chugh | Owned by: | Yogya Chugh |
|---|---|---|---|
| Component: | Template system | Version: | dev |
| Severity: | Normal | Keywords: | extends |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
So while working on a ticket, I came across a strange behaviour that whenever I pass a relative path like './goa.html' to the extends tag that leads to an Attribution error !
I have attached a test case which will pass if error is produced ! You can check it out !
So, I tried to find the reason for this and found:-
When we separately create a Template and Context class along with calling the render method of Template, the error is produced.
This happens because in such a case the origin for the template is None hence, setting it to '<unknown source>' due to this code:-
#django/template/base.py
if origin is None:
origin = Origin(UNKNOWN_SOURCE)
Here, UNKNOWN_SOURCE is global variable with value "<unknown source>"
So this ain't an issue normally but when we use {% extends %} tag, it makes use of a function construct_relative_path which is passed the template name from origin !
The function construct_relative_path performs an lstrip method on the template leading to error in case the template's origin is "<unknown source>". Because, origin.template_name is None. And so does the lstrip method produces error .
Code Snippet:-
#django/template/loader_tags.py
new_name = posixpath.normpath(
posixpath.join(
posixpath.dirname(current_template_name.lstrip("/")),
new_name,
)
)
The Error log:-
Internal Server Error: /
Traceback (most recent call last):
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Lenovo\OneDrive\Desktop\djangoplz\new\trial\views.py", line 9, in index
temp = Template(temp_string)
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\base.py", line 154, in __init__
self.nodelist = self.compile_nodelist()
~~~~~~~~~~~~~~~~~~~~~^^
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\base.py", line 196, in compile_nodelist
nodelist = parser.parse()
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\base.py", line 518, in parse
raise self.error(token, e)
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\base.py", line 516, in parse
compiled_result = compile_func(self, token)
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\loader_tags.py", line 293, in do_extends
bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Lenovo\AppData\Roaming\Python\Python313\site-packages\django\template\loader_tags.py", line 258, in construct_relative_path
posixpath.dirname(current_template_name.lstrip("/")),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'lstrip'
This error is produced on both 5.1.7 version and on the dev too !
I would love to work on this ! Please do review
Attachments (1)
Change History (7)
by , 8 months ago
| Attachment: | test_case.py added |
|---|
comment:1 by , 8 months ago
| Summary: | {% extends %} tag causes error if origin is None and path is relative → {% extends %} tag causes AttributeError if origin is None and path is relative |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 8 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
Yup ! I will add a check condition for None template name in construct_relative_path and add test case for when the template do exist !
comment:4 by , 8 months ago
| Patch needs improvement: | set |
|---|
comment:5 by , 8 months ago
| Patch needs improvement: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
Thank you, replicated. I think this should be raising a
TemplateDoesNotExisterror instead similar to if the path was not relativetests/template_tests/syntax_tests/test_exceptions.py