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