diff --git a/koji/__init__.py b/koji/__init__.py index b462dd1d..5de0225c 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2966,6 +2966,16 @@ def removeNonprintable(value): # expects raw-encoded string, not unicode return value.translate(None, NONPRINTABLE_CHARS) +def fixPrint(value): + if not value: + return str('') + elif six.PY2 and isinstance(value, six.text_type): + return value.encode('utf8') + elif six.PY3 and isinstance(value, six.binary_type): + return value.decode('utf8') + else: + return value + def fixEncoding(value, fallback='iso8859-15', remove_nonprintable=False): """ Convert value to a 'str' object encoded as UTF-8. @@ -2976,8 +2986,8 @@ def fixEncoding(value, fallback='iso8859-15', remove_nonprintable=False): return six.b('') if isinstance(value, six.text_type): - # value is already unicode, so just convert it - # to a utf8-encoded str + # value is already unicode(py3: str), so just convert it + # to a utf8-encoded str(py3: bytes) s = value.encode('utf8') else: # value is a str, but may be encoded in utf8 or some diff --git a/koji/util.py b/koji/util.py index 545e7aa4..aa8a44a5 100644 --- a/koji/util.py +++ b/koji/util.py @@ -48,9 +48,11 @@ try: except ImportError: # pragma: no cover from sha import new as sha1_constructor + def _changelogDate(cldate): return time.strftime('%a %b %d %Y', time.strptime(koji.formatTime(cldate), '%Y-%m-%d %H:%M:%S')) + def formatChangelog(entries): """Format a list of changelog entries (dicts) into a string representation.""" @@ -59,9 +61,9 @@ def formatChangelog(entries): result += """* %s %s %s -""" % (_changelogDate(entry['date']), entry['author'].encode("utf-8"), - entry['text'].encode("utf-8")) - +""" % (_changelogDate(entry['date']), + koji.fixPrint(entry['author']), + koji.fixPrint(entry['text'])) return result DATE_RE = re.compile(r'(\d+)-(\d+)-(\d+)') diff --git a/tests/test_lib/test_fixEncoding.py b/tests/test_lib/test_fixEncoding.py index 40727246..b5b6f19c 100644 --- a/tests/test_lib/test_fixEncoding.py +++ b/tests/test_lib/test_fixEncoding.py @@ -7,6 +7,7 @@ from __future__ import absolute_import import koji import six import unittest +import mock class FixEncodingTestCase(unittest.TestCase): """Main test case container""" @@ -44,6 +45,23 @@ class FixEncodingTestCase(unittest.TestCase): d = a[:-3] + u'\x00\x01' + a[-3:] self.assertEqual(koji.fixEncoding(d, remove_nonprintable=True), b) + @mock.patch('sys.stdout', new_callable=six.StringIO) + def test_fixPrint(self, stdout): + """Test the fixPrint function""" + expected = '' + for a, b in self.simple_values: + if six.PY3: + self.assertEqual(koji.fixPrint(b), a) + else: + self.assertEqual(koji.fixPrint(b), b) + print(koji.fixPrint(b)) + if six.PY3: + expected = expected + a + '\n' + else: + expected = expected + b + '\n' + actual = stdout.getvalue() + self.assertEqual(actual, expected) + complex_values = [ # [ value, fixed ] [{}, {}],