summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py59
-rw-r--r--tests/test_elementbase.py41
2 files changed, 83 insertions, 17 deletions
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 3e280d61..962cf8ed 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -183,6 +183,48 @@ class ElementBase(object):
self.plugins[interface].setStanzaValues(value)
return self
+ def __getitem__(self, attrib):
+ """
+ Return the value of a stanza interface using dictionary-like syntax.
+
+ Example:
+ >>> msg['body']
+ 'Message contents'
+
+ Stanza interfaces are typically mapped directly to the underlying XML
+ object, but can be overridden by the presence of a getAttrib method
+ (or getFoo where the interface is named foo, etc).
+
+ The search order for interface value retrieval for an interface
+ named 'foo' is:
+ 1. The list of substanzas.
+ 2. The result of calling getFoo.
+ 3. The contents of the foo subelement, if foo is a sub interface.
+ 4. The value of the foo attribute of the XML object.
+ 5. The plugin named 'foo'
+ 6. An empty string.
+
+ Arguments:
+ attrib -- The name of the requested stanza interface.
+ """
+ if attrib == 'substanzas':
+ return self.iterables
+ elif attrib in self.interfaces:
+ get_method = "get%s" % attrib.title()
+ if hasattr(self, get_method):
+ return getattr(self, get_method)()
+ else:
+ if attrib in self.sub_interfaces:
+ return self._getSubText(attrib)
+ else:
+ return self._getAttr(attrib)
+ elif attrib in self.plugin_attrib_map:
+ if attrib not in self.plugins:
+ self.initPlugin(attrib)
+ return self.plugins[attrib]
+ else:
+ return ''
+
@property
def attrib(self): #backwards compatibility
return self
@@ -266,23 +308,6 @@ class ElementBase(object):
def findall(self, xpath):
return self.xml.findall(xpath)
- def __getitem__(self, attrib):
- if attrib == 'substanzas':
- return self.iterables
- elif attrib in self.interfaces:
- if hasattr(self, "get%s" % attrib.title()):
- return getattr(self, "get%s" % attrib.title())()
- else:
- if attrib in self.sub_interfaces:
- return self._getSubText(attrib)
- else:
- return self._getAttr(attrib)
- elif attrib in self.plugin_attrib_map:
- if attrib not in self.plugins: self.initPlugin(attrib)
- return self.plugins[attrib]
- else:
- return ''
-
def __setitem__(self, attrib, value):
if attrib in self.interfaces:
if value is not None:
diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py
index 99c397a5..d6fd457c 100644
--- a/tests/test_elementbase.py
+++ b/tests/test_elementbase.py
@@ -109,5 +109,46 @@ class TestElementBase(SleekTest):
</foo>
""")
+ def testGetItem(self):
+ """Test accessing stanza interfaces."""
+
+ class TestStanza(ElementBase):
+ name = "foo"
+ namespace = "foo"
+ interfaces = set(('bar', 'baz'))
+ sub_interfaces = set(('baz',))
+
+ class TestStanzaPlugin(ElementBase):
+ name = "foobar"
+ namespace = "foo"
+ plugin_attrib = "foobar"
+ interfaces = set(('fizz',))
+
+ TestStanza.subitem = (TestStanza,)
+ registerStanzaPlugin(TestStanza, TestStanzaPlugin)
+
+ stanza = TestStanza()
+ substanza = TestStanza()
+ stanza.append(substanza)
+ stanza.setStanzaValues({'bar': 'a',
+ 'baz': 'b',
+ 'foobar': {'fizz': 'c'}})
+
+ # Test non-plugin interfaces
+ expected = {'substanzas': [substanza],
+ 'bar': 'a',
+ 'baz': 'b',
+ 'meh': ''}
+ for interface, value in expected.items():
+ result = stanza[interface]
+ self.failUnless(result == value,
+ "Incorrect stanza interface access result: %s" % result)
+
+ # Test plugin interfaces
+ self.failUnless(isinstance(stanza['foobar'], TestStanzaPlugin),
+ "Incorrect plugin object result.")
+ self.failUnless(stanza['foobar']['fizz'] == 'c',
+ "Incorrect plugin subvalue result.")
+
suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase)