Skip to content

Commit fa76ce3

Browse files
committed
Add "Lineup" class.
1 parent bb17bea commit fa76ce3

File tree

2 files changed

+142
-9
lines changed

2 files changed

+142
-9
lines changed

domdf_python_tools/bases.py

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,24 @@
5858
# this package
5959
from domdf_python_tools.doctools import prettify_docstrings
6060

61-
__all__ = ["Dictable", "NamedList", "namedlist", "UserList", "UserFloat"]
61+
__all__ = [
62+
"Dictable",
63+
"NamedList",
64+
"namedlist",
65+
"UserList",
66+
"UserFloat",
67+
"Lineup",
68+
"_V",
69+
"_LU",
70+
"_T",
71+
"_S",
72+
"_F",
73+
]
6274

75+
_F = TypeVar("_F", bound="UserFloat")
76+
_LU = TypeVar("_LU", bound="Lineup")
77+
_S = TypeVar("_S", bound="UserList")
78+
_T = TypeVar("_T")
6379
_V = TypeVar("_V")
6480

6581

@@ -110,10 +126,6 @@ def __eq__(self, other) -> bool:
110126
return NotImplemented
111127

112128

113-
_T = TypeVar("_T")
114-
_S = TypeVar("_S", bound="UserList")
115-
116-
117129
@prettify_docstrings
118130
class UserList(MutableSequence[_T]):
119131
"""
@@ -363,9 +375,6 @@ def __index__(self) -> int:
363375
...
364376

365377

366-
_F = TypeVar("_F", bound="UserFloat")
367-
368-
369378
@prettify_docstrings
370379
class UserFloat(Real):
371380
"""
@@ -462,6 +471,10 @@ def __getnewargs__(self) -> Tuple[float]:
462471
return self._value
463472

464473
def __trunc__(self) -> int:
474+
"""
475+
Truncates the float to an integer.
476+
"""
477+
465478
return float(self).__trunc__()
466479

467480
def __round__(self, ndigits: Optional[int] = None) -> Union[int, float]: # type: ignore
@@ -533,6 +546,22 @@ def __ceil__(self):
533546
def __floor__(self):
534547
raise NotImplementedError
535548

549+
def __bool__(self) -> bool:
550+
"""
551+
Return ``self != 0``.
552+
"""
553+
554+
return super().__bool__()
555+
556+
def __complex__(self) -> complex:
557+
"""
558+
Returrn :func:`complex(self) <complex>``.
559+
560+
``complex(self) == complex(float(self), 0)``
561+
"""
562+
563+
return super().__complex__()
564+
536565

537566
@prettify_docstrings
538567
class NamedList(UserList[_T]):
@@ -566,3 +595,79 @@ class cls(NamedList):
566595
cls.__name__ = name
567596

568597
return cls
598+
599+
600+
class Lineup(UserList[_T]):
601+
"""
602+
List-like type with fluent methods and some star players.
603+
"""
604+
605+
def replace(self: _LU, what: _T, with_: _T) -> _LU:
606+
r"""
607+
Replace the first instance of ``what`` with ``with_``.
608+
609+
:param what: The object to find and replace.
610+
:param with\_: The new value for the position in the list.
611+
"""
612+
613+
self[self.index(what)] = with_
614+
615+
return self
616+
617+
def sort(
618+
self: _LU,
619+
*,
620+
key=None,
621+
reverse: bool = False,
622+
) -> _LU: # type: ignore
623+
"""
624+
Sort the list in ascending order and return the self.
625+
626+
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
627+
order of two equal elements is maintained).
628+
629+
If a key function is given, apply it once to each list item and sort them,
630+
ascending or descending, according to their function values.
631+
632+
The reverse flag can be set to sort in descending order.
633+
"""
634+
635+
super().sort(key=key, reverse=reverse)
636+
return self
637+
638+
def reverse(self: _LU, ) -> _LU: # type: ignore
639+
super().reverse()
640+
return self
641+
642+
def append(
643+
self: _LU,
644+
item: _T,
645+
) -> _LU: # type: ignore
646+
super().append(item)
647+
return self
648+
649+
def extend(
650+
self: _LU,
651+
other: Iterable[_T],
652+
) -> _LU: # type: ignore
653+
super().extend(other)
654+
return self
655+
656+
def insert(
657+
self: _LU,
658+
i: int,
659+
item: _T,
660+
) -> _LU: # type: ignore
661+
super().insert(i, item)
662+
return self
663+
664+
def remove(
665+
self: _LU,
666+
item: _T,
667+
) -> _LU: # type: ignore
668+
super().remove(item)
669+
return self
670+
671+
def clear(self: _LU, ) -> _LU: # type: ignore
672+
super().clear()
673+
return self

tests/test_userlist.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from typing import Sequence, Type, no_type_check
1313

1414
# this package
15-
from domdf_python_tools.bases import UserList
15+
from domdf_python_tools.bases import Lineup, UserList
1616
from domdf_python_tools.testing import not_pypy
1717
from tests import list_tests
1818

@@ -78,3 +78,31 @@ def test_radd_specials(self):
7878
assert u2 == list("spameggs")
7979
u2 = u.__radd__(UserList("spam"))
8080
assert u2 == list("spameggs")
81+
82+
83+
class TestLineup(TestList):
84+
type2test: Type[Lineup] = Lineup
85+
86+
def test_replace(self):
87+
u = self.type2test([-2, -1, 0, 1, 2])
88+
89+
u.replace(2, 3)
90+
assert u[-1] == 3
91+
92+
def test_fluent(self):
93+
u = self.type2test([2, 1, 0, -1, -2])
94+
95+
assert u.sort() is u
96+
assert u == [-2, -1, 0, 1, 2]
97+
98+
assert u.replace(2, 3) is u
99+
assert u == [-2, -1, 0, 1, 3]
100+
101+
assert u.reverse() is u
102+
assert u == [3, 1, 0, -1, -2]
103+
104+
assert u.append(4) is u
105+
assert u == [3, 1, 0, -1, -2, 4]
106+
107+
assert u.insert(0, -3) is u
108+
assert u == [-3, 3, 1, 0, -1, -2, 4]

0 commit comments

Comments
 (0)