[diffoscope] 01/02: presenters: PartialString: preserve {{ and }} escapes when partially formatting stuff
Ximin Luo
infinity0 at debian.org
Mon Jun 19 22:27:21 CEST 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch WIP/humungous-diffs
in repository diffoscope.
commit 7a870837881d629a81788091c05431756179afa3
Author: Ximin Luo <infinity0 at debian.org>
Date: Mon Jun 19 18:02:40 2017 +0200
presenters: PartialString: preserve {{ and }} escapes when partially formatting stuff
---
diffoscope/presenters/utils.py | 31 +++++++++++++++++++++----------
tests/test_presenters.py | 7 +++++++
2 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/diffoscope/presenters/utils.py b/diffoscope/presenters/utils.py
index 69040d6..c46773a 100644
--- a/diffoscope/presenters/utils.py
+++ b/diffoscope/presenters/utils.py
@@ -104,12 +104,18 @@ def create_limited_print_func(print_func, max_page_size):
return fn
-class Formatter(string.Formatter):
+class PartialFormatter(string.Formatter):
+ @staticmethod
+ def escape(x):
+ return x.replace("}", "}}").replace("{", "{{")
def get_value(self, key, args, kwargs):
return args[key] if isinstance(key, int) else args[int(key)]
def arg_of_field_name(self, field_name, args):
x = int(_string.formatter_field_name_split(field_name)[0])
return x if x >= 0 else len(args) + x
+ def parse(self, *args, **kwargs):
+ # Preserve {{ and }} escapes when formatting
+ return map(lambda x: (self.escape(x[0]),) + x[1:], super().parse(*args, **kwargs))
class FormatPlaceholder(object):
@@ -192,7 +198,8 @@ class PartialString(object):
So you probably want to avoid such usages. The exact behaviour of these
might change in the future, too.
"""
- formatter = Formatter()
+ formatter = PartialFormatter()
+ escape = staticmethod(PartialFormatter.escape)
def __init__(self, fmtstr="", *holes):
# Ensure the format string is valid, and figure out some basic stats
@@ -217,8 +224,12 @@ class PartialString(object):
def __repr__(self):
return "%s%r" % (self.__class__.__name__, (self._fmtstr,) + self.holes)
+ def _format(self, *mapping):
+ # format a string but preserve {{ and }} escapes
+ return self.formatter.vformat(self._fmtstr, mapping, None)
+
def _offset_fmtstr(self, offset):
- return self._fmtstr.format(*(FormatPlaceholder(i + offset) for i in range(len(self.holes))))
+ return self._format(*(FormatPlaceholder(i + offset) for i in range(len(self.holes))))
def _pformat(self, mapping):
new_holes = []
@@ -235,22 +246,22 @@ class PartialString(object):
out = FormatPlaceholder(len(new_holes))
new_holes.append(k)
real_mapping.append(out)
- return self._fmtstr.format(*real_mapping), new_holes
+ return real_mapping, new_holes
def size(self, hole_size=1):
return self.base_len + hole_size * self.num_holes
- def pformat(self, mapping):
+ def pformat(self, mapping={}):
"""Partially apply a mapping, returning a new PartialString."""
- new_fmtstr, new_holes = self._pformat(mapping)
- return self.__class__(new_fmtstr, *new_holes)
+ real_mapping, new_holes = self._pformat(mapping)
+ return self.__class__(self._format(*real_mapping), *new_holes)
- def format(self, mapping):
+ def format(self, mapping={}):
"""Fully apply a mapping, returning a string."""
- new_fmtstr, new_holes = self._pformat(mapping)
+ real_mapping, new_holes = self._pformat(mapping)
if new_holes:
raise ValueError("not all holes filled: %r" % new_holes)
- return new_fmtstr
+ return self._fmtstr.format(*real_mapping)
@classmethod
def of(cls, obj):
diff --git a/tests/test_presenters.py b/tests/test_presenters.py
index 62b3ac2..d8cfd5c 100644
--- a/tests/test_presenters.py
+++ b/tests/test_presenters.py
@@ -177,3 +177,10 @@ def test_partial_string():
assert (t.format({key[0]: "line1", key[1]: "line2", key[2]: "line3"})
== 'x: line1\ny: line2\nz: line3\n')
assert t.size(hole_size=5) == 27
+
+def test_partial_string_escape():
+ esc = PartialString("{{}} {0}", None)
+ assert esc.pformat({None: PartialString.of(None)}) == esc
+ assert esc.format({None: "0"}) == "{} 0"
+ with pytest.raises(ValueError):
+ PartialString("{}")
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git
More information about the diffoscope
mailing list