• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Python version compatibility support for minidom.
2
3This module contains internal implementation details and
4should not be imported; use xml.dom.minidom instead.
5"""
6
7# This module should only be imported using "import *".
8#
9# The following names are defined:
10#
11#   NodeList      -- lightest possible NodeList implementation
12#
13#   EmptyNodeList -- lightest possible NodeList that is guaranteed to
14#                    remain empty (immutable)
15#
16#   StringTypes   -- tuple of defined string types
17#
18#   defproperty   -- function used in conjunction with GetattrMagic;
19#                    using these together is needed to make them work
20#                    as efficiently as possible in both Python 2.2+
21#                    and older versions.  For example:
22#
23#                        class MyClass(GetattrMagic):
24#                            def _get_myattr(self):
25#                                return something
26#
27#                        defproperty(MyClass, "myattr",
28#                                    "return some value")
29#
30#                    For Python 2.2 and newer, this will construct a
31#                    property object on the class, which avoids
32#                    needing to override __getattr__().  It will only
33#                    work for read-only attributes.
34#
35#                    For older versions of Python, inheriting from
36#                    GetattrMagic will use the traditional
37#                    __getattr__() hackery to achieve the same effect,
38#                    but less efficiently.
39#
40#                    defproperty() should be used for each version of
41#                    the relevant _get_<property>() function.
42
43__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"]
44
45import xml.dom
46
47StringTypes = (str,)
48
49
50class NodeList(list):
51    __slots__ = ()
52
53    def item(self, index):
54        if 0 <= index < len(self):
55            return self[index]
56
57    def _get_length(self):
58        return len(self)
59
60    def _set_length(self, value):
61        raise xml.dom.NoModificationAllowedErr(
62            "attempt to modify read-only attribute 'length'")
63
64    length = property(_get_length, _set_length,
65                      doc="The number of nodes in the NodeList.")
66
67    # For backward compatibility
68    def __setstate__(self, state):
69        if state is None:
70            state = []
71        self[:] = state
72
73
74class EmptyNodeList(tuple):
75    __slots__ = ()
76
77    def __add__(self, other):
78        NL = NodeList()
79        NL.extend(other)
80        return NL
81
82    def __radd__(self, other):
83        NL = NodeList()
84        NL.extend(other)
85        return NL
86
87    def item(self, index):
88        return None
89
90    def _get_length(self):
91        return 0
92
93    def _set_length(self, value):
94        raise xml.dom.NoModificationAllowedErr(
95            "attempt to modify read-only attribute 'length'")
96
97    length = property(_get_length, _set_length,
98                      doc="The number of nodes in the NodeList.")
99
100
101def defproperty(klass, name, doc):
102    get = getattr(klass, ("_get_" + name))
103    def set(self, value, name=name):
104        raise xml.dom.NoModificationAllowedErr(
105            "attempt to modify read-only attribute " + repr(name))
106    assert not hasattr(klass, "_set_" + name), \
107           "expected not to find _set_" + name
108    prop = property(get, set, doc=doc)
109    setattr(klass, name, prop)
110