Commit 2acc525a authored by Eli Bendersky's avatar Eli Bendersky

Issue #17011: Fix caching of xpath path when namespaces are present.

Thanks to Stefan Behnel for the report and proposed solution & test.
parent 3ceaff07
......@@ -1679,6 +1679,20 @@ class ElementFindTest(unittest.TestCase):
summarize_list(e.findall(".//{http://effbot.org/ns}tag")),
['{http://effbot.org/ns}tag'] * 3)
def test_findall_different_nsmaps(self):
root = ET.XML('''
<a xmlns:x="X" xmlns:y="Y">
<x:b><c/></x:b>
<b/>
<c><x:b/><b/></c><y:b/>
</a>''')
nsmap = {'xx': 'X'}
self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
nsmap = {'xx': 'Y'}
self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
def test_bad_find(self):
e = ET.XML(SAMPLE_XML)
with self.assertRaisesRegex(SyntaxError, 'cannot use absolute path'):
......
......@@ -246,10 +246,12 @@ class _SelectorContext:
def iterfind(elem, path, namespaces=None):
# compile selector pattern
cache_key = (path, None if namespaces is None
else tuple(sorted(namespaces.items())))
if path[-1:] == "/":
path = path + "*" # implicit all (FIXME: keep this?)
try:
selector = _cache[path]
selector = _cache[cache_key]
except KeyError:
if len(_cache) > 100:
_cache.clear()
......@@ -269,7 +271,7 @@ def iterfind(elem, path, namespaces=None):
token = next()
except StopIteration:
break
_cache[path] = selector
_cache[cache_key] = selector
# execute selector pattern
result = [elem]
context = _SelectorContext(elem)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment