# HG changeset patch # User cmlenz # Date 1153506203 0 # Node ID 44af12832c5a6fef9e56defc9db8d1fa3479dd5e # Parent ff19219485cc9c7eede2206f505750c0b073129a Bugfix in `builder` module: attribute values need to be converted to strings when generating streams. diff --git a/markup/builder.py b/markup/builder.py --- a/markup/builder.py +++ b/markup/builder.py @@ -11,7 +11,7 @@ # individuals. For the exact contribution history, see the revision # history and logs, available at http://markup.edgewall.org/log/. -from markup.core import Attributes, Namespace, QName, Stream +from markup.core import Attributes, Namespace, QName, Stream, escape __all__ = ['Fragment', 'Element', 'tag'] @@ -34,7 +34,7 @@ return self def __iter__(self): - return iter(self.generate()) + return self._generate() def __repr__(self): return '<%s>' % self.__class__.__name__ @@ -169,14 +169,20 @@ if value is None: continue attr = attr.rstrip('_').replace('_', '-') - self.attrib.set(attr, value) - return Fragment.__call__(self, *args) + self.attrib.set(attr, escape(value)) + Fragment.__call__(self, *args) + return self def __repr__(self): return '<%s "%s">' % (self.__class__.__name__, self.tag) def _generate(self): - yield Stream.START, (self.tag, self.attrib), (None, -1, -1) + attrib = Attributes() + for attr, value in self.attrib: + if not isinstance(value, basestring): + value = unicode(value) + attrib.append((attr, value)) + yield Stream.START, (self.tag, attrib), (None, -1, -1) for kind, data, pos in Fragment._generate(self): yield kind, data, pos yield Stream.END, self.tag, (None, -1, -1) diff --git a/markup/eval.py b/markup/eval.py --- a/markup/eval.py +++ b/markup/eval.py @@ -199,6 +199,7 @@ node.expr = self.visit(node.expr, *args, **kwargs) return node visitUnaryAdd = visitUnarySub = visitNot = visitInvert = _visitUnaryOp + visitBackquote = _visitUnaryOp # Identifiers, Literals and Comprehensions diff --git a/markup/tests/builder.py b/markup/tests/builder.py --- a/markup/tests/builder.py +++ b/markup/tests/builder.py @@ -29,6 +29,16 @@ self.assertEqual((Stream.TEXT, u'Bar', (None, -1, -1)), bits.next()) self.assertEqual((Stream.END, 'a', (None, -1, -1)), bits.next()) + def test_nonstring_attributes(self): + """ + Verify that if an attribute value is given as an int (or some other + non-string type), it is coverted to a string when the stream is + generated. + """ + event = iter(tag.foo(id=3)).next() + self.assertEqual((Stream.START, ('foo', [('id', '3')]), (None, -1, -1)), + event) + def suite(): suite = unittest.TestSuite()