14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Python version compatibility support for minidom.""" 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# This module should only be imported using "import *". 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# The following names are defined: 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# NodeList -- lightest possible NodeList implementation 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# EmptyNodeList -- lightest possible NodeList that is guaranteed to 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# remain empty (immutable) 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# StringTypes -- tuple of defined string types 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# defproperty -- function used in conjunction with GetattrMagic; 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# using these together is needed to make them work 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# as efficiently as possible in both Python 2.2+ 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# and older versions. For example: 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# class MyClass(GetattrMagic): 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# def _get_myattr(self): 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# return something 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# defproperty(MyClass, "myattr", 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# "return some value") 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# For Python 2.2 and newer, this will construct a 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# property object on the class, which avoids 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# needing to override __getattr__(). It will only 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# work for read-only attributes. 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# For older versions of Python, inheriting from 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# GetattrMagic will use the traditional 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# __getattr__() hackery to achieve the same effect, 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# but less efficiently. 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# defproperty() should be used for each version of 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# the relevant _get_<property>() function. 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport xml.dom 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unicode 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept NameError: 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm StringTypes = type(''), 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmelse: 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm StringTypes = type(''), type(unicode('')) 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass NodeList(list): 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __slots__ = () 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def item(self, index): 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if 0 <= index < len(self): 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self[index] 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _get_length(self): 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return len(self) 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _set_length(self, value): 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise xml.dom.NoModificationAllowedErr( 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "attempt to modify read-only attribute 'length'") 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm length = property(_get_length, _set_length, 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm doc="The number of nodes in the NodeList.") 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __getstate__(self): 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return list(self) 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __setstate__(self, state): 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self[:] = state 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass EmptyNodeList(tuple): 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __slots__ = () 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __add__(self, other): 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NL = NodeList() 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NL.extend(other) 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NL 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __radd__(self, other): 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NL = NodeList() 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NL.extend(other) 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NL 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def item(self, index): 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return None 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _get_length(self): 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _set_length(self, value): 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise xml.dom.NoModificationAllowedErr( 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "attempt to modify read-only attribute 'length'") 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm length = property(_get_length, _set_length, 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm doc="The number of nodes in the NodeList.") 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef defproperty(klass, name, doc): 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm get = getattr(klass, ("_get_" + name)).im_func 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def set(self, value, name=name): 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise xml.dom.NoModificationAllowedErr( 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "attempt to modify read-only attribute " + repr(name)) 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert not hasattr(klass, "_set_" + name), \ 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "expected not to find _set_" + name 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prop = property(get, set, doc=doc) 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setattr(klass, name, prop) 111