44import os
55import re
66import sys
7+ from collections .abc import Callable
78from functools import cmp_to_key
8- from typing import Any , Callable , Dict , List , Optional , Tuple , Union
9- import re
9+ from typing import Any
1010
1111
1212class InteractiveSort :
1313 def __init__ (self , args : argparse .Namespace ) -> None :
14- self .data : List [str ] = []
14+ self .data : list [str ] = []
1515 self .args : argparse .Namespace = args
16- self .month_map : Dict [str , int ] = {
16+ self .month_map : dict [str , int ] = {
1717 "JAN" : 1 ,
1818 "FEB" : 2 ,
1919 "MAR" : 3 ,
@@ -32,7 +32,7 @@ def get_sort_key(self, item: str) -> str:
3232 """Generates a key for sorting based on the provided arguments."""
3333 key : str = item
3434 if self .args .field_separator :
35- fields : List [str ] = key .split (self .args .field_separator )
35+ fields : list [str ] = key .split (self .args .field_separator )
3636 if fields :
3737 key = fields [0 ]
3838 else :
@@ -48,28 +48,28 @@ def month_sort_key(self, item: str) -> int:
4848 """Extracts and converts the month from the beginning of the string (or first field)."""
4949 text_to_check : str = item
5050 if self .args .field_separator :
51- fields : List [str ] = item .split (self .args .field_separator )
51+ fields : list [str ] = item .split (self .args .field_separator )
5252 if fields :
5353 text_to_check = fields [0 ]
5454 else :
5555 return 0
5656
57- match : Optional [ re .Match [str ]] = re .match (r"^(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s*" , text_to_check , re .IGNORECASE )
57+ match : re .Match [str ] | None = re .match (r"^(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s*" , text_to_check , re .IGNORECASE )
5858 if match :
5959 return self .month_map .get (match .group (1 ).upper (), 0 ) # 0 for unknown
6060 return 0 # Treat lines without a month at the beginning as "unknown"
6161
62- def human_numeric_sort_key (self , item : str ) -> Union [ float , str ] :
62+ def human_numeric_sort_key (self , item : str ) -> float | str :
6363 """Converts a human-readable number string to a comparable tuple (or from the first field)."""
6464 text_to_check : str = item
6565 if self .args .field_separator :
66- fields : List [str ] = item .split (self .args .field_separator )
66+ fields : list [str ] = item .split (self .args .field_separator )
6767 if fields :
6868 text_to_check = fields [0 ]
6969 else :
7070 return item # Fallback
7171
72- parts : List [ Tuple [str , str ]] = re .findall (r"(\d+\.?\d*)([KMGTPEZY]?)" , text_to_check , re .IGNORECASE )
72+ parts : list [ tuple [str , str ]] = re .findall (r"(\d+\.?\d*)([KMGTPEZY]?)" , text_to_check , re .IGNORECASE )
7373 if parts :
7474 value_str : str
7575 unit : str
@@ -98,11 +98,11 @@ def human_numeric_sort_key(self, item: str) -> Union[float, str]:
9898 except ValueError :
9999 return text_to_check # Keep original string if not convertible to number
100100
101- def numeric_sort_key (self , item : str ) -> Union [ float , str ] :
101+ def numeric_sort_key (self , item : str ) -> float | str :
102102 """Tries to convert the item (or first field) to a float for numeric sorting."""
103103 text_to_check : str = item
104104 if self .args .field_separator :
105- fields : List [str ] = item .split (self .args .field_separator )
105+ fields : list [str ] = item .split (self .args .field_separator )
106106 if fields :
107107 text_to_check = fields [0 ]
108108 else :
@@ -122,16 +122,16 @@ def compare_items(self, item1: str, item2: str) -> int:
122122 return key1 - key2
123123
124124 if self .args .human_numeric_sort :
125- key1_human : Union [ float , str ] = self .human_numeric_sort_key (item1 )
126- key2_human : Union [ float , str ] = self .human_numeric_sort_key (item2 )
127- if isinstance (key1_human , ( int , float )) and isinstance (key2_human , ( int , float ) ):
125+ key1_human : float | str = self .human_numeric_sort_key (item1 )
126+ key2_human : float | str = self .human_numeric_sort_key (item2 )
127+ if isinstance (key1_human , int | float ) and isinstance (key2_human , int | float ):
128128 if key1_human != key2_human :
129129 return int (key1_human - key2_human )
130130
131131 if self .args .numeric_sort :
132- key1_numeric : Union [ float , str ] = self .numeric_sort_key (item1 )
133- key2_numeric : Union [ float , str ] = self .numeric_sort_key (item2 )
134- if isinstance (key1_numeric , ( int , float )) and isinstance (key2_numeric , ( int , float ) ):
132+ key1_numeric : float | str = self .numeric_sort_key (item1 )
133+ key2_numeric : float | str = self .numeric_sort_key (item2 )
134+ if isinstance (key1_numeric , int | float ) and isinstance (key2_numeric , int | float ):
135135 if key1_numeric != key2_numeric :
136136 return int (key1_numeric - key2_numeric )
137137
@@ -148,10 +148,7 @@ def compare_items(self, item1: str, item2: str) -> int:
148148 def add_item (self , item : str ) -> None :
149149 """Adds an item to the sorted data using a custom comparison."""
150150 if not self .args .month_sort and not self .args .human_numeric_sort and not self .args .numeric_sort :
151-
152- def key_func (x : str ) -> str :
153- return self .get_sort_key (x )
154-
151+ key_func : Callable [[str ], Any ] = self .get_sort_key
155152 else :
156153 key_func = cmp_to_key (self .compare_items )
157154
@@ -165,7 +162,7 @@ def display_sorted(self) -> None:
165162 os .system ("cls" if os .name == "nt" else "clear" )
166163
167164 print ("--- Interactive Sorted Data ---" , file = output_stream )
168- items_to_display : List [str ] = self .data
165+ items_to_display : list [str ] = self .data
169166 if self .args .unique :
170167 items_to_display = sorted (
171168 set (items_to_display ), key = lambda x : self .data .index (x )
@@ -179,7 +176,7 @@ def display_sorted(self) -> None:
179176
180177 def output_final_sorted (self ) -> None :
181178 """Outputs the final sorted data to stdout (used when stderr flag is set)."""
182- items_to_display : List [str ] = self .data
179+ items_to_display : list [str ] = self .data
183180 if self .args .unique :
184181 items_to_display = sorted (
185182 set (items_to_display ), key = lambda x : self .data .index (x )
0 commit comments