Mercurial > genshi > mirror
changeset 688:d8571da25bc5 trunk
The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
author | cmlenz |
---|---|
date | Wed, 12 Mar 2008 20:46:34 +0000 |
parents | 8ce1a80c8843 |
children | 3881a602048a |
files | ChangeLog genshi/core.py genshi/output.py genshi/tests/core.py |
diffstat | 4 files changed, 45 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -46,6 +46,9 @@ of the serializer (ticket #146). * Assigning to a variable named `data` in a Python code block no longer breaks context lookup. + * The `Stream.render` now accepts an optional `out` parameter that can be + used to pass in a writable file-like object to use for assembling the + output, instead of building a big string and returning it. Version 0.4.4
--- a/genshi/core.py +++ b/genshi/core.py @@ -149,7 +149,7 @@ """ return reduce(operator.or_, (self,) + filters) - def render(self, method=None, encoding='utf-8', **kwargs): + def render(self, method=None, encoding='utf-8', out=None, **kwargs): """Return a string representation of the stream. Any additional keyword arguments are passed to the serializer, and thus @@ -161,15 +161,22 @@ the stream is used :param encoding: how the output string should be encoded; if set to `None`, this method returns a `unicode` object - :return: a `str` or `unicode` object + :param out: a file-like object that the output should be written to + instead of being returned as one big string; note that if + this is a file or socket (or similar), the `encoding` must + not be `None` (that is, the output must be encoded) + :return: a `str` or `unicode` object (depending on the `encoding` + parameter), or `None` if the `out` parameter is provided :rtype: `basestring` + :see: XMLSerializer, XHTMLSerializer, HTMLSerializer, TextSerializer + :note: Changed in 0.5: added the `out` parameter """ from genshi.output import encode if method is None: method = self.serializer or 'xml' generator = self.serialize(method=method, **kwargs) - return encode(generator, method=method, encoding=encoding) + return encode(generator, method=method, encoding=encoding, out=out) def select(self, path, namespaces=None, variables=None): """Return a new stream that contains the events matching the given
--- a/genshi/output.py +++ b/genshi/output.py @@ -30,7 +30,7 @@ 'XHTMLSerializer', 'HTMLSerializer', 'TextSerializer'] __docformat__ = 'restructuredtext en' -def encode(iterator, method='xml', encoding='utf-8'): +def encode(iterator, method='xml', encoding='utf-8', out=None): """Encode serializer output into a string. :param iterator: the iterator returned from serializing a stream (basically @@ -39,16 +39,27 @@ representable in the specified encoding are treated :param encoding: how the output string should be encoded; if set to `None`, this method returns a `unicode` object - :return: a string or unicode object (depending on the `encoding` parameter) + :param out: a file-like object that the output should be written to + instead of being returned as one big string; note that if + this is a file or socket (or similar), the `encoding` must + not be `None` (that is, the output must be encoded) + :return: a `str` or `unicode` object (depending on the `encoding` + parameter), or `None` if the `out` parameter is provided + :since: version 0.4.1 + :note: Changed in 0.5: added the `out` parameter """ - output = u''.join(list(iterator)) if encoding is not None: errors = 'replace' if method != 'text' and not isinstance(method, TextSerializer): errors = 'xmlcharrefreplace' - return output.encode(encoding, errors) - return output + _encode = lambda string: string.encode(encoding, errors) + else: + _encode = lambda string: string + if out is None: + return _encode(u''.join(list(iterator))) + for chunk in iterator: + out.write(_encode(chunk)) def get_serializer(method='xml', **kwargs): """Return a serializer object for the given method.
--- a/genshi/tests/core.py +++ b/genshi/tests/core.py @@ -14,6 +14,10 @@ import doctest import pickle from StringIO import StringIO +try: + from cStringIO import StringIO as cStringIO +except ImportError: + cStringIO = StringIO import unittest from genshi import core @@ -35,6 +39,18 @@ xml = XML('<li>Über uns</li>') self.assertEqual('<li>Über uns</li>', xml.render(encoding='ascii')) + def test_render_output_stream_utf8(self): + xml = XML('<li>Über uns</li>') + strio = cStringIO() + self.assertEqual(None, xml.render(out=strio)) + self.assertEqual('<li>Über uns</li>', strio.getvalue()) + + def test_render_output_stream_unicode(self): + xml = XML('<li>Über uns</li>') + strio = StringIO() + self.assertEqual(None, xml.render(encoding=None, out=strio)) + self.assertEqual(u'<li>Über uns</li>', strio.getvalue()) + def test_pickle(self): xml = XML('<li>Foo</li>') buf = StringIO()