#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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