66import json
77import sys
88import traceback
9- import typing as t
9+ from collections . abc import Callable
1010from dataclasses import dataclass , field
11-
12- try :
13- from typing import get_args , get_origin # type: ignore
14- except ImportError :
15- # For Python 3.7 support
16- from typing_extensions import get_args , get_origin # type: ignore
11+ from typing import Any , Optional , Union , get_args , get_origin , get_type_hints
1712
1813from docstring_parser import Docstring , DocstringParam , parse # type: ignore
1914
2015from .format import Color , format_text , get_underline
2116
22- __VERSION__ = "0.5 .0"
17+ __VERSION__ = "0.6 .0"
2318
2419
2520# If an annotation is one of these values, we will convert the string value
2924
3025@dataclass
3126class Arguments :
32- args : t . List [str ] = field (default_factory = list )
33- kwargs : t . Dict [str , t . Any ] = field (default_factory = dict )
27+ args : list [str ] = field (default_factory = list )
28+ kwargs : dict [str , Any ] = field (default_factory = dict )
3429
3530
3631@dataclass
@@ -54,14 +49,14 @@ class Command:
5449
5550 """
5651
57- command : t . Callable
58- group_name : t . Optional [str ] = None
59- command_name : t . Optional [str ] = None
60- aliases : t . List [str ] = field (default_factory = list )
52+ command : Callable
53+ group_name : Optional [str ] = None
54+ command_name : Optional [str ] = None
55+ aliases : list [str ] = field (default_factory = list )
6156
6257 def __post_init__ (self ) -> None :
6358 self .command_docstring : Docstring = parse (self .command .__doc__ or "" )
64- self .annotations = t . get_type_hints (self .command )
59+ self .annotations = get_type_hints (self .command )
6560 self .signature = inspect .signature (self .command )
6661 self .solo = False
6762 if not self .command_name :
@@ -85,7 +80,7 @@ def description(self) -> str:
8580 ]
8681 )
8782
88- def _get_docstring_param (self , arg_name ) -> t . Optional [DocstringParam ]:
83+ def _get_docstring_param (self , arg_name ) -> Optional [DocstringParam ]:
8984 for param in self .command_docstring .params :
9085 if param .arg_name == arg_name :
9186 return param
@@ -200,7 +195,7 @@ def call_with(self, arg_class: Arguments):
200195 self .print_help ()
201196 return
202197
203- annotations = t . get_type_hints (self .command )
198+ annotations = get_type_hints (self .command )
204199
205200 kwargs = arg_class .kwargs .copy ()
206201 for index , value in enumerate (arg_class .args ):
@@ -215,8 +210,8 @@ def call_with(self, arg_class: Arguments):
215210
216211 if annotation in CONVERTABLE_TYPES :
217212 value = annotation (value )
218- elif get_origin (annotation ) is t . Union : # type: ignore
219- # t. Union is used to detect t. Optional
213+ elif get_origin (annotation ) is Union : # type: ignore
214+ # Union is used to detect Optional
220215 inner_annotations = get_args (annotation )
221216 filtered = [i for i in inner_annotations if i is not None ]
222217 if len (filtered ) == 1 :
@@ -250,7 +245,7 @@ class CLI:
250245 """
251246
252247 description : str = "Targ CLI"
253- commands : t . List [Command ] = field (default_factory = list , init = False )
248+ commands : list [Command ] = field (default_factory = list , init = False )
254249
255250 def command_exists (self , group_name : str , command_name : str ) -> bool :
256251 """
@@ -277,10 +272,10 @@ def _validate_name(self, name: str) -> bool:
277272
278273 def register (
279274 self ,
280- command : t . Callable ,
281- group_name : t . Optional [str ] = None ,
282- command_name : t . Optional [str ] = None ,
283- aliases : t . List [str ] = [],
275+ command : Callable ,
276+ group_name : Optional [str ] = None ,
277+ command_name : Optional [str ] = None ,
278+ aliases : list [str ] = [],
284279 ):
285280 """
286281 Register a function or coroutine as a CLI command.
@@ -337,15 +332,15 @@ def get_help_text(self) -> str:
337332
338333 return "\n " .join (lines )
339334
340- def _get_cleaned_args (self ) -> t . List [str ]:
335+ def _get_cleaned_args (self ) -> list [str ]:
341336 """
342337 Remove any redundant arguments.
343338 """
344339 return sys .argv [1 :]
345340
346341 def _get_command (
347- self , command_name : str , group_name : t . Optional [str ] = None
348- ) -> t . Optional [Command ]:
342+ self , command_name : str , group_name : Optional [str ] = None
343+ ) -> Optional [Command ]:
349344 for command in self .commands :
350345 if (
351346 command .command_name == command_name
@@ -356,14 +351,14 @@ def _get_command(
356351 return command
357352 return None
358353
359- def _clean_cli_argument (self , value : str ) -> t . Any :
354+ def _clean_cli_argument (self , value : str ) -> Any :
360355 if value in ["True" , "true" , "t" ]:
361356 return True
362357 elif value in ["False" , "false" , "f" ]:
363358 return False
364359 return value
365360
366- def _get_arg_class (self , args : t . List [str ]) -> Arguments :
361+ def _get_arg_class (self , args : list [str ]) -> Arguments :
367362 arguments = Arguments ()
368363 for arg_str in args :
369364 if arg_str .startswith ("--" ):
@@ -401,7 +396,7 @@ def run(self, solo: bool = False):
401396
402397 """
403398 cleaned_args = self ._get_cleaned_args ()
404- command : t . Optional [Command ] = None
399+ command : Optional [Command ] = None
405400
406401 # Work out if to enable tracebacks
407402 try :
0 commit comments