| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | # -*- coding: utf-8 -*-from __future__ import absolute_import, unicode_literalsimport pytestimport reimport structfrom case import skipfrom decimal import Decimalfrom pprint import pprintfrom celery.five import (    items, long_t, python_2_unicode_compatible, text_t, values,)from celery.utils.saferepr import safereprD_NUMBERS = {    b'integer': 1,    b'float': 1.3,    b'decimal': Decimal('1.3'),    b'long': long_t(4),    b'complex': complex(13.3),}D_INT_KEYS = {v: k for k, v in items(D_NUMBERS)}QUICK_BROWN_FOX = 'The quick brown fox jumps over the lazy dog.'B_QUICK_BROWN_FOX = b'The quick brown fox jumps over the lazy dog.'D_TEXT = {    b'foo': QUICK_BROWN_FOX,    b'bar': B_QUICK_BROWN_FOX,    b'baz': B_QUICK_BROWN_FOX,    b'xuzzy': B_QUICK_BROWN_FOX,}L_NUMBERS = list(values(D_NUMBERS))D_TEXT_LARGE = {    b'bazxuzzyfoobarlongverylonglong': QUICK_BROWN_FOX * 30,}D_ALL = {    b'numbers': D_NUMBERS,    b'intkeys': D_INT_KEYS,    b'text': D_TEXT,    b'largetext': D_TEXT_LARGE,}D_D_TEXT = {b'rest': D_TEXT}RE_OLD_SET_REPR = re.compile(r'(?<!frozen)set\([\[|\{](.+?)[\}\]]\)')RE_OLD_SET_REPR_REPLACE = r'{\1}'RE_OLD_SET_CUSTOM_REPR = re.compile(r'((?:frozen)?set\d?\()\[(.+?)\](\))')RE_OLD_SET_CUSTOM_REPR_REPLACE = r'\1{\2}\3'RE_EMPTY_SET_REPR = re.compile(r'((?:frozen)?set\d?)\(\[\]\)')RE_EMPTY_SET_REPR_REPLACE = r'\1()'RE_LONG_SUFFIX = re.compile(r'(\d)+L')def old_repr(s):    return text_t(RE_LONG_SUFFIX.sub(        r'\1',        RE_EMPTY_SET_REPR.sub(            RE_EMPTY_SET_REPR_REPLACE,            RE_OLD_SET_REPR.sub(                RE_OLD_SET_REPR_REPLACE,                RE_OLD_SET_CUSTOM_REPR.sub(                    RE_OLD_SET_CUSTOM_REPR_REPLACE,                    repr(s).replace("u'", "'"),                )            ),        ),    )).replace('set([])', 'set()')class list2(list):    pass@python_2_unicode_compatibleclass list3(list):    def __repr__(self):        return list.__repr__(self)class tuple2(tuple):    pass@python_2_unicode_compatibleclass tuple3(tuple):    def __repr__(self):        return tuple.__repr__(self)class set2(set):    pass@python_2_unicode_compatibleclass set3(set):    def __repr__(self):        return set.__repr__(self)class frozenset2(frozenset):    pass@python_2_unicode_compatibleclass frozenset3(frozenset):    def __repr__(self):        return frozenset.__repr__(self)class dict2(dict):    pass@python_2_unicode_compatibleclass dict3(dict):    def __repr__(self):        return dict.__repr__(self)class test_saferepr:    @pytest.mark.parametrize('value', list(values(D_NUMBERS)))    def test_safe_types(self, value):        assert saferepr(value) == old_repr(value)    def test_numbers_dict(self):        assert saferepr(D_NUMBERS) == old_repr(D_NUMBERS)    def test_numbers_list(self):        assert saferepr(L_NUMBERS) == old_repr(L_NUMBERS)    def test_numbers_keys(self):        assert saferepr(D_INT_KEYS) == old_repr(D_INT_KEYS)    def test_text(self):        assert saferepr(D_TEXT) == old_repr(D_TEXT).replace("u'", "'")    def test_text_maxlen(self):        assert saferepr(D_D_TEXT, 100).endswith("...', ...}}")    def test_maxlevels(self):        saferepr(D_ALL, maxlevels=1)    def test_recursion(self):        d = {1: 2, 3: {4: 5}}        d[3][6] = d        res = saferepr(d)        assert 'Recursion on' in res    @pytest.mark.parametrize('value', [        0, 0, 0 + 0j, 0.0, '', b'',        (), tuple2(), tuple3(),        [], list2(), list3(),        set(), set2(), set3(),        frozenset(), frozenset2(), frozenset3(),        {}, dict2(), dict3(),        test_recursion, pprint,        -6, -6, -6 - 6j, -1.5, 'x', b'x', (3,), [3], {3: 6},        (1, 2), [3, 4], {5: 6},        tuple2((1, 2)), tuple3((1, 2)), tuple3(range(100)),        [3, 4], list2([3, 4]), list3([3, 4]), list3(range(100)),        {7}, set2({7}), set3({7}),        frozenset({8}), frozenset2({8}), frozenset3({8}),        dict2({5: 6}), dict3({5: 6}),        range(10, -11, -1)    ])    def test_same_as_repr(self, value):        # Simple objects, small containers, and classes that overwrite __repr__        # For those the result should be the same as repr().        # Ahem.  The docs don't say anything about that -- this appears to        # be testing an implementation quirk.  Starting in Python 2.5, it's        # not true for dicts:  pprint always sorts dicts by key now; before,        # it sorted a dict display if and only if the display required        # multiple lines.  For that reason, dicts with more than one element        # aren't tested here.        native = old_repr(value)        assert saferepr(value) == native    @skip.if_python3()    def test_bytes_with_unicode(self):        class X(object):            def __repr__(self):                return 'æ e i a æ å'.encode(                    'utf-8', errors='backslash replace')        val = X()        assert repr(val)        assert saferepr(val)    @skip.unless_python3()    def test_unicode_bytes(self):        val = 'øystein'.encode('utf-8')        assert saferepr(val) == "b'øystein'"    @skip.unless_python3()    def test_unicode_bytes__long(self):        val = 'øystein'.encode('utf-8') * 1024        assert saferepr(val, maxlen=128).endswith("...'")    @skip.unless_python3()    def test_binary_bytes(self):        val = struct.pack('>QQQ', 12223, 1234, 3123)        if hasattr(bytes, 'hex'):  # Python 3.5+            assert '2fbf' in saferepr(val, maxlen=128)        else:  # Python 3.4            assert saferepr(val, maxlen=128)    @skip.unless_python3()    def test_binary_bytes__long(self):        val = struct.pack('>QQQ', 12223, 1234, 3123) * 1024        result = saferepr(val, maxlen=128)        if hasattr(bytes, 'hex'):  # Python 3.5+            assert '2fbf' in result            assert result.endswith("...'")        else:  # Python 3.4            assert result    def test_repr_raises(self):        class O(object):            def __repr__(self):                raise KeyError('foo')        assert 'Unrepresentable' in saferepr(O())    def test_bytes_with_unicode_py2_and_3(self):        assert saferepr([b'foo', 'a®rgs'.encode('utf-8')])
 |