diff --git a/pyquery/pyquery.py b/pyquery/pyquery.py index 53aeaac..be7b4e3 100644 --- a/pyquery/pyquery.py +++ b/pyquery/pyquery.py @@ -344,6 +344,15 @@ def remove_namespaces(self): el.tag = el.tag.split('}', 1)[1] return self + def _serialize_nodes(self, dumps, method): + # Text nodes from contents() cannot go through tostring. + has_text_nodes = any(isinstance(e, str) for e in self) + return ''.join( + e if isinstance(e, str) else dumps( + e, encoding=str, method=method, with_tail=not has_text_nodes) + for e in self + ) + def __str__(self): """xml representation of current nodes:: @@ -353,12 +362,11 @@ def __str__(self): """ - return ''.join([etree.tostring(e, encoding=str) for e in self]) + return self._serialize_nodes(etree.tostring, method='xml') def __unicode__(self): """xml representation of current nodes""" - return u''.join([etree.tostring(e, encoding=str) - for e in self]) + return self._serialize_nodes(etree.tostring, method='xml') def __html__(self): """html representation of current nodes:: @@ -369,8 +377,7 @@ def __html__(self): """ - return u''.join([lxml.html.tostring(e, encoding=str) - for e in self]) + return self._serialize_nodes(lxml.html.tostring, method='html') def __repr__(self): r = [] diff --git a/tests/test_pyquery.py b/tests/test_pyquery.py index b8ee3c8..868a60d 100644 --- a/tests/test_pyquery.py +++ b/tests/test_pyquery.py @@ -359,6 +359,19 @@ def test_comment(self): self.assertEqual(doc.text(), 'bar') +class TestContentsStr(TestCase): + + def test_str_contents_with_text_nodes(self): + doc = pq('hello bold world') + contents = doc.contents() + self.assertEqual(str(contents), 'hello bold world') + self.assertEqual(contents.__html__(), 'hello bold world') + + def test_str_contents_text_only(self): + doc = pq('