]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #17011: Fix caching of xpath path when namespaces are present.
authorEli Bendersky <eliben@gmail.com>
Sun, 4 Aug 2013 00:47:47 +0000 (17:47 -0700)
committerEli Bendersky <eliben@gmail.com>
Sun, 4 Aug 2013 00:47:47 +0000 (17:47 -0700)
Thanks to Stefan Behnel for the report and proposed solution & test.

Lib/test/test_xml_etree.py
Lib/xml/etree/ElementPath.py

index 4c2e26f61e4b71d6aa42c79509fc57604c9fbb3c..402bc2df2aa855104addae254ff4f4c5b2265c49 100644 (file)
@@ -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'):
index 52e65f063daef231d93dcdb0d26deadc0898e3c6..e7015c7c6186e0cc67f181fa3820c1d812371f50 100644 (file)
@@ -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)