22# License, v. 2.0. If a copy of the MPL was not distributed with this
33# file, You can obtain one at https://mozilla.org/MPL/2.0/.
44
5- # Copyright (c) 2021 Rapptz
5+ # Copyright (c) 2025 Rapptz
66
7- from datetime import timezone
7+ from __future__ import annotations
8+
9+ import datetime
10+
11+ from typing import Any , Iterable , Optional , Sequence
812
913
1014class plural :
11- def __init__ (self , value ):
12- self .value = value
15+ def __init__ (self , value : int ):
16+ self .value : int = value
1317
14- def __format__ (self , format_spec ) :
18+ def __format__ (self , format_spec : str ) -> str :
1519 v = self .value
16- singular , sep , plural = format_spec .partition ("|" )
20+ skip_value = format_spec .endswith ("!" )
21+ if skip_value :
22+ format_spec = format_spec [:- 1 ]
23+
24+ singular , _ , plural = format_spec .partition ("|" )
1725 plural = plural or f"{ singular } s"
26+ if skip_value :
27+ if abs (v ) != 1 :
28+ return plural
29+ return singular
30+
1831 if abs (v ) != 1 :
1932 return f"{ v } { plural } "
2033 return f"{ v } { singular } "
2134
2235
23- def human_join (seq , delim = ", " , final = "or" ):
36+ def human_join (seq : Sequence [ str ] , delim : str = ", " , final : str = "or" ) -> str :
2437 size = len (seq )
2538 if size == 0 :
2639 return ""
@@ -36,27 +49,27 @@ def human_join(seq, delim=", ", final="or"):
3649
3750class TabularData :
3851 def __init__ (self ):
39- self ._widths = []
40- self ._columns = []
41- self ._rows = []
52+ self ._widths : list [ int ] = []
53+ self ._columns : list [ str ] = []
54+ self ._rows : list [ list [ str ]] = []
4255
43- def set_columns (self , columns ):
56+ def set_columns (self , columns : list [ str ] ):
4457 self ._columns = columns
4558 self ._widths = [len (c ) + 2 for c in columns ]
4659
47- def add_row (self , row ) :
60+ def add_row (self , row : Iterable [ Any ]) -> None :
4861 rows = [str (r ) for r in row ]
4962 self ._rows .append (rows )
5063 for index , element in enumerate (rows ):
5164 width = len (element ) + 2
5265 if width > self ._widths [index ]:
5366 self ._widths [index ] = width
5467
55- def add_rows (self , rows ) :
68+ def add_rows (self , rows : Iterable [ Iterable [ Any ]]) -> None :
5669 for row in rows :
5770 self .add_row (row )
5871
59- def render (self ):
72+ def render (self ) -> str :
6073 """Renders a table in rST format.
6174
6275 Example:
@@ -88,10 +101,19 @@ def get_entry(d):
88101 return "\n " .join (to_draw )
89102
90103
91- def format_dt (dt , style = None ):
104+ def format_dt (dt : datetime . datetime , style : Optional [ str ] = None ) -> str :
92105 if dt .tzinfo is None :
93- dt = dt .replace (tzinfo = timezone .utc )
106+ dt = dt .replace (tzinfo = datetime . timezone .utc )
94107
95108 if style is None :
96109 return f"<t:{ int (dt .timestamp ())} >"
97110 return f"<t:{ int (dt .timestamp ())} :{ style } >"
111+
112+
113+ def tick (opt : Optional [bool ], / ) -> str :
114+ lookup = {
115+ True : "<:greenTick:330090705336664065>" ,
116+ False : "<:redTick:330090723011592193>" ,
117+ None : "<:greyTick:563231201280917524>" ,
118+ }
119+ return lookup .get (opt , "<:redTick:330090723011592193>" )
0 commit comments