Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite recursion when using with Django SimpleLazyObject #1177

Closed
rkashapov opened this issue Mar 25, 2020 · 2 comments
Closed

Infinite recursion when using with Django SimpleLazyObject #1177

rkashapov opened this issue Mar 25, 2020 · 2 comments
Milestone

Comments

@rkashapov
Copy link

rkashapov commented Mar 25, 2020

Hi,
I use an object of type django.utils.functional.SimpleLazyObject as a template variable.
When an AttributeError happens in the inner of a lazy object the template rendering falls into infinite recursion.

Expected Behavior

A traceback about the attribute error is displayed.

Actual Behavior

Template rendering falls into infinite recursion.

Minimal Code To Reproduce

from django.utils.functional import SimpleLazyObject
import jinja2

def raises_attribute_error():
      raise AttributeError()

template = jinja2.Template('{{ obj.hello.recursion }}')
template.render(obj=SimpleLazyObject(lambda: raises_attribute_error()))

Full Traceback

Traceback (most recent call last):
  File "main.py", line 10, in <module>
    template.render(obj=SimpleLazyObject(lambda: raises_attribute_error()))
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/environment.py", line 471, in getattr
    return getattr(obj, attribute)
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/runtime.py", line 738, in _undefined_message
    object_type_repr(self._undefined_obj),
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/jinja2/utils.py", line 169, in object_type_repr
    if obj.__class__.__module__ in ("__builtin__", "builtins"):
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/django/utils/functional.py", line 224, in inner
    self._setup()
  File "/Users/rkashapov/Library/Python/3.7/lib/python/site-packages/django/utils/functional.py", line 360, in _setup
    self._wrapped = self._setupfunc()
  File "main.py", line 10, in <lambda>
    template.render(obj=SimpleLazyObject(lambda: raises_attribute_error()))
  File "main.py", line 6, in raises_attribute_error
    raise AttributeError()
RecursionError: maximum recursion depth exceeded while calling a Python object

Your Environment

  • Python version: 3.7.3
  • Jinja version: 2.11.1
@davidism
Copy link
Member

davidism commented Mar 27, 2020

This is due to the way that Jinja variable lookup and undefined handling works. First it tries to get the attribute hello, which raises an attribute error. Then it tries to treat the variable as a dict key, which also raises an attribute error, so it returns an undefined object. Then it tries to look up the attrribute recursion on the undefined object, which raises an undefined error, which tries to print out some information about the object (obj.__class__.__name__), which raises an attribute error again.

In this case, it's possible to fix this by changing the undefined code to use type(obj) instead.

In general, the code you've shown indicates a bad design. Avoid code that could potentially raise an AttributeError in every situation it's used, as that's a recipe for disaster, especially when looking up attributes.

@rkashapov
Copy link
Author

Thanks

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants