Merge lp:~gz/bzr/trivial_util_remove_elementtree into lp:bzr
- trivial_util_remove_elementtree
- Merge into bzr.dev
Proposed by
Martin Packman
Status: | Merged |
---|---|
Approved by: | Vincent Ladeuil |
Approved revision: | no longer in the source branch. |
Merged at revision: | 6432 |
Proposed branch: | lp:~gz/bzr/trivial_util_remove_elementtree |
Merge into: | lp:bzr |
Diff against target: |
1359 lines (+15/-1312) 3 files modified
bzrlib/util/elementtree/ElementTree.py (+0/-1256) bzrlib/util/elementtree/__init__.py (+0/-32) bzrlib/xml_serializer.py (+15/-24) |
To merge this branch: | bzr merge lp:~gz/bzr/trivial_util_remove_elementtree |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vincent Ladeuil | Approve | ||
Review via email: mp+87609@code.launchpad.net |
Commit message
Remove bzrlib/
Description of the change
Remove the effbot package from util which isn't used anywhere. The tools/http_
To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote : | # |
For the confused, I mixed up the merge proposal descriptions for this and <lp:~gz/bzr/trivial_util_remove_effbot>.
Revision history for this message
Martin Packman (gz) wrote : | # |
sent to pqm by email
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed directory 'bzrlib/util/elementtree' |
2 | === removed file 'bzrlib/util/elementtree/ElementTree.py' |
3 | --- bzrlib/util/elementtree/ElementTree.py 2011-12-18 15:28:38 +0000 |
4 | +++ bzrlib/util/elementtree/ElementTree.py 1970-01-01 00:00:00 +0000 |
5 | @@ -1,1256 +0,0 @@ |
6 | -# |
7 | -# ElementTree |
8 | -# $Id: ElementTree.py 2326 2005-03-17 07:45:21Z fredrik $ |
9 | -# |
10 | -# light-weight XML support for Python 1.5.2 and later. |
11 | -# |
12 | -# history: |
13 | -# 2001-10-20 fl created (from various sources) |
14 | -# 2001-11-01 fl return root from parse method |
15 | -# 2002-02-16 fl sort attributes in lexical order |
16 | -# 2002-04-06 fl TreeBuilder refactoring, added PythonDoc markup |
17 | -# 2002-05-01 fl finished TreeBuilder refactoring |
18 | -# 2002-07-14 fl added basic namespace support to ElementTree.write |
19 | -# 2002-07-25 fl added QName attribute support |
20 | -# 2002-10-20 fl fixed encoding in write |
21 | -# 2002-11-24 fl changed default encoding to ascii; fixed attribute encoding |
22 | -# 2002-11-27 fl accept file objects or file names for parse/write |
23 | -# 2002-12-04 fl moved XMLTreeBuilder back to this module |
24 | -# 2003-01-11 fl fixed entity encoding glitch for us-ascii |
25 | -# 2003-02-13 fl added XML literal factory |
26 | -# 2003-02-21 fl added ProcessingInstruction/PI factory |
27 | -# 2003-05-11 fl added tostring/fromstring helpers |
28 | -# 2003-05-26 fl added ElementPath support |
29 | -# 2003-07-05 fl added makeelement factory method |
30 | -# 2003-07-28 fl added more well-known namespace prefixes |
31 | -# 2003-08-15 fl fixed typo in ElementTree.findtext (Thomas Dartsch) |
32 | -# 2003-09-04 fl fall back on emulator if ElementPath is not installed |
33 | -# 2003-10-31 fl markup updates |
34 | -# 2003-11-15 fl fixed nested namespace bug |
35 | -# 2004-03-28 fl added XMLID helper |
36 | -# 2004-06-02 fl added default support to findtext |
37 | -# 2004-06-08 fl fixed encoding of non-ascii element/attribute names |
38 | -# 2004-08-23 fl take advantage of post-2.1 expat features |
39 | -# 2005-02-01 fl added iterparse implementation |
40 | -# 2005-03-02 fl fixed iterparse support for pre-2.2 versions |
41 | -# |
42 | -# Copyright (c) 1999-2005 by Fredrik Lundh. All rights reserved. |
43 | -# |
44 | -# fredrik@pythonware.com |
45 | -# http://www.pythonware.com |
46 | -# |
47 | -# -------------------------------------------------------------------- |
48 | -# The ElementTree toolkit is |
49 | -# |
50 | -# Copyright (c) 1999-2005 by Fredrik Lundh |
51 | -# |
52 | -# By obtaining, using, and/or copying this software and/or its |
53 | -# associated documentation, you agree that you have read, understood, |
54 | -# and will comply with the following terms and conditions: |
55 | -# |
56 | -# Permission to use, copy, modify, and distribute this software and |
57 | -# its associated documentation for any purpose and without fee is |
58 | -# hereby granted, provided that the above copyright notice appears in |
59 | -# all copies, and that both that copyright notice and this permission |
60 | -# notice appear in supporting documentation, and that the name of |
61 | -# Secret Labs AB or the author not be used in advertising or publicity |
62 | -# pertaining to distribution of the software without specific, written |
63 | -# prior permission. |
64 | -# |
65 | -# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD |
66 | -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- |
67 | -# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR |
68 | -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY |
69 | -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
70 | -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS |
71 | -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
72 | -# OF THIS SOFTWARE. |
73 | -# -------------------------------------------------------------------- |
74 | - |
75 | -from __future__ import absolute_import |
76 | - |
77 | -__all__ = [ |
78 | - # public symbols |
79 | - "Comment", |
80 | - "dump", |
81 | - "Element", "ElementTree", |
82 | - "fromstring", |
83 | - "iselement", "iterparse", |
84 | - "parse", |
85 | - "PI", "ProcessingInstruction", |
86 | - "QName", |
87 | - "SubElement", |
88 | - "tostring", |
89 | - "TreeBuilder", |
90 | - "VERSION", "XML", |
91 | - "XMLTreeBuilder", |
92 | - ] |
93 | - |
94 | -## |
95 | -# The <b>Element</b> type is a flexible container object, designed to |
96 | -# store hierarchical data structures in memory. The type can be |
97 | -# described as a cross between a list and a dictionary. |
98 | -# <p> |
99 | -# Each element has a number of properties associated with it: |
100 | -# <ul> |
101 | -# <li>a <i>tag</i>. This is a string identifying what kind of data |
102 | -# this element represents (the element type, in other words).</li> |
103 | -# <li>a number of <i>attributes</i>, stored in a Python dictionary.</li> |
104 | -# <li>a <i>text</i> string.</li> |
105 | -# <li>an optional <i>tail</i> string.</li> |
106 | -# <li>a number of <i>child elements</i>, stored in a Python sequence</li> |
107 | -# </ul> |
108 | -# |
109 | -# To create an element instance, use the {@link #Element} or {@link |
110 | -# #SubElement} factory functions. |
111 | -# <p> |
112 | -# The {@link #ElementTree} class can be used to wrap an element |
113 | -# structure, and convert it from and to XML. |
114 | -## |
115 | - |
116 | -import string, sys, re |
117 | - |
118 | -class _SimpleElementPath: |
119 | - # emulate pre-1.2 find/findtext/findall behaviour |
120 | - def find(self, element, tag): |
121 | - for elem in element: |
122 | - if elem.tag == tag: |
123 | - return elem |
124 | - return None |
125 | - def findtext(self, element, tag, default=None): |
126 | - for elem in element: |
127 | - if elem.tag == tag: |
128 | - return elem.text or "" |
129 | - return default |
130 | - def findall(self, element, tag): |
131 | - if tag[:3] == ".//": |
132 | - return element.getiterator(tag[3:]) |
133 | - result = [] |
134 | - for elem in element: |
135 | - if elem.tag == tag: |
136 | - result.append(elem) |
137 | - return result |
138 | - |
139 | -try: |
140 | - import ElementPath |
141 | -except ImportError: |
142 | - # FIXME: issue warning in this case? |
143 | - ElementPath = _SimpleElementPath() |
144 | - |
145 | -# TODO: add support for custom namespace resolvers/default namespaces |
146 | -# TODO: add improved support for incremental parsing |
147 | - |
148 | -VERSION = "1.2.6" |
149 | - |
150 | -## |
151 | -# Internal element class. This class defines the Element interface, |
152 | -# and provides a reference implementation of this interface. |
153 | -# <p> |
154 | -# You should not create instances of this class directly. Use the |
155 | -# appropriate factory functions instead, such as {@link #Element} |
156 | -# and {@link #SubElement}. |
157 | -# |
158 | -# @see Element |
159 | -# @see SubElement |
160 | -# @see Comment |
161 | -# @see ProcessingInstruction |
162 | - |
163 | -class _ElementInterface: |
164 | - # <tag attrib>text<child/>...</tag>tail |
165 | - |
166 | - ## |
167 | - # (Attribute) Element tag. |
168 | - |
169 | - tag = None |
170 | - |
171 | - ## |
172 | - # (Attribute) Element attribute dictionary. Where possible, use |
173 | - # {@link #_ElementInterface.get}, |
174 | - # {@link #_ElementInterface.set}, |
175 | - # {@link #_ElementInterface.keys}, and |
176 | - # {@link #_ElementInterface.items} to access |
177 | - # element attributes. |
178 | - |
179 | - attrib = None |
180 | - |
181 | - ## |
182 | - # (Attribute) Text before first subelement. This is either a |
183 | - # string or the value None, if there was no text. |
184 | - |
185 | - text = None |
186 | - |
187 | - ## |
188 | - # (Attribute) Text after this element's end tag, but before the |
189 | - # next sibling element's start tag. This is either a string or |
190 | - # the value None, if there was no text. |
191 | - |
192 | - tail = None # text after end tag, if any |
193 | - |
194 | - def __init__(self, tag, attrib): |
195 | - self.tag = tag |
196 | - self.attrib = attrib |
197 | - self._children = [] |
198 | - |
199 | - def __repr__(self): |
200 | - return "<Element %s at %x>" % (self.tag, id(self)) |
201 | - |
202 | - ## |
203 | - # Creates a new element object of the same type as this element. |
204 | - # |
205 | - # @param tag Element tag. |
206 | - # @param attrib Element attributes, given as a dictionary. |
207 | - # @return A new element instance. |
208 | - |
209 | - def makeelement(self, tag, attrib): |
210 | - return Element(tag, attrib) |
211 | - |
212 | - ## |
213 | - # Returns the number of subelements. |
214 | - # |
215 | - # @return The number of subelements. |
216 | - |
217 | - def __len__(self): |
218 | - return len(self._children) |
219 | - |
220 | - ## |
221 | - # Returns the given subelement. |
222 | - # |
223 | - # @param index What subelement to return. |
224 | - # @return The given subelement. |
225 | - # @exception IndexError If the given element does not exist. |
226 | - |
227 | - def __getitem__(self, index): |
228 | - return self._children[index] |
229 | - |
230 | - ## |
231 | - # Replaces the given subelement. |
232 | - # |
233 | - # @param index What subelement to replace. |
234 | - # @param element The new element value. |
235 | - # @exception IndexError If the given element does not exist. |
236 | - # @exception AssertionError If element is not a valid object. |
237 | - |
238 | - def __setitem__(self, index, element): |
239 | - assert iselement(element) |
240 | - self._children[index] = element |
241 | - |
242 | - ## |
243 | - # Deletes the given subelement. |
244 | - # |
245 | - # @param index What subelement to delete. |
246 | - # @exception IndexError If the given element does not exist. |
247 | - |
248 | - def __delitem__(self, index): |
249 | - del self._children[index] |
250 | - |
251 | - ## |
252 | - # Returns a list containing subelements in the given range. |
253 | - # |
254 | - # @param start The first subelement to return. |
255 | - # @param stop The first subelement that shouldn't be returned. |
256 | - # @return A sequence object containing subelements. |
257 | - |
258 | - def __getslice__(self, start, stop): |
259 | - return self._children[start:stop] |
260 | - |
261 | - ## |
262 | - # Replaces a number of subelements with elements from a sequence. |
263 | - # |
264 | - # @param start The first subelement to replace. |
265 | - # @param stop The first subelement that shouldn't be replaced. |
266 | - # @param elements A sequence object with zero or more elements. |
267 | - # @exception AssertionError If a sequence member is not a valid object. |
268 | - |
269 | - def __setslice__(self, start, stop, elements): |
270 | - for element in elements: |
271 | - assert iselement(element) |
272 | - self._children[start:stop] = list(elements) |
273 | - |
274 | - ## |
275 | - # Deletes a number of subelements. |
276 | - # |
277 | - # @param start The first subelement to delete. |
278 | - # @param stop The first subelement to leave in there. |
279 | - |
280 | - def __delslice__(self, start, stop): |
281 | - del self._children[start:stop] |
282 | - |
283 | - ## |
284 | - # Adds a subelement to the end of this element. |
285 | - # |
286 | - # @param element The element to add. |
287 | - # @exception AssertionError If a sequence member is not a valid object. |
288 | - |
289 | - def append(self, element): |
290 | - assert iselement(element) |
291 | - self._children.append(element) |
292 | - |
293 | - ## |
294 | - # Inserts a subelement at the given position in this element. |
295 | - # |
296 | - # @param index Where to insert the new subelement. |
297 | - # @exception AssertionError If the element is not a valid object. |
298 | - |
299 | - def insert(self, index, element): |
300 | - assert iselement(element) |
301 | - self._children.insert(index, element) |
302 | - |
303 | - ## |
304 | - # Removes a matching subelement. Unlike the <b>find</b> methods, |
305 | - # this method compares elements based on identity, not on tag |
306 | - # value or contents. |
307 | - # |
308 | - # @param element What element to remove. |
309 | - # @exception ValueError If a matching element could not be found. |
310 | - # @exception AssertionError If the element is not a valid object. |
311 | - |
312 | - def remove(self, element): |
313 | - assert iselement(element) |
314 | - self._children.remove(element) |
315 | - |
316 | - ## |
317 | - # Returns all subelements. The elements are returned in document |
318 | - # order. |
319 | - # |
320 | - # @return A list of subelements. |
321 | - # @defreturn list of Element instances |
322 | - |
323 | - def getchildren(self): |
324 | - return self._children |
325 | - |
326 | - ## |
327 | - # Finds the first matching subelement, by tag name or path. |
328 | - # |
329 | - # @param path What element to look for. |
330 | - # @return The first matching element, or None if no element was found. |
331 | - # @defreturn Element or None |
332 | - |
333 | - def find(self, path): |
334 | - return ElementPath.find(self, path) |
335 | - |
336 | - ## |
337 | - # Finds text for the first matching subelement, by tag name or path. |
338 | - # |
339 | - # @param path What element to look for. |
340 | - # @param default What to return if the element was not found. |
341 | - # @return The text content of the first matching element, or the |
342 | - # default value no element was found. Note that if the element |
343 | - # has is found, but has no text content, this method returns an |
344 | - # empty string. |
345 | - # @defreturn string |
346 | - |
347 | - def findtext(self, path, default=None): |
348 | - return ElementPath.findtext(self, path, default) |
349 | - |
350 | - ## |
351 | - # Finds all matching subelements, by tag name or path. |
352 | - # |
353 | - # @param path What element to look for. |
354 | - # @return A list or iterator containing all matching elements, |
355 | - # in document order. |
356 | - # @defreturn list of Element instances |
357 | - |
358 | - def findall(self, path): |
359 | - return ElementPath.findall(self, path) |
360 | - |
361 | - ## |
362 | - # Resets an element. This function removes all subelements, clears |
363 | - # all attributes, and sets the text and tail attributes to None. |
364 | - |
365 | - def clear(self): |
366 | - self.attrib.clear() |
367 | - self._children = [] |
368 | - self.text = self.tail = None |
369 | - |
370 | - ## |
371 | - # Gets an element attribute. |
372 | - # |
373 | - # @param key What attribute to look for. |
374 | - # @param default What to return if the attribute was not found. |
375 | - # @return The attribute value, or the default value, if the |
376 | - # attribute was not found. |
377 | - # @defreturn string or None |
378 | - |
379 | - def get(self, key, default=None): |
380 | - return self.attrib.get(key, default) |
381 | - |
382 | - ## |
383 | - # Sets an element attribute. |
384 | - # |
385 | - # @param key What attribute to set. |
386 | - # @param value The attribute value. |
387 | - |
388 | - def set(self, key, value): |
389 | - self.attrib[key] = value |
390 | - |
391 | - ## |
392 | - # Gets a list of attribute names. The names are returned in an |
393 | - # arbitrary order (just like for an ordinary Python dictionary). |
394 | - # |
395 | - # @return A list of element attribute names. |
396 | - # @defreturn list of strings |
397 | - |
398 | - def keys(self): |
399 | - return self.attrib.keys() |
400 | - |
401 | - ## |
402 | - # Gets element attributes, as a sequence. The attributes are |
403 | - # returned in an arbitrary order. |
404 | - # |
405 | - # @return A list of (name, value) tuples for all attributes. |
406 | - # @defreturn list of (string, string) tuples |
407 | - |
408 | - def items(self): |
409 | - return self.attrib.items() |
410 | - |
411 | - ## |
412 | - # Creates a tree iterator. The iterator loops over this element |
413 | - # and all subelements, in document order, and returns all elements |
414 | - # with a matching tag. |
415 | - # <p> |
416 | - # If the tree structure is modified during iteration, the result |
417 | - # is undefined. |
418 | - # |
419 | - # @param tag What tags to look for (default is to return all elements). |
420 | - # @return A list or iterator containing all the matching elements. |
421 | - # @defreturn list or iterator |
422 | - |
423 | - def getiterator(self, tag=None): |
424 | - nodes = [] |
425 | - if tag == "*": |
426 | - tag = None |
427 | - if tag is None or self.tag == tag: |
428 | - nodes.append(self) |
429 | - for node in self._children: |
430 | - nodes.extend(node.getiterator(tag)) |
431 | - return nodes |
432 | - |
433 | -# compatibility |
434 | -_Element = _ElementInterface |
435 | - |
436 | -## |
437 | -# Element factory. This function returns an object implementing the |
438 | -# standard Element interface. The exact class or type of that object |
439 | -# is implementation dependent, but it will always be compatible with |
440 | -# the {@link #_ElementInterface} class in this module. |
441 | -# <p> |
442 | -# The element name, attribute names, and attribute values can be |
443 | -# either 8-bit ASCII strings or Unicode strings. |
444 | -# |
445 | -# @param tag The element name. |
446 | -# @param attrib An optional dictionary, containing element attributes. |
447 | -# @param **extra Additional attributes, given as keyword arguments. |
448 | -# @return An element instance. |
449 | -# @defreturn Element |
450 | - |
451 | -def Element(tag, attrib={}, **extra): |
452 | - attrib = attrib.copy() |
453 | - attrib.update(extra) |
454 | - return _ElementInterface(tag, attrib) |
455 | - |
456 | -## |
457 | -# Subelement factory. This function creates an element instance, and |
458 | -# appends it to an existing element. |
459 | -# <p> |
460 | -# The element name, attribute names, and attribute values can be |
461 | -# either 8-bit ASCII strings or Unicode strings. |
462 | -# |
463 | -# @param parent The parent element. |
464 | -# @param tag The subelement name. |
465 | -# @param attrib An optional dictionary, containing element attributes. |
466 | -# @param **extra Additional attributes, given as keyword arguments. |
467 | -# @return An element instance. |
468 | -# @defreturn Element |
469 | - |
470 | -def SubElement(parent, tag, attrib={}, **extra): |
471 | - attrib = attrib.copy() |
472 | - attrib.update(extra) |
473 | - element = parent.makeelement(tag, attrib) |
474 | - parent.append(element) |
475 | - return element |
476 | - |
477 | -## |
478 | -# Comment element factory. This factory function creates a special |
479 | -# element that will be serialized as an XML comment. |
480 | -# <p> |
481 | -# The comment string can be either an 8-bit ASCII string or a Unicode |
482 | -# string. |
483 | -# |
484 | -# @param text A string containing the comment string. |
485 | -# @return An element instance, representing a comment. |
486 | -# @defreturn Element |
487 | - |
488 | -def Comment(text=None): |
489 | - element = Element(Comment) |
490 | - element.text = text |
491 | - return element |
492 | - |
493 | -## |
494 | -# PI element factory. This factory function creates a special element |
495 | -# that will be serialized as an XML processing instruction. |
496 | -# |
497 | -# @param target A string containing the PI target. |
498 | -# @param text A string containing the PI contents, if any. |
499 | -# @return An element instance, representing a PI. |
500 | -# @defreturn Element |
501 | - |
502 | -def ProcessingInstruction(target, text=None): |
503 | - element = Element(ProcessingInstruction) |
504 | - element.text = target |
505 | - if text: |
506 | - element.text = element.text + " " + text |
507 | - return element |
508 | - |
509 | -PI = ProcessingInstruction |
510 | - |
511 | -## |
512 | -# QName wrapper. This can be used to wrap a QName attribute value, in |
513 | -# order to get proper namespace handling on output. |
514 | -# |
515 | -# @param text A string containing the QName value, in the form {uri}local, |
516 | -# or, if the tag argument is given, the URI part of a QName. |
517 | -# @param tag Optional tag. If given, the first argument is interpreted as |
518 | -# an URI, and this argument is interpreted as a local name. |
519 | -# @return An opaque object, representing the QName. |
520 | - |
521 | -class QName: |
522 | - def __init__(self, text_or_uri, tag=None): |
523 | - if tag: |
524 | - text_or_uri = "{%s}%s" % (text_or_uri, tag) |
525 | - self.text = text_or_uri |
526 | - def __str__(self): |
527 | - return self.text |
528 | - def __hash__(self): |
529 | - return hash(self.text) |
530 | - def __cmp__(self, other): |
531 | - if isinstance(other, QName): |
532 | - return cmp(self.text, other.text) |
533 | - return cmp(self.text, other) |
534 | - |
535 | -## |
536 | -# ElementTree wrapper class. This class represents an entire element |
537 | -# hierarchy, and adds some extra support for serialization to and from |
538 | -# standard XML. |
539 | -# |
540 | -# @param element Optional root element. |
541 | -# @keyparam file Optional file handle or name. If given, the |
542 | -# tree is initialized with the contents of this XML file. |
543 | - |
544 | -class ElementTree: |
545 | - |
546 | - def __init__(self, element=None, file=None): |
547 | - assert element is None or iselement(element) |
548 | - self._root = element # first node |
549 | - if file: |
550 | - self.parse(file) |
551 | - |
552 | - ## |
553 | - # Gets the root element for this tree. |
554 | - # |
555 | - # @return An element instance. |
556 | - # @defreturn Element |
557 | - |
558 | - def getroot(self): |
559 | - return self._root |
560 | - |
561 | - ## |
562 | - # Replaces the root element for this tree. This discards the |
563 | - # current contents of the tree, and replaces it with the given |
564 | - # element. Use with care. |
565 | - # |
566 | - # @param element An element instance. |
567 | - |
568 | - def _setroot(self, element): |
569 | - assert iselement(element) |
570 | - self._root = element |
571 | - |
572 | - ## |
573 | - # Loads an external XML document into this element tree. |
574 | - # |
575 | - # @param source A file name or file object. |
576 | - # @param parser An optional parser instance. If not given, the |
577 | - # standard {@link XMLTreeBuilder} parser is used. |
578 | - # @return The document root element. |
579 | - # @defreturn Element |
580 | - |
581 | - def parse(self, source, parser=None): |
582 | - if getattr(source, "read", None) is None: |
583 | - source = open(source, "rb") |
584 | - if not parser: |
585 | - parser = XMLTreeBuilder() |
586 | - while 1: |
587 | - data = source.read(32768) |
588 | - if not data: |
589 | - break |
590 | - parser.feed(data) |
591 | - self._root = parser.close() |
592 | - return self._root |
593 | - |
594 | - ## |
595 | - # Creates a tree iterator for the root element. The iterator loops |
596 | - # over all elements in this tree, in document order. |
597 | - # |
598 | - # @param tag What tags to look for (default is to return all elements) |
599 | - # @return An iterator. |
600 | - # @defreturn iterator |
601 | - |
602 | - def getiterator(self, tag=None): |
603 | - assert self._root is not None |
604 | - return self._root.getiterator(tag) |
605 | - |
606 | - ## |
607 | - # Finds the first toplevel element with given tag. |
608 | - # Same as getroot().find(path). |
609 | - # |
610 | - # @param path What element to look for. |
611 | - # @return The first matching element, or None if no element was found. |
612 | - # @defreturn Element or None |
613 | - |
614 | - def find(self, path): |
615 | - assert self._root is not None |
616 | - if path[:1] == "/": |
617 | - path = "." + path |
618 | - return self._root.find(path) |
619 | - |
620 | - ## |
621 | - # Finds the element text for the first toplevel element with given |
622 | - # tag. Same as getroot().findtext(path). |
623 | - # |
624 | - # @param path What toplevel element to look for. |
625 | - # @param default What to return if the element was not found. |
626 | - # @return The text content of the first matching element, or the |
627 | - # default value no element was found. Note that if the element |
628 | - # has is found, but has no text content, this method returns an |
629 | - # empty string. |
630 | - # @defreturn string |
631 | - |
632 | - def findtext(self, path, default=None): |
633 | - assert self._root is not None |
634 | - if path[:1] == "/": |
635 | - path = "." + path |
636 | - return self._root.findtext(path, default) |
637 | - |
638 | - ## |
639 | - # Finds all toplevel elements with the given tag. |
640 | - # Same as getroot().findall(path). |
641 | - # |
642 | - # @param path What element to look for. |
643 | - # @return A list or iterator containing all matching elements, |
644 | - # in document order. |
645 | - # @defreturn list of Element instances |
646 | - |
647 | - def findall(self, path): |
648 | - assert self._root is not None |
649 | - if path[:1] == "/": |
650 | - path = "." + path |
651 | - return self._root.findall(path) |
652 | - |
653 | - ## |
654 | - # Writes the element tree to a file, as XML. |
655 | - # |
656 | - # @param file A file name, or a file object opened for writing. |
657 | - # @param encoding Optional output encoding (default is US-ASCII). |
658 | - |
659 | - def write(self, file, encoding="us-ascii"): |
660 | - assert self._root is not None |
661 | - if getattr(file, "write", None) is None: |
662 | - file = open(file, "wb") |
663 | - if not encoding: |
664 | - encoding = "us-ascii" |
665 | - elif encoding != "utf-8" and encoding != "us-ascii": |
666 | - file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) |
667 | - self._write(file, self._root, encoding, {}) |
668 | - |
669 | - def _write(self, file, node, encoding, namespaces): |
670 | - # write XML to file |
671 | - tag = node.tag |
672 | - if tag is Comment: |
673 | - file.write("<!-- %s -->" % _escape_cdata(node.text, encoding)) |
674 | - elif tag is ProcessingInstruction: |
675 | - file.write("<?%s?>" % _escape_cdata(node.text, encoding)) |
676 | - else: |
677 | - items = node.items() |
678 | - xmlns_items = [] # new namespaces in this scope |
679 | - try: |
680 | - if isinstance(tag, QName) or tag[:1] == "{": |
681 | - tag, xmlns = fixtag(tag, namespaces) |
682 | - if xmlns: xmlns_items.append(xmlns) |
683 | - except TypeError: |
684 | - _raise_serialization_error(tag) |
685 | - file.write("<" + _encode(tag, encoding)) |
686 | - if items or xmlns_items: |
687 | - items.sort() # lexical order |
688 | - for k, v in items: |
689 | - try: |
690 | - if isinstance(k, QName) or k[:1] == "{": |
691 | - k, xmlns = fixtag(k, namespaces) |
692 | - if xmlns: xmlns_items.append(xmlns) |
693 | - except TypeError: |
694 | - _raise_serialization_error(k) |
695 | - try: |
696 | - if isinstance(v, QName): |
697 | - v, xmlns = fixtag(v, namespaces) |
698 | - if xmlns: xmlns_items.append(xmlns) |
699 | - except TypeError: |
700 | - _raise_serialization_error(v) |
701 | - file.write(" %s=\"%s\"" % (_encode(k, encoding), |
702 | - _escape_attrib(v, encoding))) |
703 | - for k, v in xmlns_items: |
704 | - file.write(" %s=\"%s\"" % (_encode(k, encoding), |
705 | - _escape_attrib(v, encoding))) |
706 | - if node.text or len(node): |
707 | - file.write(">") |
708 | - if node.text: |
709 | - file.write(_escape_cdata(node.text, encoding)) |
710 | - for n in node: |
711 | - self._write(file, n, encoding, namespaces) |
712 | - file.write("</" + _encode(tag, encoding) + ">") |
713 | - else: |
714 | - file.write(" />") |
715 | - for k, v in xmlns_items: |
716 | - del namespaces[v] |
717 | - if node.tail: |
718 | - file.write(_escape_cdata(node.tail, encoding)) |
719 | - |
720 | -# -------------------------------------------------------------------- |
721 | -# helpers |
722 | - |
723 | -## |
724 | -# Checks if an object appears to be a valid element object. |
725 | -# |
726 | -# @param An element instance. |
727 | -# @return A true value if this is an element object. |
728 | -# @defreturn flag |
729 | - |
730 | -def iselement(element): |
731 | - # FIXME: not sure about this; might be a better idea to look |
732 | - # for tag/attrib/text attributes |
733 | - return isinstance(element, _ElementInterface) or (getattr(element, "tag", None) is not None) |
734 | - |
735 | -## |
736 | -# Writes an element tree or element structure to sys.stdout. This |
737 | -# function should be used for debugging only. |
738 | -# <p> |
739 | -# The exact output format is implementation dependent. In this |
740 | -# version, it's written as an ordinary XML file. |
741 | -# |
742 | -# @param elem An element tree or an individual element. |
743 | - |
744 | -def dump(elem): |
745 | - # debugging |
746 | - if not isinstance(elem, ElementTree): |
747 | - elem = ElementTree(elem) |
748 | - elem.write(sys.stdout) |
749 | - tail = elem.getroot().tail |
750 | - if not tail or tail[-1] != "\n": |
751 | - sys.stdout.write("\n") |
752 | - |
753 | -def _encode(s, encoding): |
754 | - try: |
755 | - return s.encode(encoding) |
756 | - except AttributeError: |
757 | - return s # 1.5.2: assume the string uses the right encoding |
758 | - |
759 | -if sys.version[:3] == "1.5": |
760 | - _escape = re.compile(r"[&<>\"\x80-\xff]+") # 1.5.2 |
761 | -else: |
762 | - _escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"')) |
763 | - |
764 | -_escape_map = { |
765 | - "&": "&", |
766 | - "<": "<", |
767 | - ">": ">", |
768 | - '"': """, |
769 | -} |
770 | - |
771 | -_namespace_map = { |
772 | - # "well-known" namespace prefixes |
773 | - "http://www.w3.org/XML/1998/namespace": "xml", |
774 | - "http://www.w3.org/1999/xhtml": "html", |
775 | - "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf", |
776 | - "http://schemas.xmlsoap.org/wsdl/": "wsdl", |
777 | -} |
778 | - |
779 | -def _raise_serialization_error(text): |
780 | - raise TypeError( |
781 | - "cannot serialize %r (type %s)" % (text, type(text).__name__) |
782 | - ) |
783 | - |
784 | -def _encode_entity(text, pattern=_escape): |
785 | - # map reserved and non-ascii characters to numerical entities |
786 | - def escape_entities(m, map=_escape_map): |
787 | - out = [] |
788 | - append = out.append |
789 | - for char in m.group(): |
790 | - text = map.get(char) |
791 | - if text is None: |
792 | - text = "&#%d;" % ord(char) |
793 | - append(text) |
794 | - return string.join(out, "") |
795 | - try: |
796 | - return _encode(pattern.sub(escape_entities, text), "ascii") |
797 | - except TypeError: |
798 | - _raise_serialization_error(text) |
799 | - |
800 | -# |
801 | -# the following functions assume an ascii-compatible encoding |
802 | -# (or "utf-16") |
803 | - |
804 | -def _escape_cdata(text, encoding=None, replace=string.replace): |
805 | - # escape character data |
806 | - try: |
807 | - if encoding: |
808 | - try: |
809 | - text = _encode(text, encoding) |
810 | - except UnicodeError: |
811 | - return _encode_entity(text) |
812 | - text = replace(text, "&", "&") |
813 | - text = replace(text, "<", "<") |
814 | - text = replace(text, ">", ">") |
815 | - return text |
816 | - except (TypeError, AttributeError): |
817 | - _raise_serialization_error(text) |
818 | - |
819 | -def _escape_attrib(text, encoding=None, replace=string.replace): |
820 | - # escape attribute value |
821 | - try: |
822 | - if encoding: |
823 | - try: |
824 | - text = _encode(text, encoding) |
825 | - except UnicodeError: |
826 | - return _encode_entity(text) |
827 | - text = replace(text, "&", "&") |
828 | - text = replace(text, "'", "'") # FIXME: overkill |
829 | - text = replace(text, "\"", """) |
830 | - text = replace(text, "<", "<") |
831 | - text = replace(text, ">", ">") |
832 | - return text |
833 | - except (TypeError, AttributeError): |
834 | - _raise_serialization_error(text) |
835 | - |
836 | -def fixtag(tag, namespaces): |
837 | - # given a decorated tag (of the form {uri}tag), return prefixed |
838 | - # tag and namespace declaration, if any |
839 | - if isinstance(tag, QName): |
840 | - tag = tag.text |
841 | - namespace_uri, tag = string.split(tag[1:], "}", 1) |
842 | - prefix = namespaces.get(namespace_uri) |
843 | - if prefix is None: |
844 | - prefix = _namespace_map.get(namespace_uri) |
845 | - if prefix is None: |
846 | - prefix = "ns%d" % len(namespaces) |
847 | - namespaces[namespace_uri] = prefix |
848 | - if prefix == "xml": |
849 | - xmlns = None |
850 | - else: |
851 | - xmlns = ("xmlns:%s" % prefix, namespace_uri) |
852 | - else: |
853 | - xmlns = None |
854 | - return "%s:%s" % (prefix, tag), xmlns |
855 | - |
856 | -## |
857 | -# Parses an XML document into an element tree. |
858 | -# |
859 | -# @param source A filename or file object containing XML data. |
860 | -# @param parser An optional parser instance. If not given, the |
861 | -# standard {@link XMLTreeBuilder} parser is used. |
862 | -# @return An ElementTree instance |
863 | - |
864 | -def parse(source, parser=None): |
865 | - tree = ElementTree() |
866 | - tree.parse(source, parser) |
867 | - return tree |
868 | - |
869 | -## |
870 | -# Parses an XML document into an element tree incrementally, and reports |
871 | -# what's going on to the user. |
872 | -# |
873 | -# @param source A filename or file object containing XML data. |
874 | -# @param events A list of events to report back. If omitted, only "end" |
875 | -# events are reported. |
876 | -# @return A (event, elem) iterator. |
877 | - |
878 | -class iterparse: |
879 | - |
880 | - def __init__(self, source, events=None): |
881 | - if getattr(source, "read", None) is None: |
882 | - source = open(source, "rb") |
883 | - self._file = source |
884 | - self._events = [] |
885 | - self._index = 0 |
886 | - self.root = self._root = None |
887 | - self._parser = XMLTreeBuilder() |
888 | - # wire up the parser for event reporting |
889 | - parser = self._parser._parser |
890 | - append = self._events.append |
891 | - if events is None: |
892 | - events = ["end"] |
893 | - for event in events: |
894 | - if event == "start": |
895 | - try: |
896 | - parser.ordered_attributes = 1 |
897 | - parser.specified_attributes = 1 |
898 | - def handler(tag, attrib_in, event=event, append=append, |
899 | - start=self._parser._start_list): |
900 | - append((event, start(tag, attrib_in))) |
901 | - parser.StartElementHandler = handler |
902 | - except AttributeError: |
903 | - def handler(tag, attrib_in, event=event, append=append, |
904 | - start=self._parser._start): |
905 | - append((event, start(tag, attrib_in))) |
906 | - parser.StartElementHandler = handler |
907 | - elif event == "end": |
908 | - def handler(tag, event=event, append=append, |
909 | - end=self._parser._end): |
910 | - append((event, end(tag))) |
911 | - parser.EndElementHandler = handler |
912 | - elif event == "start-ns": |
913 | - def handler(prefix, uri, event=event, append=append): |
914 | - try: |
915 | - uri = _encode(uri, "ascii") |
916 | - except UnicodeError: |
917 | - pass |
918 | - append((event, (prefix or "", uri))) |
919 | - parser.StartNamespaceDeclHandler = handler |
920 | - elif event == "end-ns": |
921 | - def handler(prefix, event=event, append=append): |
922 | - append((event, None)) |
923 | - parser.EndNamespaceDeclHandler = handler |
924 | - |
925 | - def next(self): |
926 | - while 1: |
927 | - try: |
928 | - item = self._events[self._index] |
929 | - except IndexError: |
930 | - if self._parser is None: |
931 | - self.root = self._root |
932 | - try: |
933 | - raise StopIteration |
934 | - except NameError: |
935 | - raise IndexError |
936 | - # load event buffer |
937 | - del self._events[:] |
938 | - self._index = 0 |
939 | - data = self._file.read(16384) |
940 | - if data: |
941 | - self._parser.feed(data) |
942 | - else: |
943 | - self._root = self._parser.close() |
944 | - self._parser = None |
945 | - else: |
946 | - self._index = self._index + 1 |
947 | - return item |
948 | - |
949 | - try: |
950 | - iter |
951 | - def __iter__(self): |
952 | - return self |
953 | - except NameError: |
954 | - def __getitem__(self, index): |
955 | - return self.next() |
956 | - |
957 | -## |
958 | -# Parses an XML document from a string constant. This function can |
959 | -# be used to embed "XML literals" in Python code. |
960 | -# |
961 | -# @param source A string containing XML data. |
962 | -# @return An Element instance. |
963 | -# @defreturn Element |
964 | - |
965 | -def XML(text): |
966 | - parser = XMLTreeBuilder() |
967 | - parser.feed(text) |
968 | - return parser.close() |
969 | - |
970 | -## |
971 | -# Parses an XML document from a string constant, and also returns |
972 | -# a dictionary which maps from element id:s to elements. |
973 | -# |
974 | -# @param source A string containing XML data. |
975 | -# @return A tuple containing an Element instance and a dictionary. |
976 | -# @defreturn (Element, dictionary) |
977 | - |
978 | -def XMLID(text): |
979 | - parser = XMLTreeBuilder() |
980 | - parser.feed(text) |
981 | - tree = parser.close() |
982 | - ids = {} |
983 | - for elem in tree.getiterator(): |
984 | - id = elem.get("id") |
985 | - if id: |
986 | - ids[id] = elem |
987 | - return tree, ids |
988 | - |
989 | -## |
990 | -# Parses an XML document from a string constant. Same as {@link #XML}. |
991 | -# |
992 | -# @def fromstring(text) |
993 | -# @param source A string containing XML data. |
994 | -# @return An Element instance. |
995 | -# @defreturn Element |
996 | - |
997 | -fromstring = XML |
998 | - |
999 | -## |
1000 | -# Generates a string representation of an XML element, including all |
1001 | -# subelements. |
1002 | -# |
1003 | -# @param element An Element instance. |
1004 | -# @return An encoded string containing the XML data. |
1005 | -# @defreturn string |
1006 | - |
1007 | -def tostring(element, encoding=None): |
1008 | - class dummy: |
1009 | - pass |
1010 | - data = [] |
1011 | - file = dummy() |
1012 | - file.write = data.append |
1013 | - ElementTree(element).write(file, encoding) |
1014 | - return string.join(data, "") |
1015 | - |
1016 | -## |
1017 | -# Generic element structure builder. This builder converts a sequence |
1018 | -# of {@link #TreeBuilder.start}, {@link #TreeBuilder.data}, and {@link |
1019 | -# #TreeBuilder.end} method calls to a well-formed element structure. |
1020 | -# <p> |
1021 | -# You can use this class to build an element structure using a custom XML |
1022 | -# parser, or a parser for some other XML-like format. |
1023 | -# |
1024 | -# @param element_factory Optional element factory. This factory |
1025 | -# is called to create new Element instances, as necessary. |
1026 | - |
1027 | -class TreeBuilder: |
1028 | - |
1029 | - def __init__(self, element_factory=None): |
1030 | - self._data = [] # data collector |
1031 | - self._elem = [] # element stack |
1032 | - self._last = None # last element |
1033 | - self._tail = None # true if we're after an end tag |
1034 | - if element_factory is None: |
1035 | - element_factory = _ElementInterface |
1036 | - self._factory = element_factory |
1037 | - |
1038 | - ## |
1039 | - # Flushes the parser buffers, and returns the toplevel documen |
1040 | - # element. |
1041 | - # |
1042 | - # @return An Element instance. |
1043 | - # @defreturn Element |
1044 | - |
1045 | - def close(self): |
1046 | - assert len(self._elem) == 0, "missing end tags" |
1047 | - assert self._last is not None, "missing toplevel element" |
1048 | - return self._last |
1049 | - |
1050 | - def _flush(self): |
1051 | - if self._data: |
1052 | - if self._last is not None: |
1053 | - text = string.join(self._data, "") |
1054 | - if self._tail: |
1055 | - assert self._last.tail is None, "internal error (tail)" |
1056 | - self._last.tail = text |
1057 | - else: |
1058 | - assert self._last.text is None, "internal error (text)" |
1059 | - self._last.text = text |
1060 | - self._data = [] |
1061 | - |
1062 | - ## |
1063 | - # Adds text to the current element. |
1064 | - # |
1065 | - # @param data A string. This should be either an 8-bit string |
1066 | - # containing ASCII text, or a Unicode string. |
1067 | - |
1068 | - def data(self, data): |
1069 | - self._data.append(data) |
1070 | - |
1071 | - ## |
1072 | - # Opens a new element. |
1073 | - # |
1074 | - # @param tag The element name. |
1075 | - # @param attrib A dictionary containing element attributes. |
1076 | - # @return The opened element. |
1077 | - # @defreturn Element |
1078 | - |
1079 | - def start(self, tag, attrs): |
1080 | - self._flush() |
1081 | - self._last = elem = self._factory(tag, attrs) |
1082 | - if self._elem: |
1083 | - self._elem[-1].append(elem) |
1084 | - self._elem.append(elem) |
1085 | - self._tail = 0 |
1086 | - return elem |
1087 | - |
1088 | - ## |
1089 | - # Closes the current element. |
1090 | - # |
1091 | - # @param tag The element name. |
1092 | - # @return The closed element. |
1093 | - # @defreturn Element |
1094 | - |
1095 | - def end(self, tag): |
1096 | - self._flush() |
1097 | - self._last = self._elem.pop() |
1098 | - assert self._last.tag == tag,\ |
1099 | - "end tag mismatch (expected %s, got %s)" % ( |
1100 | - self._last.tag, tag) |
1101 | - self._tail = 1 |
1102 | - return self._last |
1103 | - |
1104 | -## |
1105 | -# Element structure builder for XML source data, based on the |
1106 | -# <b>expat</b> parser. |
1107 | -# |
1108 | -# @keyparam target Target object. If omitted, the builder uses an |
1109 | -# instance of the standard {@link #TreeBuilder} class. |
1110 | -# @keyparam html Predefine HTML entities. This flag is not supported |
1111 | -# by the current implementation. |
1112 | -# @see #ElementTree |
1113 | -# @see #TreeBuilder |
1114 | - |
1115 | -class XMLTreeBuilder: |
1116 | - |
1117 | - def __init__(self, html=0, target=None): |
1118 | - try: |
1119 | - from xml.parsers import expat |
1120 | - except ImportError: |
1121 | - raise ImportError( |
1122 | - "No module named expat; use SimpleXMLTreeBuilder instead" |
1123 | - ) |
1124 | - self._parser = parser = expat.ParserCreate(None, "}") |
1125 | - if target is None: |
1126 | - target = TreeBuilder() |
1127 | - self._target = target |
1128 | - self._names = {} # name memo cache |
1129 | - # callbacks |
1130 | - parser.DefaultHandlerExpand = self._default |
1131 | - parser.StartElementHandler = self._start |
1132 | - parser.EndElementHandler = self._end |
1133 | - parser.CharacterDataHandler = self._data |
1134 | - # let expat do the buffering, if supported |
1135 | - try: |
1136 | - self._parser.buffer_text = 1 |
1137 | - except AttributeError: |
1138 | - pass |
1139 | - # use new-style attribute handling, if supported |
1140 | - try: |
1141 | - self._parser.ordered_attributes = 1 |
1142 | - self._parser.specified_attributes = 1 |
1143 | - parser.StartElementHandler = self._start_list |
1144 | - except AttributeError: |
1145 | - pass |
1146 | - encoding = None |
1147 | - if not parser.returns_unicode: |
1148 | - encoding = "utf-8" |
1149 | - # target.xml(encoding, None) |
1150 | - self._doctype = None |
1151 | - self.entity = {} |
1152 | - |
1153 | - def _fixtext(self, text): |
1154 | - # convert text string to ascii, if possible |
1155 | - try: |
1156 | - return _encode(text, "ascii") |
1157 | - except UnicodeError: |
1158 | - return text |
1159 | - |
1160 | - def _fixname(self, key): |
1161 | - # expand qname, and convert name string to ascii, if possible |
1162 | - try: |
1163 | - name = self._names[key] |
1164 | - except KeyError: |
1165 | - name = key |
1166 | - if "}" in name: |
1167 | - name = "{" + name |
1168 | - self._names[key] = name = self._fixtext(name) |
1169 | - return name |
1170 | - |
1171 | - def _start(self, tag, attrib_in): |
1172 | - fixname = self._fixname |
1173 | - tag = fixname(tag) |
1174 | - attrib = {} |
1175 | - for key, value in attrib_in.items(): |
1176 | - attrib[fixname(key)] = self._fixtext(value) |
1177 | - return self._target.start(tag, attrib) |
1178 | - |
1179 | - def _start_list(self, tag, attrib_in): |
1180 | - fixname = self._fixname |
1181 | - tag = fixname(tag) |
1182 | - attrib = {} |
1183 | - if attrib_in: |
1184 | - for i in range(0, len(attrib_in), 2): |
1185 | - attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i+1]) |
1186 | - return self._target.start(tag, attrib) |
1187 | - |
1188 | - def _data(self, text): |
1189 | - return self._target.data(self._fixtext(text)) |
1190 | - |
1191 | - def _end(self, tag): |
1192 | - return self._target.end(self._fixname(tag)) |
1193 | - |
1194 | - def _default(self, text): |
1195 | - prefix = text[:1] |
1196 | - if prefix == "&": |
1197 | - # deal with undefined entities |
1198 | - try: |
1199 | - self._target.data(self.entity[text[1:-1]]) |
1200 | - except KeyError: |
1201 | - from xml.parsers import expat |
1202 | - raise expat.error( |
1203 | - "undefined entity %s: line %d, column %d" % |
1204 | - (text, self._parser.ErrorLineNumber, |
1205 | - self._parser.ErrorColumnNumber) |
1206 | - ) |
1207 | - elif prefix == "<" and text[:9] == "<!DOCTYPE": |
1208 | - self._doctype = [] # inside a doctype declaration |
1209 | - elif self._doctype is not None: |
1210 | - # parse doctype contents |
1211 | - if prefix == ">": |
1212 | - self._doctype = None |
1213 | - return |
1214 | - text = string.strip(text) |
1215 | - if not text: |
1216 | - return |
1217 | - self._doctype.append(text) |
1218 | - n = len(self._doctype) |
1219 | - if n > 2: |
1220 | - type = self._doctype[1] |
1221 | - if type == "PUBLIC" and n == 4: |
1222 | - name, type, pubid, system = self._doctype |
1223 | - elif type == "SYSTEM" and n == 3: |
1224 | - name, type, system = self._doctype |
1225 | - pubid = None |
1226 | - else: |
1227 | - return |
1228 | - if pubid: |
1229 | - pubid = pubid[1:-1] |
1230 | - self.doctype(name, pubid, system[1:-1]) |
1231 | - self._doctype = None |
1232 | - |
1233 | - ## |
1234 | - # Handles a doctype declaration. |
1235 | - # |
1236 | - # @param name Doctype name. |
1237 | - # @param pubid Public identifier. |
1238 | - # @param system System identifier. |
1239 | - |
1240 | - def doctype(self, name, pubid, system): |
1241 | - pass |
1242 | - |
1243 | - ## |
1244 | - # Feeds data to the parser. |
1245 | - # |
1246 | - # @param data Encoded data. |
1247 | - |
1248 | - def feed(self, data): |
1249 | - self._parser.Parse(data, 0) |
1250 | - |
1251 | - ## |
1252 | - # Finishes feeding data to the parser. |
1253 | - # |
1254 | - # @return An element structure. |
1255 | - # @defreturn Element |
1256 | - |
1257 | - def close(self): |
1258 | - self._parser.Parse("", 1) # end of data |
1259 | - tree = self._target.close() |
1260 | - del self._target, self._parser # get rid of circular references |
1261 | - return tree |
1262 | |
1263 | === removed file 'bzrlib/util/elementtree/__init__.py' |
1264 | --- bzrlib/util/elementtree/__init__.py 2011-12-18 15:28:38 +0000 |
1265 | +++ bzrlib/util/elementtree/__init__.py 1970-01-01 00:00:00 +0000 |
1266 | @@ -1,32 +0,0 @@ |
1267 | -# $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $ |
1268 | -# elementtree package |
1269 | - |
1270 | -# -------------------------------------------------------------------- |
1271 | -# The ElementTree toolkit is |
1272 | -# |
1273 | -# Copyright (c) 1999-2004 by Fredrik Lundh |
1274 | -# |
1275 | -# By obtaining, using, and/or copying this software and/or its |
1276 | -# associated documentation, you agree that you have read, understood, |
1277 | -# and will comply with the following terms and conditions: |
1278 | -# |
1279 | -# Permission to use, copy, modify, and distribute this software and |
1280 | -# its associated documentation for any purpose and without fee is |
1281 | -# hereby granted, provided that the above copyright notice appears in |
1282 | -# all copies, and that both that copyright notice and this permission |
1283 | -# notice appear in supporting documentation, and that the name of |
1284 | -# Secret Labs AB or the author not be used in advertising or publicity |
1285 | -# pertaining to distribution of the software without specific, written |
1286 | -# prior permission. |
1287 | -# |
1288 | -# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD |
1289 | -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- |
1290 | -# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR |
1291 | -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY |
1292 | -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
1293 | -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS |
1294 | -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
1295 | -# OF THIS SOFTWARE. |
1296 | -# -------------------------------------------------------------------- |
1297 | - |
1298 | -from __future__ import absolute_import |
1299 | |
1300 | === modified file 'bzrlib/xml_serializer.py' |
1301 | --- bzrlib/xml_serializer.py 2011-12-19 13:23:58 +0000 |
1302 | +++ bzrlib/xml_serializer.py 2012-01-05 12:38:22 +0000 |
1303 | @@ -26,41 +26,32 @@ |
1304 | |
1305 | import re |
1306 | |
1307 | -from bzrlib.serializer import Serializer |
1308 | -from bzrlib.trace import mutter |
1309 | - |
1310 | try: |
1311 | + import xml.etree.cElementTree as elementtree |
1312 | + ParseError = getattr(elementtree, "ParseError", SyntaxError) |
1313 | +except ImportError: |
1314 | + # Fall back to pure python implementation if C extention is unavailable |
1315 | + import xml.etree.ElementTree as elementtree |
1316 | try: |
1317 | - # it's in this package in python2.5 |
1318 | - from xml.etree.cElementTree import (ElementTree, SubElement, Element, |
1319 | - XMLTreeBuilder, fromstring, tostring) |
1320 | - import xml.etree as elementtree |
1321 | - # Also import ElementTree module so monkey-patching below always works |
1322 | - import xml.etree.ElementTree |
1323 | + from xml.etree.ElementTree import ParseError |
1324 | except ImportError: |
1325 | - from cElementTree import (ElementTree, SubElement, Element, |
1326 | - XMLTreeBuilder, fromstring, tostring) |
1327 | - import elementtree.ElementTree |
1328 | - ParseError = SyntaxError |
1329 | -except ImportError: |
1330 | - mutter('WARNING: using slower ElementTree; consider installing cElementTree' |
1331 | - " and make sure it's on your PYTHONPATH") |
1332 | - # this copy is shipped with bzr |
1333 | - from util.elementtree.ElementTree import (ElementTree, SubElement, |
1334 | - Element, XMLTreeBuilder, |
1335 | - fromstring, tostring) |
1336 | - import util.elementtree as elementtree |
1337 | - from xml.parsers.expat import ExpatError as ParseError |
1338 | + from xml.parsers.expat import ExpatError as ParseError |
1339 | + |
1340 | +(ElementTree, SubElement, Element, XMLTreeBuilder, fromstring, tostring) = ( |
1341 | + elementtree.ElementTree, elementtree.SubElement, elementtree.Element, |
1342 | + elementtree.XMLTreeBuilder, elementtree.fromstring, elementtree.tostring) |
1343 | + |
1344 | |
1345 | from bzrlib import ( |
1346 | cache_utf8, |
1347 | + errors, |
1348 | inventory, |
1349 | lazy_regex, |
1350 | - errors, |
1351 | + serializer, |
1352 | ) |
1353 | |
1354 | |
1355 | -class XMLSerializer(Serializer): |
1356 | +class XMLSerializer(serializer.Serializer): |
1357 | """Abstract XML object serialize/deserialize""" |
1358 | |
1359 | squashes_xml_invalid_characters = True |
My understanding is that this was required for very old pythons and as such safe to delete.