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