13257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel"""Python version compatibility support for minidom.""" 23257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 33257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# This module should only be imported using "import *". 43257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 53257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# The following names are defined: 63257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 73257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# NodeList -- lightest possible NodeList implementation 83257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 93257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# EmptyNodeList -- lightest possible NodeList that is guaranteed to 103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# remain empty (immutable) 113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# StringTypes -- tuple of defined string types 133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# defproperty -- function used in conjunction with GetattrMagic; 153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# using these together is needed to make them work 163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# as efficiently as possible in both Python 2.2+ 173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# and older versions. For example: 183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# class MyClass(GetattrMagic): 203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# def _get_myattr(self): 213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# return something 223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# defproperty(MyClass, "myattr", 243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# "return some value") 253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# For Python 2.2 and newer, this will construct a 273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# property object on the class, which avoids 283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# needing to override __getattr__(). It will only 293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# work for read-only attributes. 303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# For older versions of Python, inheriting from 323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# GetattrMagic will use the traditional 333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# __getattr__() hackery to achieve the same effect, 343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# but less efficiently. 353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# 363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# defproperty() should be used for each version of 373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel# the relevant _get_<property>() function. 383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] 403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport xml.dom 423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieltry: 443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel unicode 453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielexcept NameError: 463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel StringTypes = type(''), 473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielelse: 483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel StringTypes = type(''), type(unicode('')) 493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielclass NodeList(list): 523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel __slots__ = () 533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def item(self, index): 553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel if 0 <= index < len(self): 563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return self[index] 573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _get_length(self): 593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return len(self) 603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _set_length(self, value): 623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise xml.dom.NoModificationAllowedErr( 633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel "attempt to modify read-only attribute 'length'") 643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel length = property(_get_length, _set_length, 663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel doc="The number of nodes in the NodeList.") 673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __getstate__(self): 693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return list(self) 703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __setstate__(self, state): 723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel self[:] = state 733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielclass EmptyNodeList(tuple): 763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel __slots__ = () 773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __add__(self, other): 793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel NL = NodeList() 803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel NL.extend(other) 813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return NL 823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def __radd__(self, other): 843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel NL = NodeList() 853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel NL.extend(other) 863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return NL 873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def item(self, index): 893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return None 903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _get_length(self): 923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel return 0 933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def _set_length(self, value): 953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise xml.dom.NoModificationAllowedErr( 963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel "attempt to modify read-only attribute 'length'") 973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel length = property(_get_length, _set_length, 993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel doc="The number of nodes in the NodeList.") 1003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel 1023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef defproperty(klass, name, doc): 1033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel get = getattr(klass, ("_get_" + name)).im_func 1043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel def set(self, value, name=name): 1053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel raise xml.dom.NoModificationAllowedErr( 1063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel "attempt to modify read-only attribute " + repr(name)) 1073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel assert not hasattr(klass, "_set_" + name), \ 1083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel "expected not to find _set_" + name 1093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel prop = property(get, set, doc=doc) 1103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel setattr(klass, name, prop) 111