diff --git a/llsd/serde_xml.py b/llsd/serde_xml.py
index 99d39b8..7dfeaa2 100644
--- a/llsd/serde_xml.py
+++ b/llsd/serde_xml.py
@@ -44,17 +44,13 @@ def _elt(self, name, contents=None):
If 'contents' is omitted, write .
If 'contents' is bytes, write contents.
If 'contents' is str, write contents.encode('utf8').
- If 'contents' is callable, write , call contents(), write .
"""
if not contents:
self.stream.writelines([b"<", name, b" />"])
else:
- self.stream.writelines([b"<", name, b">"])
- if callable(contents):
- contents()
- else:
- self.stream.write(_str_to_bytes(contents))
- self.stream.writelines([b"", name, b">"])
+ self.stream.writelines([b"<", name, b">",
+ _str_to_bytes(contents),
+ b"", name, b">"])
def xml_esc(self, v):
"Escape string or unicode object v for xml output"
@@ -100,15 +96,16 @@ def _URI(self, v):
def _DATE(self, v):
return self._elt(b'date', _format_datestr(v))
def _ARRAY(self, v):
- return self._elt(
- b'array',
- lambda: [self._generate(item) for item in v])
+ self.stream.write(b'')
+ for item in v:
+ self._generate(item)
+ self.stream.write(b'')
def _MAP(self, v):
- return self._elt(
- b'map',
- lambda: [(self._elt(b'key', self.xml_esc(UnicodeType(key))),
- self._generate(value))
- for key, value in v.items()])
+ self.stream.write(b'')
def _generate(self, something):
"Generate xml from a single python object."
@@ -127,8 +124,10 @@ def _write(self, something):
:param something: A python object (typically a dict) to be serialized.
"""
- self.stream.write(b'')
- self._elt(b"llsd", lambda: self._generate(something))
+ self.stream.write(b''
+ b'')
+ self._generate(something)
+ self.stream.write(b'')
class LLSDXMLPrettyFormatter(LLSDXMLFormatter):
diff --git a/tests/llsd_test.py b/tests/llsd_test.py
index 6691c1c..46f64fe 100644
--- a/tests/llsd_test.py
+++ b/tests/llsd_test.py
@@ -1345,6 +1345,20 @@ def testMap(self):
map_within_map_xml)
self.assertXMLRoundtrip({}, blank_map_xml)
+ def testDeepMap(self):
+ """
+ Test that formatting a deeply nested map does not cause a RecursionError
+ """
+
+ test_map = {"foo":"bar", "depth":0, "next":None}
+ max_depth = 200
+ for depth in range(max_depth):
+ test_map = {"foo":"bar", "depth":depth, "next":test_map}
+
+ # this should not throw an exception.
+ test_xml = self.llsd.as_xml(test_map)
+
+
def testBinary(self):
"""
Test the parse and serialization of input type : binary.