From 0cb8d6ac1e3f34c8b8d7118a0e1f30f8b6968319 Mon Sep 17 00:00:00 2001 From: Aleksei Stepanov Date: Sun, 24 Nov 2019 17:53:11 +0100 Subject: [PATCH] Get rid of python 2.7 traces No manual magic with pseudo-repr for strings anymore (cherry picked from commit 7a9b73144554d42479232894dee89a98eb53715d) --- logwrap/repr_utils.pxd | 3 --- logwrap/repr_utils.py | 26 -------------------------- logwrap/repr_utils.pyx | 33 --------------------------------- test/test_log_wrap.py | 10 +++++----- test/test_repr_utils.py | 28 +++++++++++++--------------- test/test_repr_utils_special.py | 12 ++++++------ 6 files changed, 24 insertions(+), 88 deletions(-) diff --git a/logwrap/repr_utils.pxd b/logwrap/repr_utils.pxd index a6141ad..054475b 100644 --- a/logwrap/repr_utils.pxd +++ b/logwrap/repr_utils.pxd @@ -63,9 +63,6 @@ cdef: cpdef str process_element(self, src: typing.Any, unsigned long indent=?, bint no_indent_start=?) - class PrettyRepr(PrettyFormat): - cdef str _strings_repr(self, unsigned long indent, val: typing.Union[bytes, str]) - class PrettyStr(PrettyFormat): cdef str _strings_str(self, unsigned long indent, val: typing.Union[bytes, str]) diff --git a/logwrap/repr_utils.py b/logwrap/repr_utils.py index 351172b..0b5b7a3 100644 --- a/logwrap/repr_utils.py +++ b/logwrap/repr_utils.py @@ -39,18 +39,6 @@ def _simple(item: typing.Any) -> bool: return not isinstance(item, (list, set, tuple, dict, frozenset)) -SPECIAL_SYMBOLS_ESCAPE = { - "\\": "\\\\", - "\n": "\\n", - "\r": "\\r", - "\f": "\\f", - "\v": "\\v", - "\b": "\\b", - "\t": "\\t", - "\a": "\\a", -} - - class ReprParameter: """Parameter wrapper wor repr and str operations over signature.""" @@ -353,18 +341,6 @@ def _magic_method_name(self) -> str: """ return "__pretty_repr__" - @staticmethod - def _strings_repr(indent: int, val: typing.Union[bytes, str]) -> str: - """Custom repr for strings and binary strings.""" - if isinstance(val, bytes): - string = val.decode(encoding="utf-8", errors="backslashreplace") - prefix = "b" - else: - prefix = "u" - string = val - escaped = "".join(SPECIAL_SYMBOLS_ESCAPE.get(sym, sym) for sym in string) - return "{spc:<{indent}}{prefix}'''{escaped}'''".format(spc="", indent=indent, prefix=prefix, escaped=escaped) - def _repr_simple(self, src: typing.Any, indent: int = 0, no_indent_start: bool = False) -> str: """Repr object without iteration. @@ -380,8 +356,6 @@ def _repr_simple(self, src: typing.Any, indent: int = 0, no_indent_start: bool = indent = 0 if no_indent_start else indent if isinstance(src, set): return "{spc:<{indent}}{val}".format(spc="", indent=indent, val="set(" + " ,".join(map(repr, src)) + ")") - if isinstance(src, (bytes, str)): - return self._strings_repr(indent=indent, val=src) return "{spc:<{indent}}{val!r}".format(spc="", indent=indent, val=src) def _repr_dict_items(self, src: typing.Dict[typing.Any, typing.Any], indent: int = 0) -> typing.Iterator[str]: diff --git a/logwrap/repr_utils.pyx b/logwrap/repr_utils.pyx index 5d10384..1d423b8 100644 --- a/logwrap/repr_utils.pyx +++ b/logwrap/repr_utils.pyx @@ -35,17 +35,6 @@ cdef: """Check for nested iterations: True, if not.""" return not isinstance(item, (list, set, tuple, dict, frozenset)) - dict SPECIAL_SYMBOLS_ESCAPE = { - "\\": "\\\\", - "\n": "\\n", - "\r": "\\r", - "\f": "\\f", - "\v": "\\v", - "\b": "\\b", - "\t": "\\t", - "\a": "\\a" - } - class ReprParameter: """Parameter wrapper wor repr and str operations over signature.""" @@ -333,26 +322,6 @@ cdef class PrettyRepr(PrettyFormat): self._magic_method_name = "__pretty_repr__" cdef: - str _strings_repr( - self, - unsigned long indent, - val: typing.Union[bytes, str] - ): - """Custom repr for strings and binary strings.""" - cdef: - str prefix - str string - str escaped - - if isinstance(val, bytes): - string = val.decode(encoding="utf-8", errors="backslashreplace") - prefix = "b" - else: - prefix = "u" - string = val - escaped = "".join(SPECIAL_SYMBOLS_ESCAPE.get(sym, sym) for sym in string) - return "{spc:<{indent}}{prefix}'''{escaped}'''".format(spc="", indent=indent, prefix=prefix, escaped=escaped) - str _repr_simple( self, src: typing.Any, @@ -373,8 +342,6 @@ cdef class PrettyRepr(PrettyFormat): cdef unsigned long real_indent = 0 if no_indent_start else indent if isinstance(src, set): return "{spc:<{real_indent}}{val}".format(spc="", real_indent=real_indent, val="set(" + " ,".join(map(repr, src)) + ")") - if isinstance(src, (bytes, str)): - return self._strings_repr(indent=real_indent, val=src) return "{spc:<{real_indent}}{val!r}".format(spc="", real_indent=real_indent, val=src) str _repr_callable( diff --git a/test/test_log_wrap.py b/test/test_log_wrap.py index 5dff52b..75f4612 100644 --- a/test/test_log_wrap.py +++ b/test/test_log_wrap.py @@ -811,16 +811,16 @@ def func(arg, arg_secret, arg2='public', secret_arg=('key')): msg="Calling: \n" "'func'(\n" " # POSITIONAL_OR_KEYWORD:\n" - " 'arg'=u'''data''',\n" + " 'arg'='data',\n" " 'arg_secret'=None,\n" - " 'arg2'=u'''public''',\n" + " 'arg2'='public',\n" " 'secret_arg'=None,\n" ")"), mock.call.log(level=logging.DEBUG, msg="Done: 'func'") ] ) - def test_003_override_change_repr(self): + def test_004_override_change_repr(self): class ChangeRepr(logwrap.LogWrap): def post_process_param( self, @@ -848,9 +848,9 @@ def func(arg, arg_secret, arg2='public', secret_arg=('key')): msg="Calling: \n" "'func'(\n" " # POSITIONAL_OR_KEYWORD:\n" - " 'arg'=u'''data''',\n" + " 'arg'='data',\n" " 'arg_secret'=<*hidden*>,\n" - " 'arg2'=u'''public''',\n" + " 'arg2'='public',\n" " 'secret_arg'=<*hidden*>,\n" ")"), mock.call.log(level=logging.DEBUG, msg="Done: 'func'") diff --git a/test/test_repr_utils.py b/test/test_repr_utils.py index 038cab2..f70438d 100644 --- a/test/test_repr_utils.py +++ b/test/test_repr_utils.py @@ -28,20 +28,22 @@ # noinspection PyUnusedLocal,PyMissingOrEmptyDocstring class TestPrettyRepr(unittest.TestCase): - def test_simple(self): + def test_001_simple(self): self.assertEqual( logwrap.pretty_repr(True), repr(True) ) - def test_text(self): + def test_002_text(self): + txt = 'Unicode text' + b_txt = b'bytes text\x01' self.assertEqual( - logwrap.pretty_repr('Unicode text'), "u'''Unicode text'''" + repr(txt), logwrap.pretty_repr(txt) ) self.assertEqual( - logwrap.pretty_repr(b'bytes text\x01'), "b'''bytes text\x01'''" + repr(b_txt), logwrap.pretty_repr(b_txt) ) - def test_iterable(self): + def test_003_iterable(self): self.assertEqual( 'list([{nl:<5}1,{nl:<5}2,{nl:<5}3,\n' '])'.format(nl='\n'), @@ -61,7 +63,7 @@ def test_iterable(self): res.startswith('frozenset({') and res.endswith('\n})') ) - def test_dict(self): + def test_004_dict(self): self.assertEqual( 'dict({\n' ' 1 : 1,\n' @@ -71,7 +73,7 @@ def test_dict(self): logwrap.pretty_repr({1: 1, 2: 2, 33: 33}), ) - def test_nested_obj(self): + def test_005_nested_obj(self): test_obj = [ {1: 2}, {3: {4}}, @@ -111,7 +113,7 @@ def test_nested_obj(self): ) self.assertEqual(exp_repr, logwrap.pretty_repr(test_obj)) - def test_callable(self): + def test_006_callable(self): fmt = "\n{spc:<{indent}}<{obj!r} with interface ({args})>".format def empty_func(): @@ -218,7 +220,7 @@ def tst_classmethod(cls, arg, darg=1, *positional, **named): ) ) - def test_indent(self): + def test_007_indent(self): obj = [[[[[[[[[[123]]]]]]]]]] self.assertEqual( "list([\n" @@ -255,7 +257,7 @@ def test_indent(self): logwrap.pretty_repr(obj, max_indent=10), ) - def test_magic_override(self): + def test_008_magic_override(self): # noinspection PyMissingOrEmptyDocstring class Tst(object): def __repr__(self): @@ -280,13 +282,9 @@ def __pretty_repr__( ) self.assertEqual( result, - "u''''''".format(id(Tst)) + "''".format(id(Tst)) ) - def test_string_escape(self): - src = "n\n b\b r\r f\f v\v t\t \\ a\a" - self.assertEqual("u'''n\\n b\\b r\\r f\\f v\\v t\\t \\\\ a\\a'''", logwrap.pretty_repr(src)) - # noinspection PyUnusedLocal,PyMissingOrEmptyDocstring class TestAnnotated(unittest.TestCase): diff --git a/test/test_repr_utils_special.py b/test/test_repr_utils_special.py index 1cc10ff..1293f3c 100644 --- a/test/test_repr_utils_special.py +++ b/test/test_repr_utils_special.py @@ -29,14 +29,14 @@ # noinspection PyUnusedLocal,PyMissingOrEmptyDocstring class TestPrettyRepr(unittest.TestCase): - def test_dict_subclass(self): + def test_001_dict_subclass(self): class MyDict(dict): """Dict subclass.""" val = MyDict(key='value') self.assertEqual( "MyDict({\n" - " 'key': u'''value''',\n" + " 'key': 'value',\n" "})", logwrap.pretty_repr(val) ) @@ -48,14 +48,14 @@ class MyDict(dict): logwrap.pretty_str(val) ) - def test_typing_specific_dict(self): + def test_002_typing_specific_dict(self): class MyDict(typing.Dict[str, str]): """Dict subclass.""" val = MyDict(key='value') self.assertEqual( "MyDict({\n" - " 'key': u'''value''',\n" + " 'key': 'value',\n" "})", logwrap.pretty_repr(val) ) @@ -68,14 +68,14 @@ class MyDict(typing.Dict[str, str]): ) # @unittest.skipIf(sys.version_info[:2] < (3, 8), 'pep-0589 is implemented in python 3.8') - # def test_typed_dict(self): + # def test_003_typed_dict(self): # class MyDict(typing.TypedDict): # key: str # # val = MyDict(key='value') # self.assertEqual( # "dict({\n" - # " 'key': u'''value''',\n" + # " 'key': 'value',\n" # "})", # logwrap.pretty_repr(val) # )