blob: 2e6cc7e34c0a0ed9e9eedd846b87cb13fc6949ba [file] [log] [blame]
Martin v. Löwisfc5fec72003-01-25 15:11:07 +00001"""Python version compatibility support for minidom."""
2
3# This module should only be imported using "import *".
4#
5# The following names are defined:
6#
Martin v. Löwisfc5fec72003-01-25 15:11:07 +00007# NodeList -- lightest possible NodeList implementation
8#
9# EmptyNodeList -- lightest possible NodeList that is guarateed to
10# remain empty (immutable)
11#
12# StringTypes -- tuple of defined string types
13#
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000014# defproperty -- function used in conjunction with GetattrMagic;
15# using these together is needed to make them work
16# as efficiently as possible in both Python 2.2+
17# and older versions. For example:
18#
19# class MyClass(GetattrMagic):
20# def _get_myattr(self):
21# return something
22#
23# defproperty(MyClass, "myattr",
24# "return some value")
25#
26# For Python 2.2 and newer, this will construct a
27# property object on the class, which avoids
28# needing to override __getattr__(). It will only
29# work for read-only attributes.
30#
31# For older versions of Python, inheriting from
32# GetattrMagic will use the traditional
33# __getattr__() hackery to achieve the same effect,
34# but less efficiently.
35#
36# defproperty() should be used for each version of
37# the relevant _get_<property>() function.
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000038
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000039__all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"]
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000040
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041import xml.dom
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000042
Walter Dörwald5de48bd2007-06-11 21:38:39 +000043StringTypes = (str,)
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000044
45
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000046class NodeList(list):
47 __slots__ = ()
48
49 def item(self, index):
50 if 0 <= index < len(self):
51 return self[index]
52
53 def _get_length(self):
54 return len(self)
55
56 def _set_length(self, value):
57 raise xml.dom.NoModificationAllowedErr(
58 "attempt to modify read-only attribute 'length'")
59
60 length = property(_get_length, _set_length,
61 doc="The number of nodes in the NodeList.")
62
63 def __getstate__(self):
64 return list(self)
65
66 def __setstate__(self, state):
67 self[:] = state
68
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000070class EmptyNodeList(tuple):
71 __slots__ = ()
72
73 def __add__(self, other):
74 NL = NodeList()
75 NL.extend(other)
76 return NL
77
78 def __radd__(self, other):
79 NL = NodeList()
80 NL.extend(other)
81 return NL
82
83 def item(self, index):
84 return None
85
86 def _get_length(self):
87 return 0
88
89 def _set_length(self, value):
90 raise xml.dom.NoModificationAllowedErr(
91 "attempt to modify read-only attribute 'length'")
92
93 length = property(_get_length, _set_length,
94 doc="The number of nodes in the NodeList.")
Martin v. Löwisfc5fec72003-01-25 15:11:07 +000095
96
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000097def defproperty(klass, name, doc):
Christian Heimes4a22b5d2007-11-25 09:39:14 +000098 get = getattr(klass, ("_get_" + name))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000099 def set(self, value, name=name):
100 raise xml.dom.NoModificationAllowedErr(
101 "attempt to modify read-only attribute " + repr(name))
102 assert not hasattr(klass, "_set_" + name), \
103 "expected not to find _set_" + name
104 prop = property(get, set, doc=doc)
105 setattr(klass, name, prop)