10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Python version compatibility support for minidom.""" 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This module should only be imported using "import *". 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The following names are defined: 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# NodeList -- lightest possible NodeList implementation 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# EmptyNodeList -- lightest possible NodeList that is guaranteed to 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# remain empty (immutable) 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# StringTypes -- tuple of defined string types 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# defproperty -- function used in conjunction with GetattrMagic; 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# using these together is needed to make them work 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# as efficiently as possible in both Python 2.2+ 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# and older versions. For example: 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# class MyClass(GetattrMagic): 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# def _get_myattr(self): 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# return something 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# defproperty(MyClass, "myattr", 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# "return some value") 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# For Python 2.2 and newer, this will construct a 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# property object on the class, which avoids 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# needing to override __getattr__(). It will only 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# work for read-only attributes. 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# For older versions of Python, inheriting from 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# GetattrMagic will use the traditional 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# __getattr__() hackery to achieve the same effect, 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# but less efficiently. 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# defproperty() should be used for each version of 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the relevant _get_<property>() function. 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport xml.dom 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao unicode 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError: 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao StringTypes = type(''), 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse: 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao StringTypes = type(''), type(unicode('')) 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass NodeList(list): 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao __slots__ = () 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def item(self, index): 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if 0 <= index < len(self): 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self[index] 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _get_length(self): 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return len(self) 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _set_length(self, value): 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise xml.dom.NoModificationAllowedErr( 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "attempt to modify read-only attribute 'length'") 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao length = property(_get_length, _set_length, 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao doc="The number of nodes in the NodeList.") 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __getstate__(self): 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return list(self) 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __setstate__(self, state): 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self[:] = state 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass EmptyNodeList(tuple): 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao __slots__ = () 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __add__(self, other): 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao NL = NodeList() 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao NL.extend(other) 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return NL 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __radd__(self, other): 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao NL = NodeList() 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao NL.extend(other) 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return NL 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def item(self, index): 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return None 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _get_length(self): 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 0 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _set_length(self, value): 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise xml.dom.NoModificationAllowedErr( 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "attempt to modify read-only attribute 'length'") 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao length = property(_get_length, _set_length, 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao doc="The number of nodes in the NodeList.") 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef defproperty(klass, name, doc): 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao get = getattr(klass, ("_get_" + name)).im_func 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def set(self, value, name=name): 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise xml.dom.NoModificationAllowedErr( 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "attempt to modify read-only attribute " + repr(name)) 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert not hasattr(klass, "_set_" + name), \ 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "expected not to find _set_" + name 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao prop = property(get, set, doc=doc) 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao setattr(klass, name, prop) 111