From 6f5169ab871e7bedb098c9ebcafcb46decad59ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Barrois?= Date: Wed, 22 Jan 2014 00:03:10 +0100 Subject: Fix log_pprint (Closes #123). --- factory/utils.py | 21 +++++++++++++++++++-- tests/test_utils.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/factory/utils.py b/factory/utils.py index 48c6eed..b27fd77 100644 --- a/factory/utils.py +++ b/factory/utils.py @@ -20,6 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +from __future__ import unicode_literals + import collections #: String for splitting an attribute name into a @@ -96,11 +98,26 @@ def import_object(module_name, attribute_name): return getattr(module, attribute_name) +def _safe_repr(obj): + try: + obj_repr = repr(obj) + except UnicodeError: + return '' % id(obj) + + try: # Convert to "text type" (= unicode) + return '%s' % obj_repr + except UnicodeError: # non-ascii bytes repr on Py2 + return obj_repr.decode('utf-8') + + def log_pprint(args=(), kwargs=None): kwargs = kwargs or {} return ', '.join( - [str(arg) for arg in args] + - ['%s=%r' % item for item in kwargs.items()] + [repr(arg) for arg in args] + + [ + '%s=%s' % (key, _safe_repr(value)) + for key, value in kwargs.items() + ] ) diff --git a/tests/test_utils.py b/tests/test_utils.py index 8c73935..d321c2a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,11 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +from __future__ import unicode_literals + + import itertools from factory import utils -from .compat import unittest +from .compat import is_python2, unittest class ExtractDictTestCase(unittest.TestCase): @@ -233,6 +236,52 @@ class ImportObjectTestCase(unittest.TestCase): 'this-is-an-invalid-module', '__name__') +class LogPPrintTestCase(unittest.TestCase): + def test_nothing(self): + txt = utils.log_pprint() + self.assertEqual('', txt) + + def test_only_args(self): + txt = utils.log_pprint((1, 2, 3)) + self.assertEqual('1, 2, 3', txt) + + def test_only_kwargs(self): + txt = utils.log_pprint(kwargs={'a': 1, 'b': 2}) + self.assertIn(txt, ['a=1, b=2', 'b=2, a=1']) + + def test_bytes_args(self): + txt = utils.log_pprint((b'\xe1\xe2',)) + expected = "b'\\xe1\\xe2'" + if is_python2: + expected = expected.lstrip('b') + self.assertEqual(expected, txt) + + def test_text_args(self): + txt = utils.log_pprint(('ŧêßŧ',)) + expected = "'ŧêßŧ'" + if is_python2: + expected = "u'\\u0167\\xea\\xdf\\u0167'" + self.assertEqual(expected, txt) + + def test_bytes_kwargs(self): + txt = utils.log_pprint(kwargs={'x': b'\xe1\xe2', 'y': b'\xe2\xe1'}) + expected1 = "x=b'\\xe1\\xe2', y=b'\\xe2\\xe1'" + expected2 = "y=b'\\xe2\\xe1', x=b'\\xe1\\xe2'" + if is_python2: + expected1 = expected1.replace('b', '') + expected2 = expected2.replace('b', '') + self.assertIn(txt, (expected1, expected2)) + + def test_text_kwargs(self): + txt = utils.log_pprint(kwargs={'x': 'ŧêßŧ', 'y': 'ŧßêŧ'}) + expected1 = "x='ŧêßŧ', y='ŧßêŧ'" + expected2 = "y='ŧßêŧ', x='ŧêßŧ'" + if is_python2: + expected1 = "x=u'\\u0167\\xea\\xdf\\u0167', y=u'\\u0167\\xdf\\xea\\u0167'" + expected2 = "y=u'\\u0167\\xdf\\xea\\u0167', x=u'\\u0167\\xea\\xdf\\u0167'" + self.assertIn(txt, (expected1, expected2)) + + class ResetableIteratorTestCase(unittest.TestCase): def test_no_reset(self): i = utils.ResetableIterator([1, 2, 3]) -- cgit v1.2.3 From fb794bd1bcfcb84ec82e72d4f9c3b67624724fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Barrois?= Date: Wed, 22 Jan 2014 00:26:13 +0100 Subject: Update ChangeLog. --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index d18f8e2..4609821 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,8 @@ ChangeLog *Bugfix:* - Fix badly written assert containing state-changing code, spotted by `chsigi `_ (:issue:`126`) + - Don't crash when handling objects whose __repr__ is non-pure-ascii bytes on Py2, + discovered by `mbertheau `_ (:issue:`123`) .. _v2.3.0: -- cgit v1.2.3