Skip to content

Commit ec7dfe5

Browse files
committed
python: support W presentation type
Problem: Python does not take into account wide characters (i.e. emojis) when attempting to do output alignment. So when outputting wide characters in flux-jobs, the output can be poor due to the characters have different output widths. Solution: Add a new W presentation type that can adjust formating of the form "(<|>)N", e.g. {id.emoji:>12W}. The output width will be adjusted given the number of wide characters that exist in the string.
1 parent a4f3786 commit ec7dfe5

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/bindings/python/flux/util.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import sys
2525
import threading
2626
import traceback
27+
import unicodedata
2728
from collections import abc, namedtuple
2829
from datetime import datetime, timedelta
2930
from operator import attrgetter
@@ -579,6 +580,27 @@ def format_field(self, value, spec):
579580
basecases = empty_outputs()
580581
value = "-" if str(value) in basecases else str(value)
581582
spec = spec[:-1] + "s"
583+
584+
# Normal python output will not consider emoji width with
585+
# width formatting. So we will adjust the output width of
586+
# field accordingly to account for it if the "W" modifier
587+
# is specified.
588+
if spec.endswith("W") and isinstance(value, str):
589+
match = re.search(r"^([<>])(\d+)W", spec)
590+
if match:
591+
align = match[1]
592+
width = int(match[2])
593+
display_width = wcswidth(value)
594+
normal_width = len(value)
595+
width_diff = display_width - normal_width
596+
if width_diff > 0 and width > width_diff:
597+
width -= width_diff
598+
spec = f"{align}{width}s"
599+
# if spec was not modified above, need to convert to "W"
600+
# conversion to "s"
601+
if spec.endswith("W"):
602+
spec = spec[:-1] + "s"
603+
582604
retval = super().format_field(value, spec)
583605

584606
if denote_truncation and len(retval) < len(str(value)):
@@ -735,6 +757,7 @@ class FormatSpec:
735757
"precision_str",
736758
"type",
737759
"hyphen",
760+
"wide",
738761
"truncate",
739762
)
740763

@@ -759,6 +782,7 @@ def __init__(self, spec):
759782
r"(?:(?P<decimal>\.)(?P<precision_str>\d+))?"
760783
r"(?P<type>[bcdeEfFgGnosxX%])?"
761784
r"(?P<hyphen>h)?"
785+
r"(?P<wide>W)?"
762786
r"(?P<truncate>\+)?"
763787
)
764788
try:

0 commit comments

Comments
 (0)