|
1 """Python version compatibility support for minidom.""" |
|
2 |
|
3 # This module should only be imported using "import *". |
|
4 # |
|
5 # The following names are defined: |
|
6 # |
|
7 # NodeList -- lightest possible NodeList implementation |
|
8 # |
|
9 # EmptyNodeList -- lightest possible NodeList that is guarateed to |
|
10 # remain empty (immutable) |
|
11 # |
|
12 # StringTypes -- tuple of defined string types |
|
13 # |
|
14 # defproperty -- function used in conjunction with GetattrMagic; |
|
15 # using these together is needed to make them work |
|
16 # as efficiently as possible in both Python 2.2+ |
|
17 # and older versions. For example: |
|
18 # |
|
19 # class MyClass(GetattrMagic): |
|
20 # def _get_myattr(self): |
|
21 # return something |
|
22 # |
|
23 # defproperty(MyClass, "myattr", |
|
24 # "return some value") |
|
25 # |
|
26 # For Python 2.2 and newer, this will construct a |
|
27 # property object on the class, which avoids |
|
28 # needing to override __getattr__(). It will only |
|
29 # work for read-only attributes. |
|
30 # |
|
31 # For older versions of Python, inheriting from |
|
32 # GetattrMagic will use the traditional |
|
33 # __getattr__() hackery to achieve the same effect, |
|
34 # but less efficiently. |
|
35 # |
|
36 # defproperty() should be used for each version of |
|
37 # the relevant _get_<property>() function. |
|
38 |
|
39 __all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] |
|
40 |
|
41 import xml.dom |
|
42 |
|
43 try: |
|
44 unicode |
|
45 except NameError: |
|
46 StringTypes = type(''), |
|
47 else: |
|
48 StringTypes = type(''), type(unicode('')) |
|
49 |
|
50 |
|
51 class NodeList(list): |
|
52 __slots__ = () |
|
53 |
|
54 def item(self, index): |
|
55 if 0 <= index < len(self): |
|
56 return self[index] |
|
57 |
|
58 def _get_length(self): |
|
59 return len(self) |
|
60 |
|
61 def _set_length(self, value): |
|
62 raise xml.dom.NoModificationAllowedErr( |
|
63 "attempt to modify read-only attribute 'length'") |
|
64 |
|
65 length = property(_get_length, _set_length, |
|
66 doc="The number of nodes in the NodeList.") |
|
67 |
|
68 def __getstate__(self): |
|
69 return list(self) |
|
70 |
|
71 def __setstate__(self, state): |
|
72 self[:] = state |
|
73 |
|
74 |
|
75 class EmptyNodeList(tuple): |
|
76 __slots__ = () |
|
77 |
|
78 def __add__(self, other): |
|
79 NL = NodeList() |
|
80 NL.extend(other) |
|
81 return NL |
|
82 |
|
83 def __radd__(self, other): |
|
84 NL = NodeList() |
|
85 NL.extend(other) |
|
86 return NL |
|
87 |
|
88 def item(self, index): |
|
89 return None |
|
90 |
|
91 def _get_length(self): |
|
92 return 0 |
|
93 |
|
94 def _set_length(self, value): |
|
95 raise xml.dom.NoModificationAllowedErr( |
|
96 "attempt to modify read-only attribute 'length'") |
|
97 |
|
98 length = property(_get_length, _set_length, |
|
99 doc="The number of nodes in the NodeList.") |
|
100 |
|
101 |
|
102 def defproperty(klass, name, doc): |
|
103 get = getattr(klass, ("_get_" + name)).im_func |
|
104 def set(self, value, name=name): |
|
105 raise xml.dom.NoModificationAllowedErr( |
|
106 "attempt to modify read-only attribute " + repr(name)) |
|
107 assert not hasattr(klass, "_set_" + name), \ |
|
108 "expected not to find _set_" + name |
|
109 prop = property(get, set, doc=doc) |
|
110 setattr(klass, name, prop) |