[formatter] add 'Lb' format specifier - 'L' for bytes

This commit is contained in:
Mike Fährmann
2025-11-03 13:22:39 +01:00
parent 91a5fd85db
commit 5591a16cd7
3 changed files with 38 additions and 8 deletions

View File

@@ -293,6 +293,16 @@ Format specifiers can be used for advanced formatting by using the options provi
<td><code>{foo:L3/long/}</code></td>
<td><code>long</code></td>
</tr>
<tr>
<td rowspan="2"><code>Lb&lt;maxlen&gt;/&lt;ext&gt;/</code></td>
<td rowspan="2">Same as <code>L</code>, but applies to the <a href="https://docs.python.org/3/library/stdtypes.html#bytes"><code>bytes()</code></a> representation of a string in <a href="https://docs.python.org/3/library/sys.html#sys.getfilesystemencoding">filesystem encoding</a></td>
<td><code>{foo_ja:Lb15/長い/}</code></td>
<td><code>フー・バー</code></td>
</tr>
<tr>
<td><code>{foo_ja:Lb8/長い/}</code></td>
<td><code>長い</code></td>
</tr>
<tr>
<td rowspan="2"><code>X&lt;maxlen&gt;/&lt;ext&gt;/</code></td>
<td rowspan="2">Limit output to <code>&lt;maxlen&gt;</code> characters. Cut output and add <code>&lt;ext&gt;</code> to its end if its length exceeds <code>&lt;maxlen&gt;</code></td>

View File

@@ -413,12 +413,20 @@ def _parse_conversion(format_spec, default):
def _parse_maxlen(format_spec, default):
maxlen, replacement, format_spec = format_spec.split(_SEPARATOR, 2)
maxlen = text.parse_int(maxlen[1:])
fmt = _build_format_func(format_spec, default)
def mlen(obj):
obj = fmt(obj)
return obj if len(obj) <= maxlen else replacement
if maxlen[1] == "b":
maxlen = text.parse_int(maxlen[2:])
def mlen(obj):
obj = fmt(obj)
return obj if len(obj.encode(_ENCODING)) <= maxlen else replacement
else:
maxlen = text.parse_int(maxlen[1:])
def mlen(obj):
obj = fmt(obj)
return obj if len(obj) <= maxlen else replacement
return mlen
@@ -501,13 +509,12 @@ def _parse_sort(format_spec, default):
fmt = _build_format_func(format_spec, default)
if "d" in args or "r" in args:
def sort_desc(obj):
def sort(obj):
return fmt(sorted(obj, reverse=True))
return sort_desc
else:
def sort_asc(obj):
def sort(obj):
return fmt(sorted(obj))
return sort_asc
return sort
def _parse_limit(format_spec, default):

View File

@@ -248,6 +248,19 @@ class TestFormatter(unittest.TestCase):
self._run_test("{a:L50/foo/>51}", "foo")
self._run_test("{a:Lab/foo/}", "foo")
def test_specifier_maxlen_bytes(self):
v = self.kwdict["a"]
self._run_test("{a:Lb5/foo/}" , "foo")
self._run_test("{a:Lb50/foo/}", v)
self._run_test("{a:Lb50/foo/>50}", " " * 39 + v)
self._run_test("{a:Lb50/foo/>51}", "foo")
self._run_test("{a:Lbab/foo/}", "foo")
v = self.kwdict["j"]
self._run_test("{j:Lb5/foo/}" , "foo")
self._run_test("{j:Lb50/foo/}", v)
self._run_test("{j:Lbab/foo/}", "foo")
def test_specifier_join(self):
self._run_test("{l:J}" , "abc")
self._run_test("{l:J,}" , "a,b,c")