зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1296503 - Add an indented_repr function to mozbuild.util. r=ted
This commit is contained in:
Родитель
1ff245b181
Коммит
31a17a020e
|
@ -1,3 +1,4 @@
|
|||
# coding: utf-8
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -12,6 +13,7 @@ import shutil
|
|||
import string
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
from mozfile.mozfile import NamedTemporaryFile
|
||||
from mozunit import (
|
||||
|
@ -24,6 +26,7 @@ from mozbuild.util import (
|
|||
FileAvoidWrite,
|
||||
group_unified_files,
|
||||
hash_file,
|
||||
indented_repr,
|
||||
memoize,
|
||||
memoized_property,
|
||||
pair,
|
||||
|
@ -887,5 +890,35 @@ class TestEnumString(unittest.TestCase):
|
|||
with self.assertRaises(ValueError):
|
||||
type = CompilerType('foo')
|
||||
|
||||
|
||||
class TestIndentedRepr(unittest.TestCase):
|
||||
def test_indented_repr(self):
|
||||
data = textwrap.dedent(r'''
|
||||
{
|
||||
'a': 1,
|
||||
'b': b'abc',
|
||||
b'c': 'xyz',
|
||||
'd': False,
|
||||
'e': {
|
||||
'a': 1,
|
||||
'b': b'2',
|
||||
'c': '3',
|
||||
},
|
||||
'f': [
|
||||
1,
|
||||
b'2',
|
||||
'3',
|
||||
],
|
||||
'pile_of_bytes': b'\xf0\x9f\x92\xa9',
|
||||
'pile_of_poo': '💩',
|
||||
'special_chars': '\\\'"\x08\n\t',
|
||||
'with_accents': 'éàñ',
|
||||
}''').lstrip()
|
||||
|
||||
obj = eval(data)
|
||||
|
||||
self.assertEqual(indented_repr(obj), data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1176,3 +1176,71 @@ class EnumString(unicode):
|
|||
class EnumStringSubclass(EnumString):
|
||||
POSSIBLE_VALUES = possible_values
|
||||
return EnumStringSubclass
|
||||
|
||||
|
||||
def _escape_char(c):
|
||||
# str.encode('unicode_espace') doesn't escape quotes, presumably because
|
||||
# quoting could be done with either ' or ".
|
||||
if c == "'":
|
||||
return "\\'"
|
||||
return unicode(c.encode('unicode_escape'))
|
||||
|
||||
# Mapping table between raw characters below \x80 and their escaped
|
||||
# counterpart, when they differ
|
||||
_INDENTED_REPR_TABLE = {
|
||||
c: e
|
||||
for c, e in map(lambda x: (x, _escape_char(x)),
|
||||
map(unichr, range(128)))
|
||||
if c != e
|
||||
}
|
||||
# Regexp matching all characters to escape.
|
||||
_INDENTED_REPR_RE = re.compile(
|
||||
'([' + ''.join(_INDENTED_REPR_TABLE.values()) + ']+)')
|
||||
|
||||
|
||||
def indented_repr(o, indent=4):
|
||||
'''Similar to repr(), but returns an indented representation of the object
|
||||
|
||||
One notable difference with repr is that the returned representation
|
||||
assumes `from __future__ import unicode_literals`.
|
||||
'''
|
||||
one_indent = ' ' * indent
|
||||
def recurse_indented_repr(o, level):
|
||||
if isinstance(o, dict):
|
||||
yield '{\n'
|
||||
for k, v in sorted(o.items()):
|
||||
yield one_indent * (level + 1)
|
||||
for d in recurse_indented_repr(k, level + 1):
|
||||
yield d
|
||||
yield ': '
|
||||
for d in recurse_indented_repr(v, level + 1):
|
||||
yield d
|
||||
yield ',\n'
|
||||
yield one_indent * level
|
||||
yield '}'
|
||||
elif isinstance(o, bytes):
|
||||
yield 'b'
|
||||
yield repr(o)
|
||||
elif isinstance(o, unicode):
|
||||
yield "'"
|
||||
# We want a readable string (non escaped unicode), but some
|
||||
# special characters need escaping (e.g. \n, \t, etc.)
|
||||
for i, s in enumerate(_INDENTED_REPR_RE.split(o)):
|
||||
if i % 2:
|
||||
for c in s:
|
||||
yield _INDENTED_REPR_TABLE[c]
|
||||
else:
|
||||
yield s
|
||||
yield "'"
|
||||
elif hasattr(o, '__iter__'):
|
||||
yield '[\n'
|
||||
for i in o:
|
||||
yield one_indent * (level + 1)
|
||||
for d in recurse_indented_repr(i, level + 1):
|
||||
yield d
|
||||
yield ',\n'
|
||||
yield one_indent * level
|
||||
yield ']'
|
||||
else:
|
||||
yield repr(o)
|
||||
return ''.join(recurse_indented_repr(o, 0))
|
||||
|
|
Загрузка…
Ссылка в новой задаче