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 ['CLIUtil' ],
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.
@@ -3655,7 +3687,7 @@ def addcommand(
36553687 Decorator to register a command
36563688 """
36573689 def func (cmd : DecoratorCallable ) -> DecoratorCallable :
3658- cls . commands [ cmd .__name__ ] = cmd
3690+ cmd .cliutil_type = _CLIUtilMetaclass . TYPE . COMMAND # type: ignore
36593691 cmd ._spaces = spaces # type: ignore
36603692 cmd ._globsupport = globsupport # type: ignore
36613693 cls ._inspectkwargs (cmd )
@@ -3670,7 +3702,8 @@ def addoutput(cls, cmd: DecoratorCallable) -> Callable[[DecoratorCallable], Deco
36703702 Decorator to register a command output processor
36713703 """
36723704 def func (processor : DecoratorCallable ) -> DecoratorCallable :
3673- cls .commands_output [cmd .__name__ ] = processor
3705+ processor .cliutil_type = _CLIUtilMetaclass .TYPE .OUTPUT # type: ignore
3706+ processor .cliutil_ref = cmd # type: ignore
36743707 cls ._inspectkwargs (processor )
36753708 return processor
36763709 return func
@@ -3681,7 +3714,8 @@ def addcomplete(cls, cmd: DecoratorCallable) -> Callable[[DecoratorCallable], De
36813714 Decorator to register a command completor
36823715 """
36833716 def func (processor : DecoratorCallable ) -> DecoratorCallable :
3684- cls .commands_complete [cmd .__name__ ] = processor
3717+ processor .cliutil_type = _CLIUtilMetaclass .TYPE .COMPLETE # type: ignore
3718+ processor .cliutil_ref = cmd # type: ignore
36853719 return processor
36863720 return func
36873721
0 commit comments