jpayne@68: """Python version compatibility support for minidom. jpayne@68: jpayne@68: This module contains internal implementation details and jpayne@68: should not be imported; use xml.dom.minidom instead. jpayne@68: """ jpayne@68: jpayne@68: # This module should only be imported using "import *". jpayne@68: # jpayne@68: # The following names are defined: jpayne@68: # jpayne@68: # NodeList -- lightest possible NodeList implementation jpayne@68: # jpayne@68: # EmptyNodeList -- lightest possible NodeList that is guaranteed to jpayne@68: # remain empty (immutable) jpayne@68: # jpayne@68: # StringTypes -- tuple of defined string types jpayne@68: # jpayne@68: # defproperty -- function used in conjunction with GetattrMagic; jpayne@68: # using these together is needed to make them work jpayne@68: # as efficiently as possible in both Python 2.2+ jpayne@68: # and older versions. For example: jpayne@68: # jpayne@68: # class MyClass(GetattrMagic): jpayne@68: # def _get_myattr(self): jpayne@68: # return something jpayne@68: # jpayne@68: # defproperty(MyClass, "myattr", jpayne@68: # "return some value") jpayne@68: # jpayne@68: # For Python 2.2 and newer, this will construct a jpayne@68: # property object on the class, which avoids jpayne@68: # needing to override __getattr__(). It will only jpayne@68: # work for read-only attributes. jpayne@68: # jpayne@68: # For older versions of Python, inheriting from jpayne@68: # GetattrMagic will use the traditional jpayne@68: # __getattr__() hackery to achieve the same effect, jpayne@68: # but less efficiently. jpayne@68: # jpayne@68: # defproperty() should be used for each version of jpayne@68: # the relevant _get_() function. jpayne@68: jpayne@68: __all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] jpayne@68: jpayne@68: import xml.dom jpayne@68: jpayne@68: StringTypes = (str,) jpayne@68: jpayne@68: jpayne@68: class NodeList(list): jpayne@68: __slots__ = () jpayne@68: jpayne@68: def item(self, index): jpayne@68: if 0 <= index < len(self): jpayne@68: return self[index] jpayne@68: jpayne@68: def _get_length(self): jpayne@68: return len(self) jpayne@68: jpayne@68: def _set_length(self, value): jpayne@68: raise xml.dom.NoModificationAllowedErr( jpayne@68: "attempt to modify read-only attribute 'length'") jpayne@68: jpayne@68: length = property(_get_length, _set_length, jpayne@68: doc="The number of nodes in the NodeList.") jpayne@68: jpayne@68: # For backward compatibility jpayne@68: def __setstate__(self, state): jpayne@68: if state is None: jpayne@68: state = [] jpayne@68: self[:] = state jpayne@68: jpayne@68: jpayne@68: class EmptyNodeList(tuple): jpayne@68: __slots__ = () jpayne@68: jpayne@68: def __add__(self, other): jpayne@68: NL = NodeList() jpayne@68: NL.extend(other) jpayne@68: return NL jpayne@68: jpayne@68: def __radd__(self, other): jpayne@68: NL = NodeList() jpayne@68: NL.extend(other) jpayne@68: return NL jpayne@68: jpayne@68: def item(self, index): jpayne@68: return None jpayne@68: jpayne@68: def _get_length(self): jpayne@68: return 0 jpayne@68: jpayne@68: def _set_length(self, value): jpayne@68: raise xml.dom.NoModificationAllowedErr( jpayne@68: "attempt to modify read-only attribute 'length'") jpayne@68: jpayne@68: length = property(_get_length, _set_length, jpayne@68: doc="The number of nodes in the NodeList.") jpayne@68: jpayne@68: jpayne@68: def defproperty(klass, name, doc): jpayne@68: get = getattr(klass, ("_get_" + name)) jpayne@68: def set(self, value, name=name): jpayne@68: raise xml.dom.NoModificationAllowedErr( jpayne@68: "attempt to modify read-only attribute " + repr(name)) jpayne@68: assert not hasattr(klass, "_set_" + name), \ jpayne@68: "expected not to find _set_" + name jpayne@68: prop = property(get, set, doc=doc) jpayne@68: setattr(klass, name, prop)