#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.