summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.rst4
-rw-r--r--src/zope/tales/tales.py16
-rw-r--r--src/zope/tales/tests/test_tales.py8
3 files changed, 21 insertions, 7 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index e7ec251..bbf9168 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,10 @@
5.2.0 (unreleased)
==================
+- ``tales.Context.getValue`` now returns the innermost (not outermost)
+ value for the given variable. Fixes
+ `#19 <https://github.com/zopefoundation/zope.tales/issues/19>`_.
+
- Add support for Python 3.9, 3.10.
- Fix error message raised if the first element of a path expression is not
diff --git a/src/zope/tales/tales.py b/src/zope/tales/tales.py
index d5ca006..4f9a08a 100644
--- a/src/zope/tales/tales.py
+++ b/src/zope/tales/tales.py
@@ -744,12 +744,16 @@ class Context(object):
vars[name] = value
def getValue(self, name, default=None):
- value = default
- for vars in self._vars_stack:
- value = vars.get(name, default)
- if value is not default:
- break
- return value
+ """return the current value of variable *name* or *default*."""
+ # ``beginScope`` puts a copy of all variables into ``vars``
+ # and pushes it onto ``_vars_stack``,
+ # ``endScope`` pops the last element of ``vars_stack`` into ``vars``,
+ # ``setGlobal`` updates all variable bindings in ``_vars_stack``
+ # (and thereby, implicitly, ``vars``).
+ # Consequently, the current value of a variable can
+ # always be found in ``vars``
+ # (no need to iterate over ``_vars_stack``).
+ return self.vars.get(name, default)
def setRepeat(self, name, expr):
expr = self.evaluate(expr)
diff --git a/src/zope/tales/tests/test_tales.py b/src/zope/tales/tests/test_tales.py
index 03a1fe5..508a174 100644
--- a/src/zope/tales/tests/test_tales.py
+++ b/src/zope/tales/tests/test_tales.py
@@ -134,6 +134,7 @@ class TALESTests(unittest.TestCase):
c = ctxt.vars
self.assertEqual(c['v1'], 1, 'Variable "v1"')
+ self.assertEqual(ctxt.getValue('v1'), 1, 'Variable "v1"')
ctxt.beginScope()
ctxt.setLocal('v1', 3)
@@ -141,14 +142,19 @@ class TALESTests(unittest.TestCase):
c = ctxt.vars
self.assertEqual(c['v1'], 3, 'Inner scope')
+ self.assertEqual(ctxt.getValue('v1'), 3, 'Inner scope')
self.assertEqual(c['v2'], 2, 'Outer scope')
+ self.assertEqual(ctxt.getValue('v2'), 2, 'Outer scope')
self.assertEqual(c['g'], 1, 'Global')
+ self.assertEqual(ctxt.getValue('g'), 1, 'Global')
ctxt.endScope()
c = ctxt.vars
self.assertEqual(c['v1'], 1, "Uncovered local")
+ self.assertEqual(ctxt.getValue('v1'), 1, "Uncovered local")
self.assertEqual(c['g'], 1, "Global from inner scope")
+ self.assertEqual(ctxt.getValue('g'), 1, "Global from inner scope")
ctxt.endScope()
@@ -220,7 +226,7 @@ class TestContext(unittest.TestCase):
self.context.vars['it'] = 1
self.context.beginScope()
self.context.vars['it'] = 2
- self.assertEqual(self.context.getValue('it'), 1)
+ self.assertEqual(self.context.getValue('it'), 2)
def test_evaluate_boolean(self):
# Make sure it always returns a regular bool, no matter