mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-11-30 19:19:55 +00:00
Updated the remaining ElementBase methods.
Remaining ElementBase todos: Write the class documentation for ElementBase. Write unit tests for the __magic__ methods.
This commit is contained in:
parent
a3580dcef9
commit
10298a6eab
1 changed files with 205 additions and 85 deletions
|
@ -55,7 +55,7 @@ class ElementBase(object):
|
||||||
self.xml = xml
|
self.xml = xml
|
||||||
self.plugins = {}
|
self.plugins = {}
|
||||||
self.iterables = []
|
self.iterables = []
|
||||||
self.idx = 0
|
self._index = 0
|
||||||
if parent is None:
|
if parent is None:
|
||||||
self.parent = None
|
self.parent = None
|
||||||
else:
|
else:
|
||||||
|
@ -510,89 +510,134 @@ class ElementBase(object):
|
||||||
# Everything matched.
|
# Everything matched.
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
def find(self, xpath):
|
||||||
def attrib(self): #backwards compatibility
|
"""
|
||||||
return self
|
Find an XML object in this stanza given an XPath expression.
|
||||||
|
|
||||||
def __iter__(self):
|
Exposes ElementTree interface for backwards compatibility.
|
||||||
self.idx = 0
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __bool__(self): #python 3.x
|
Note that matching on attribute values is not supported in Python 2.6
|
||||||
return True
|
or Python 3.1
|
||||||
|
|
||||||
def __nonzero__(self): #python 2.x
|
Arguments:
|
||||||
return True
|
xpath -- An XPath expression matching a single desired element.
|
||||||
|
"""
|
||||||
def __next__(self):
|
return self.xml.find(xpath)
|
||||||
self.idx += 1
|
|
||||||
if self.idx > len(self.iterables):
|
|
||||||
self.idx = 0
|
|
||||||
raise StopIteration
|
|
||||||
return self.iterables[self.idx - 1]
|
|
||||||
|
|
||||||
def next(self):
|
|
||||||
return self.__next__()
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self.iterables)
|
|
||||||
|
|
||||||
def append(self, item):
|
|
||||||
if not isinstance(item, ElementBase):
|
|
||||||
if type(item) == XML_TYPE:
|
|
||||||
return self.appendxml(item)
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
||||||
self.xml.append(item.xml)
|
|
||||||
self.iterables.append(item)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def pop(self, idx=0):
|
|
||||||
aff = self.iterables.pop(idx)
|
|
||||||
self.xml.remove(aff.xml)
|
|
||||||
return aff
|
|
||||||
|
|
||||||
def get(self, key, defaultvalue=None):
|
|
||||||
value = self[key]
|
|
||||||
if value is None or value == '':
|
|
||||||
return defaultvalue
|
|
||||||
return value
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
out = []
|
|
||||||
out += [x for x in self.interfaces]
|
|
||||||
out += [x for x in self.plugins]
|
|
||||||
if self.iterables:
|
|
||||||
out.append('substanzas')
|
|
||||||
return tuple(out)
|
|
||||||
|
|
||||||
def find(self, xpath): # for backwards compatiblity, expose elementtree interface
|
|
||||||
return self.xml.find(xpath)
|
|
||||||
|
|
||||||
def findall(self, xpath):
|
def findall(self, xpath):
|
||||||
return self.xml.findall(xpath)
|
"""
|
||||||
|
Find multiple XML objects in this stanza given an XPath expression.
|
||||||
|
|
||||||
def __eq__(self, other):
|
Exposes ElementTree interface for backwards compatibility.
|
||||||
if not isinstance(other, ElementBase):
|
|
||||||
return False
|
Note that matching on attribute values is not supported in Python 2.6
|
||||||
values = self.getStanzaValues()
|
or Python 3.1.
|
||||||
for key in other:
|
|
||||||
if key not in values or values[key] != other[key]:
|
Arguments:
|
||||||
return False
|
xpath -- An XPath expression matching multiple desired elements.
|
||||||
return True
|
"""
|
||||||
|
return self.xml.findall(xpath)
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
"""
|
||||||
|
Return the value of a stanza interface. If the found value is None
|
||||||
|
or an empty string, return the supplied default value.
|
||||||
|
|
||||||
|
Allows stanza objects to be used like dictionaries.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
key -- The name of the stanza interface to check.
|
||||||
|
default -- Value to return if the stanza interface has a value
|
||||||
|
of None or "". Will default to returning None.
|
||||||
|
"""
|
||||||
|
value = self[key]
|
||||||
|
if value is None or value == '':
|
||||||
|
return default
|
||||||
|
return value
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
"""
|
||||||
|
Return the names of all stanza interfaces provided by the
|
||||||
|
stanza object.
|
||||||
|
|
||||||
|
Allows stanza objects to be used like dictionaries.
|
||||||
|
"""
|
||||||
|
out = []
|
||||||
|
out += [x for x in self.interfaces]
|
||||||
|
out += [x for x in self.plugins]
|
||||||
|
if self.iterables:
|
||||||
|
out.append('substanzas')
|
||||||
|
return tuple(out)
|
||||||
|
|
||||||
|
def append(self, item):
|
||||||
|
"""
|
||||||
|
Append either an XML object or a substanza to this stanza object.
|
||||||
|
|
||||||
|
If a substanza object is appended, it will be added to the list
|
||||||
|
of iterable stanzas.
|
||||||
|
|
||||||
|
Allows stanza objects to be used like lists.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
item -- Either an XML object or a stanza object to add to
|
||||||
|
this stanza's contents.
|
||||||
|
"""
|
||||||
|
if not isinstance(item, ElementBase):
|
||||||
|
if type(item) == XML_TYPE:
|
||||||
|
return self.appendxml(item)
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
self.xml.append(item.xml)
|
||||||
|
self.iterables.append(item)
|
||||||
|
return self
|
||||||
|
|
||||||
def appendxml(self, xml):
|
def appendxml(self, xml):
|
||||||
self.xml.append(xml)
|
"""
|
||||||
return self
|
Append an XML object to the stanza's XML.
|
||||||
|
|
||||||
def __copy__(self):
|
The added XML will not be included in the list of
|
||||||
return self.__class__(xml=copy.deepcopy(self.xml), parent=self.parent)
|
iterable substanzas.
|
||||||
|
|
||||||
def __str__(self):
|
Arguments:
|
||||||
return tostring(self.xml, xmlns='', stanza_ns=self.namespace)
|
xml -- The XML object to add to the stanza.
|
||||||
|
"""
|
||||||
|
self.xml.append(xml)
|
||||||
|
return self
|
||||||
|
|
||||||
def __repr__(self):
|
def pop(self, index=0):
|
||||||
return self.__str__()
|
"""
|
||||||
|
Remove and return the last substanza in the list of
|
||||||
|
iterable substanzas.
|
||||||
|
|
||||||
|
Allows stanza objects to be used like lists.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
index -- The index of the substanza to remove.
|
||||||
|
"""
|
||||||
|
substanza = self.iterables.pop(index)
|
||||||
|
self.xml.remove(substanza.xml)
|
||||||
|
return substanza
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
"""
|
||||||
|
Return the next iterable substanza.
|
||||||
|
"""
|
||||||
|
return self.__next__()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def attrib(self):
|
||||||
|
"""
|
||||||
|
DEPRECATED
|
||||||
|
|
||||||
|
For backwards compatibility, stanza.attrib returns the stanza itself.
|
||||||
|
|
||||||
|
Older implementations of stanza objects used XML objects directly,
|
||||||
|
requiring the use of .attrib to access attribute values.
|
||||||
|
|
||||||
|
Use of the dictionary syntax with the stanza object itself for
|
||||||
|
accessing stanza interfaces is preferred.
|
||||||
|
"""
|
||||||
|
return self
|
||||||
|
|
||||||
def _fix_ns(self, xpath):
|
def _fix_ns(self, xpath):
|
||||||
"""
|
"""
|
||||||
|
@ -610,10 +655,85 @@ class ElementBase(object):
|
||||||
|
|
||||||
return "/".join(map(fix_ns, xpath.split("/")))
|
return "/".join(map(fix_ns, xpath.split("/")))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
"""
|
||||||
|
Compare the stanza object with another to test for equality.
|
||||||
|
|
||||||
|
Stanzas are equal if their interfaces return the same values,
|
||||||
|
and if they are both instances of ElementBase.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
other -- The stanza object to compare against.
|
||||||
|
"""
|
||||||
|
if not isinstance(other, ElementBase):
|
||||||
|
return False
|
||||||
|
values = self.getStanzaValues()
|
||||||
|
for key in other:
|
||||||
|
if key not in values or values[key] != other[key]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
"""
|
||||||
|
Stanza objects should be treated as True in boolean contexts.
|
||||||
|
|
||||||
|
Python 3.x version.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
"""
|
||||||
|
Stanza objects should be treated as True in boolean contexts.
|
||||||
|
|
||||||
|
Python 2.x version.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""
|
||||||
|
Return the number of iterable substanzas contained in this stanza.
|
||||||
|
"""
|
||||||
|
return len(self.iterables)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""
|
||||||
|
Return an iterator object for iterating over the stanza's substanzas.
|
||||||
|
|
||||||
|
The iterator is the stanza object itself. Attempting to use two
|
||||||
|
iterators on the same stanza at the same time is discouraged.
|
||||||
|
"""
|
||||||
|
self._index = 0
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
"""
|
||||||
|
Return the next iterable substanza.
|
||||||
|
"""
|
||||||
|
self._index += 1
|
||||||
|
if self._index > len(self.iterables):
|
||||||
|
self._index = 0
|
||||||
|
raise StopIteration
|
||||||
|
return self.iterables[self._index - 1]
|
||||||
|
|
||||||
|
def __copy__(self):
|
||||||
|
"""
|
||||||
|
Return a copy of the stanza object that does not share the same
|
||||||
|
underlying XML object.
|
||||||
|
"""
|
||||||
|
return self.__class__(xml=copy.deepcopy(self.xml), parent=self.parent)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""
|
||||||
|
Return a string serialization of the underlying XML object.
|
||||||
|
"""
|
||||||
|
return tostring(self.xml, xmlns='', stanza_ns=self.namespace)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
Use the stanza's serialized XML as its representation.
|
||||||
|
"""
|
||||||
|
return self.__str__()
|
||||||
|
|
||||||
#def __del__(self): #prevents garbage collection of reference cycle
|
|
||||||
# if self.parent is not None:
|
|
||||||
# self.parent.xml.remove(self.xml)
|
|
||||||
|
|
||||||
class StanzaBase(ElementBase):
|
class StanzaBase(ElementBase):
|
||||||
name = 'stanza'
|
name = 'stanza'
|
||||||
|
|
Loading…
Reference in a new issue