Skip to content

Commit

Permalink
Add SupportsIndex support to sequence formatters (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
avylove committed Jan 13, 2022
1 parent 1e53577 commit 165f43d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
9 changes: 5 additions & 4 deletions blessed/sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def ljust(self, width, fillchar=u' '):
:rtype: str
"""
rightside = fillchar * int(
(max(0.0, float(width - self.length()))) / float(len(fillchar)))
(max(0.0, float(width.__index__() - self.length()))) / float(len(fillchar)))
return u''.join((self, rightside))

def rjust(self, width, fillchar=u' '):
Expand All @@ -287,7 +287,7 @@ def rjust(self, width, fillchar=u' '):
:rtype: str
"""
leftside = fillchar * int(
(max(0.0, float(width - self.length()))) / float(len(fillchar)))
(max(0.0, float(width.__index__() - self.length()))) / float(len(fillchar)))
return u''.join((leftside, self))

def center(self, width, fillchar=u' '):
Expand All @@ -300,7 +300,7 @@ def center(self, width, fillchar=u' '):
:returns: String of ``text``, centered by ``width``.
:rtype: str
"""
split = max(0.0, float(width) - self.length()) / 2
split = max(0.0, float(width.__index__()) - self.length()) / 2
leftside = fillchar * int(
(max(0.0, math.floor(split))) / float(len(fillchar)))
rightside = fillchar * int(
Expand All @@ -321,14 +321,15 @@ def truncate(self, width):
"""
output = ""
current_width = 0
target_width = width.__index__()
parsed_seq = iter_parse(self._term, self.padd())

# Retain all text until non-cap width reaches desired width
for text, cap in parsed_seq:
if not cap:
# use wcwidth clipped to 0 because it can sometimes return -1
current_width += max(wcwidth(text), 0)
if current_width > width:
if current_width > target_width:
break
output += text

Expand Down
10 changes: 5 additions & 5 deletions blessed/sequences.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# std imports
import textwrap
from typing import Any, Type, Tuple, Pattern, TypeVar, Iterator, Optional
from typing import Any, Type, Tuple, Pattern, TypeVar, Iterator, Optional, SupportsIndex

# local
from .terminal import Terminal
Expand Down Expand Up @@ -38,10 +38,10 @@ class SequenceTextWrapper(textwrap.TextWrapper):

class Sequence(str):
def __new__(cls: Type[_T], sequence_text: str, term: Terminal) -> _T: ...
def ljust(self, width: int, fillchar: str = ...) -> str: ...
def rjust(self, width: int, fillchar: str = ...) -> str: ...
def center(self, width: int, fillchar: str = ...) -> str: ...
def truncate(self, width: int) -> str: ...
def ljust(self, width: SupportsIndex, fillchar: str = ...) -> str: ...
def rjust(self, width: SupportsIndex, fillchar: str = ...) -> str: ...
def center(self, width: SupportsIndex, fillchar: str = ...) -> str: ...
def truncate(self, width: SupportsIndex) -> str: ...
def length(self) -> int: ...
def strip(self, chars: Optional[str] = ...) -> str: ...
def lstrip(self, chars: Optional[str] = ...) -> str: ...
Expand Down
29 changes: 29 additions & 0 deletions tests/test_sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,3 +728,32 @@ def child(kind):
assert term.truncate(term.red('x' * 1000)) == term.red('x' * term.width)

child(all_terms)


def test_supports_index(all_terms):
"""Ensure sequence formatting methods support objects with __index__()"""

@as_subprocess
def child(kind):
from blessed.sequences import Sequence
from blessed.terminal import Terminal

class Indexable: # pylint: disable=too-few-public-methods
"""Custom class implementing __index__()"""
def __index__(self):
return 100

term = Terminal(kind)
seq = Sequence('abcd', term)
indexable = Indexable()

assert seq.rjust(100) == seq.rjust(indexable)
assert seq.ljust(100) == seq.ljust(indexable)
assert seq.center(100) == seq.center(indexable)
assert seq.truncate(100) == seq.truncate(indexable)

seq = Sequence('abcd' * 30, term)
assert seq.truncate(100) == seq.truncate(indexable)

kind = 'vtwin10' if IS_WINDOWS else 'xterm-256color'
child(kind)

0 comments on commit 165f43d

Please sign in to comment.