#28782: Template variable resolution on objects that are no mappings but 
implement
__getitem__
-------------------------------------+-------------------------------------
               Reporter:  Frank      |          Owner:  Frank Sachsenheim
  Sachsenheim                        |
                   Type:  Bug        |         Status:  assigned
              Component:  Template   |        Version:  master
  system                             |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 there are classes in the Pythoniverse that implement a `__getitem__`
 method for the sake of syntactical sweetness, but they are no mappings.
 (in my case it's a wrapper around an xml document where `__getitem__`
 returns the result of xpath evaluations. there are other use-cases around,
 but i don't remember any atm.).
 this causes a lookup in a template rendering context on an attribute of
 such instances to return an unexpected value, because `foo[bar]` doesn't
 necessarily raise an exception and returns some value, while `foo.bar` was
 intended. this is caused by the very implicit implementation of
 `django.template.base.Variable._resolve_lookup`.

 my approach to solve this issue is to refactor that method to an explicit
 behaviour mainly based on type checks, so a member lookup is only
 performed on instances that base on `collections.abc.Mapping` which any
 implementation of a mapping should. my rationale is that the
 documentations mentions a dictionary (though
 [https://docs.python.org/3/glossary.html#term-mapping mapping] would be
 more precise term) lookup, not a lookup via `__getitem__`, and
 dictionary/mapping objects should base on the mentioned abstract class
 (the why is elaborated in
 [https://www.python.org/dev/peps/pep-3119/#rationale PEP 3119]).

 beside solving my problem, i would argue that in doubt "explicit is better
 than implicit" excels "it's better to ask forgiveness than to ask
 permission" and the explicit approach is more comprehensible.

 atm i got this working for all tests in `template_tests`, but still need
 to figure out why some more complex tests fail.

 so, i could need some feedback at this point before i continue. one
 question is whether access to non-mappings via `__getitem__` should be
 supported as last resort with a deprecation warning.

 two related issues came up while working on it:

 1) i didn't research why this was implemented, but the possiblity to
 lookup attributes on context objects is rather ambigious imo. could this
 design decision be reverted? (sidenote: using `SimpleNamespace` objects as
 context seems reasonable though, and they can easily be converted to a
 mapping with `vars`.)
 2) it seems to me that `django.template.context.Basecontext` could be
 based on `collections.ChainMap` and it may then even allow to simplify the
 `…._resolve_lookup` implementation. shall i give it a shot while i'm at
 it?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28782>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/054.bccdbcba2069b6cf0064341e2e508030%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to