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 guaranteed 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) 111