annotate Lib/xml/etree/ElementPath.py @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents ce0be0d03c0a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
1 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
2 # ElementTree
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
3 # $Id: ElementPath.py 3375 2008-02-13 08:05:08Z fredrik $
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
4 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
5 # limited xpath support for element trees
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
6 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
7 # history:
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
8 # 2003-05-23 fl created
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
9 # 2003-05-28 fl added support for // etc
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
10 # 2003-08-27 fl fixed parsing of periods in element names
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
11 # 2007-09-10 fl new selection engine
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
12 # 2007-09-12 fl fixed parent selector
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
13 # 2007-09-13 fl added iterfind; changed findall to return a list
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
14 # 2007-11-30 fl added namespaces support
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
15 # 2009-10-30 fl added child element value filter
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
16 #
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
17 # Copyright (c) 2003-2009 by Fredrik Lundh. All rights reserved.
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
18 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
19 # fredrik@pythonware.com
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
20 # http://www.pythonware.com
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
21 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
22 # --------------------------------------------------------------------
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
23 # The ElementTree toolkit is
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
24 #
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
25 # Copyright (c) 1999-2009 by Fredrik Lundh
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
26 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
27 # By obtaining, using, and/or copying this software and/or its
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
28 # associated documentation, you agree that you have read, understood,
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
29 # and will comply with the following terms and conditions:
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
30 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
31 # Permission to use, copy, modify, and distribute this software and
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
32 # its associated documentation for any purpose and without fee is
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
33 # hereby granted, provided that the above copyright notice appears in
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
34 # all copies, and that both that copyright notice and this permission
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
35 # notice appear in supporting documentation, and that the name of
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
36 # Secret Labs AB or the author not be used in advertising or publicity
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
37 # pertaining to distribution of the software without specific, written
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
38 # prior permission.
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
39 #
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
40 # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
41 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
42 # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
43 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
44 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
45 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
46 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
47 # OF THIS SOFTWARE.
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
48 # --------------------------------------------------------------------
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
49
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
50 # Licensed to PSF under a Contributor Agreement.
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
51 # See http://www.python.org/psf/license for licensing details.
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
52
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
53 ##
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
54 # Implementation module for XPath support. There's usually no reason
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
55 # to import this module directly; the <b>ElementTree</b> does this for
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
56 # you, if needed.
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
57 ##
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
58
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
59 import re
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
60
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
61 xpath_tokenizer_re = re.compile(
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
62 "("
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
63 "'[^']*'|\"[^\"]*\"|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
64 "::|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
65 "//?|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
66 "\.\.|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
67 "\(\)|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
68 "[/.*:\[\]\(\)@=])|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
69 "((?:\{[^}]+\})?[^/\[\]\(\)@=\s]+)|"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
70 "\s+"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
71 )
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
72
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
73 def xpath_tokenizer(pattern, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
74 for token in xpath_tokenizer_re.findall(pattern):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
75 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
76 if tag and tag[0] != "{" and ":" in tag:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
77 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
78 prefix, uri = tag.split(":", 1)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
79 if not namespaces:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
80 raise KeyError
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
81 yield token[0], "{%s}%s" % (namespaces[prefix], uri)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
82 except KeyError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
83 raise SyntaxError("prefix %r not found in prefix map" % prefix)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
84 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
85 yield token
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
86
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
87 def get_parent_map(context):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
88 parent_map = context.parent_map
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
89 if parent_map is None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
90 context.parent_map = parent_map = {}
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
91 for p in context.root.iter():
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
92 for e in p:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
93 parent_map[e] = p
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
94 return parent_map
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
95
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
96 def prepare_child(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
97 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
98 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
99 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
100 for e in elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
101 if e.tag == tag:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
102 yield e
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
103 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
104
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
105 def prepare_star(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
106 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
107 for elem in result:
79389
33a221662f39 more yield from
Philip Jenvey <pjenvey@underboss.org>
parents: 59601
diff changeset
108 yield from elem
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
109 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
110
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
111 def prepare_self(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
112 def select(context, result):
79389
33a221662f39 more yield from
Philip Jenvey <pjenvey@underboss.org>
parents: 59601
diff changeset
113 yield from result
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
114 return select
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
115
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
116 def prepare_descendant(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
117 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
118 if token[0] == "*":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
119 tag = "*"
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
120 elif not token[0]:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
121 tag = token[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
122 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
123 raise SyntaxError("invalid descendant")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
124 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
125 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
126 for e in elem.iter(tag):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
127 if e is not elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
128 yield e
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
129 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
130
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
131 def prepare_parent(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
132 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
133 # FIXME: raise error if .. is applied at toplevel?
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
134 parent_map = get_parent_map(context)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
135 result_map = {}
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
136 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
137 if elem in parent_map:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
138 parent = parent_map[elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
139 if parent not in result_map:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
140 result_map[parent] = None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
141 yield parent
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
142 return select
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
143
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
144 def prepare_predicate(next, token):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
145 # FIXME: replace with real parser!!! refs:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
146 # http://effbot.org/zone/simple-iterator-parser.htm
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
147 # http://javascript.crockford.com/tdop/tdop.html
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
148 signature = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
149 predicate = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
150 while 1:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
151 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
152 if token[0] == "]":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
153 break
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
154 if token[0] and token[0][:1] in "'\"":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
155 token = "'", token[0][1:-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
156 signature.append(token[0] or "-")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
157 predicate.append(token[1])
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
158 signature = "".join(signature)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
159 # use signature to determine predicate type
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
160 if signature == "@-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
161 # [@attribute] predicate
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
162 key = predicate[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
163 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
164 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
165 if elem.get(key) is not None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
166 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
167 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
168 if signature == "@-='":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
169 # [@attribute='value']
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
170 key = predicate[1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
171 value = predicate[-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
172 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
173 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
174 if elem.get(key) == value:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
175 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
176 return select
81681
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
177 if signature == "-" and not re.match("\-?\d+$", predicate[0]):
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
178 # [tag]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
179 tag = predicate[0]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
180 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
181 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
182 if elem.find(tag) is not None:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
183 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
184 return select
81681
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
185 if signature == "-='" and not re.match("\-?\d+$", predicate[0]):
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
186 # [tag='value']
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
187 tag = predicate[0]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
188 value = predicate[-1]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
189 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
190 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
191 for e in elem.findall(tag):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
192 if "".join(e.itertext()) == value:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
193 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
194 break
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
195 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
196 if signature == "-" or signature == "-()" or signature == "-()-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
197 # [index] or [last()] or [last()-index]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
198 if signature == "-":
81681
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
199 # [index]
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
200 index = int(predicate[0]) - 1
81681
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
201 if index < 0:
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
202 raise SyntaxError("XPath position >= 1 expected")
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
203 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
204 if predicate[0] != "last":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
205 raise SyntaxError("unsupported function")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
206 if signature == "-()-":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
207 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
208 index = int(predicate[2]) - 1
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
209 except ValueError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
210 raise SyntaxError("unsupported expression")
81681
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
211 if index > -2:
56a4561600ad Issue #12323: Strengthen error checking of the position XPath selectors
Eli Bendersky <eliben@gmail.com>
parents: 79389
diff changeset
212 raise SyntaxError("XPath offset from last() must be negative")
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
213 else:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
214 index = -1
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
215 def select(context, result):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
216 parent_map = get_parent_map(context)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
217 for elem in result:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
218 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
219 parent = parent_map[elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
220 # FIXME: what if the selector is "*" ?
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
221 elems = list(parent.findall(elem.tag))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
222 if elems[index] is elem:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
223 yield elem
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
224 except (IndexError, KeyError):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
225 pass
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
226 return select
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
227 raise SyntaxError("invalid predicate")
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
228
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
229 ops = {
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
230 "": prepare_child,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
231 "*": prepare_star,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
232 ".": prepare_self,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
233 "..": prepare_parent,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
234 "//": prepare_descendant,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
235 "[": prepare_predicate,
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
236 }
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
237
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
238 _cache = {}
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
239
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
240 class _SelectorContext:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
241 parent_map = None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
242 def __init__(self, root):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
243 self.root = root
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
244
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
245 # --------------------------------------------------------------------
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
246
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
247 ##
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
248 # Generate all matching objects.
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
249
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
250 def iterfind(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
251 # compile selector pattern
85005
854ded9135c2 Issue #17011: Fix caching of xpath path when namespaces are present.
Eli Bendersky <eliben@gmail.com>
parents: 59601
diff changeset
252 cache_key = (path, None if namespaces is None
854ded9135c2 Issue #17011: Fix caching of xpath path when namespaces are present.
Eli Bendersky <eliben@gmail.com>
parents: 59601
diff changeset
253 else tuple(sorted(namespaces.items())))
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
254 if path[-1:] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
255 path = path + "*" # implicit all (FIXME: keep this?)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
256 try:
85005
854ded9135c2 Issue #17011: Fix caching of xpath path when namespaces are present.
Eli Bendersky <eliben@gmail.com>
parents: 59601
diff changeset
257 selector = _cache[cache_key]
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
258 except KeyError:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
259 if len(_cache) > 100:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
260 _cache.clear()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
261 if path[:1] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
262 raise SyntaxError("cannot use absolute path on element")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
263 next = iter(xpath_tokenizer(path, namespaces)).__next__
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
264 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
265 selector = []
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
266 while 1:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
267 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
268 selector.append(ops[token[0]](next, token))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
269 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
270 raise SyntaxError("invalid path")
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
271 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
272 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
273 if token[0] == "/":
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
274 token = next()
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
275 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
276 break
85005
854ded9135c2 Issue #17011: Fix caching of xpath path when namespaces are present.
Eli Bendersky <eliben@gmail.com>
parents: 59601
diff changeset
277 _cache[cache_key] = selector
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
278 # execute selector pattern
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
279 result = [elem]
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
280 context = _SelectorContext(elem)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
281 for select in selector:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
282 result = select(context, result)
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
283 return result
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
284
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
285 ##
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
286 # Find first matching object.
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
287
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
288 def find(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
289 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
290 return next(iterfind(elem, path, namespaces))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
291 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
292 return None
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
293
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
294 ##
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
295 # Find all matching objects.
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
296
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
297 def findall(elem, path, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
298 return list(iterfind(elem, path, namespaces))
39275
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
299
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
300 ##
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
301 # Find text for first matching object.
cb1e432b4919 expunge the xmlcore changes:
Fred Drake <fdrake@acm.org>
parents:
diff changeset
302
59601
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
303 def findtext(elem, path, default=None, namespaces=None):
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
304 try:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
305 elem = next(iterfind(elem, path, namespaces))
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
306 return elem.text or ""
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
307 except StopIteration:
7a18c2762886 Merged revisions 78838-78839,78917,78919,78934,78937 via svnmerge from
Florent Xicluna <florent.xicluna@gmail.com>
parents: 39275
diff changeset
308 return default