Perform resolution of a real variable (i.e. not a literal) against the given context. As indicated by the method's name, this method is an implementation detail and shouldn't be called by external code. Use Variable.resolve() instead.
(self, context)
| 962 | return self.var |
| 963 | |
| 964 | def _resolve_lookup(self, context): |
| 965 | """ |
| 966 | Perform resolution of a real variable (i.e. not a literal) against the |
| 967 | given context. |
| 968 | |
| 969 | As indicated by the method's name, this method is an implementation |
| 970 | detail and shouldn't be called by external code. Use Variable.resolve() |
| 971 | instead. |
| 972 | """ |
| 973 | current = context |
| 974 | try: # catch-all for silent variable failures |
| 975 | for bit in self.lookups: |
| 976 | try: # dictionary lookup |
| 977 | # Only allow if the metaclass implements __getitem__. See |
| 978 | # https://docs.python.org/3/reference/datamodel.html#classgetitem-versus-getitem |
| 979 | if not hasattr(type(current), "__getitem__"): |
| 980 | raise TypeError |
| 981 | current = current[bit] |
| 982 | # ValueError/IndexError are for numpy.array lookup on |
| 983 | # numpy < 1.9 and 1.9+ respectively |
| 984 | except (TypeError, AttributeError, KeyError, ValueError, IndexError): |
| 985 | try: # attribute lookup |
| 986 | # Don't return class attributes if the class is the |
| 987 | # context: |
| 988 | if isinstance(current, BaseContext) and getattr( |
| 989 | type(current), bit |
| 990 | ): |
| 991 | raise AttributeError |
| 992 | current = getattr(current, bit) |
| 993 | except (TypeError, AttributeError): |
| 994 | # Reraise if the exception was raised by a @property |
| 995 | if not isinstance(current, BaseContext) and bit in dir(current): |
| 996 | raise |
| 997 | try: # list-index lookup |
| 998 | current = current[int(bit)] |
| 999 | except ( |
| 1000 | IndexError, # list index out of range |
| 1001 | ValueError, # invalid literal for int() |
| 1002 | KeyError, # current is a dict without `int(bit)` key |
| 1003 | TypeError, |
| 1004 | ): # unsubscriptable object |
| 1005 | raise VariableDoesNotExist( |
| 1006 | "Failed lookup for key [%s] in %r", |
| 1007 | (bit, current), |
| 1008 | ) # missing attribute |
| 1009 | if callable(current): |
| 1010 | if getattr(current, "do_not_call_in_templates", False): |
| 1011 | pass |
| 1012 | elif getattr(current, "alters_data", False): |
| 1013 | current = context.template.engine.string_if_invalid |
| 1014 | else: |
| 1015 | try: # method call (assuming no args required) |
| 1016 | current = current() |
| 1017 | except TypeError: |
| 1018 | try: |
| 1019 | current_signature = signature(current) |
| 1020 | except ValueError: # No signature found. |
| 1021 | current = context.template.engine.string_if_invalid |
no test coverage detected