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