1919import collections
2020import decimal
2121import difflib
22+ import enum
2223import gzip
2324import inspect
2425import locale
@@ -3566,7 +3567,38 @@ def whois(ip_address):
35663567####################
35673568
35683569
3569- class CLIUtil :
3570+ class _CLIUtilMetaclass (type ):
3571+ class TYPE (enum .Enum ):
3572+ COMMAND = 0
3573+ OUTPUT = 1
3574+ COMPLETE = 2
3575+
3576+ def __new__ (cls , # type: Type[_CLIUtilMetaclass]
3577+ name , # type: str
3578+ bases , # type: Tuple[type, ...]
3579+ dct # type: Dict[str, Any]
3580+ ):
3581+ # type: (...) -> Type[CLIUtil]
3582+ dct ["commands" ] = {
3583+ x .__name__ : x
3584+ for x in dct .values ()
3585+ if getattr (x , "cliutil_type" , None ) == _CLIUtilMetaclass .TYPE .COMMAND
3586+ }
3587+ dct ["commands_output" ] = {
3588+ x .cliutil_ref .__name__ : x
3589+ for x in dct .values ()
3590+ if getattr (x , "cliutil_type" , None ) == _CLIUtilMetaclass .TYPE .OUTPUT
3591+ }
3592+ dct ["commands_complete" ] = {
3593+ x .cliutil_ref .__name__ : x
3594+ for x in dct .values ()
3595+ if getattr (x , "cliutil_type" , None ) == _CLIUtilMetaclass .TYPE .COMPLETE
3596+ }
3597+ newcls = cast (Type ['CLIUtil' ], type .__new__ (cls , name , bases , dct ))
3598+ return newcls
3599+
3600+
3601+ class CLIUtil (metaclass = _CLIUtilMetaclass ):
35703602 """
35713603 Provides a Util class to easily create simple CLI tools in Scapy,
35723604 that can still be used as an API.
@@ -3594,6 +3626,14 @@ def _depcheck(self) -> None:
35943626 # provides completion to command
35953627 commands_complete : Dict [str , Callable [..., List [str ]]] = {}
35963628
3629+ def __init__ (self , cli : bool = True , debug : bool = False ) -> None :
3630+ """
3631+ DEV: overwrite
3632+ """
3633+ if cli :
3634+ self ._depcheck ()
3635+ self .loop (debug = debug )
3636+
35973637 @staticmethod
35983638 def _inspectkwargs (func : DecoratorCallable ) -> None :
35993639 """
@@ -3655,7 +3695,7 @@ def addcommand(
36553695 Decorator to register a command
36563696 """
36573697 def func (cmd : DecoratorCallable ) -> DecoratorCallable :
3658- cls . commands [ cmd .__name__ ] = cmd
3698+ cmd .cliutil_type = _CLIUtilMetaclass . TYPE . COMMAND # type: ignore
36593699 cmd ._spaces = spaces # type: ignore
36603700 cmd ._globsupport = globsupport # type: ignore
36613701 cls ._inspectkwargs (cmd )
@@ -3670,7 +3710,8 @@ def addoutput(cls, cmd: DecoratorCallable) -> Callable[[DecoratorCallable], Deco
36703710 Decorator to register a command output processor
36713711 """
36723712 def func (processor : DecoratorCallable ) -> DecoratorCallable :
3673- cls .commands_output [cmd .__name__ ] = processor
3713+ processor .cliutil_type = _CLIUtilMetaclass .TYPE .OUTPUT # type: ignore
3714+ processor .cliutil_ref = cmd # type: ignore
36743715 cls ._inspectkwargs (processor )
36753716 return processor
36763717 return func
@@ -3681,7 +3722,8 @@ def addcomplete(cls, cmd: DecoratorCallable) -> Callable[[DecoratorCallable], De
36813722 Decorator to register a command completor
36823723 """
36833724 def func (processor : DecoratorCallable ) -> DecoratorCallable :
3684- cls .commands_complete [cmd .__name__ ] = processor
3725+ processor .cliutil_type = _CLIUtilMetaclass .TYPE .COMPLETE # type: ignore
3726+ processor .cliutil_ref = cmd # type: ignore
36853727 return processor
36863728 return func
36873729
0 commit comments