@@ -92,20 +92,42 @@ class CommandSet(object):
9292 """
9393
9494 def __init__ (self ) -> None :
95- self ._cmd : Optional [cmd2 .Cmd ] = None
95+ # Private reference to the CLI instance in which this CommandSet running.
96+ # This will be set when the CommandSet is registered and it should be
97+ # accessed by child classes using the self._cmd property.
98+ self .__private_cmd : Optional [cmd2 .Cmd ] = None
99+
96100 self ._settables : Dict [str , Settable ] = {}
97101 self ._settable_prefix = self .__class__ .__name__
98102
103+ @property
104+ def _cmd (self ) -> 'cmd2.Cmd' :
105+ """
106+ Property for child classes to access self.__internal_cmd.
107+
108+ Using this property ensures that self.__internal_cmd has been set
109+ and it tells type checkers that it's no longer a None type.
110+
111+ Override this property if you need to change its return type to a
112+ child class of Cmd.
113+
114+ :raises: CommandSetRegistrationError if CommandSet is not registered.
115+ """
116+ if self .__private_cmd is None :
117+ raise CommandSetRegistrationError ('This CommandSet is not registered' )
118+ return self .__private_cmd
119+
99120 def on_register (self , cmd : 'cmd2.Cmd' ) -> None :
100121 """
101122 Called by cmd2.Cmd as the first step to registering a CommandSet. The commands defined in this class have
102123 not been added to the CLI object at this point. Subclasses can override this to perform any initialization
103124 requiring access to the Cmd object (e.g. configure commands and their parsers based on CLI state data).
104125
105126 :param cmd: The cmd2 main application
127+ :raises: CommandSetRegistrationError if CommandSet is already registered.
106128 """
107- if self ._cmd is None :
108- self ._cmd = cmd
129+ if self .__private_cmd is None :
130+ self .__private_cmd = cmd
109131 else :
110132 raise CommandSetRegistrationError ('This CommandSet has already been registered' )
111133
@@ -129,7 +151,7 @@ def on_unregistered(self) -> None:
129151 Called by ``cmd2.Cmd`` after a CommandSet has been unregistered and all its commands removed from the CLI.
130152 Subclasses can override this to perform remaining cleanup steps.
131153 """
132- self ._cmd = None
154+ self .__private_cmd = None
133155
134156 @property
135157 def settable_prefix (self ) -> str :
@@ -145,7 +167,7 @@ def add_settable(self, settable: Settable) -> None:
145167
146168 :param settable: Settable object being added
147169 """
148- if self ._cmd :
170+ if self .__private_cmd is not None :
149171 if not self ._cmd .always_prefix_settables :
150172 if settable .name in self ._cmd .settables .keys () and settable .name not in self ._settables .keys ():
151173 raise KeyError (f'Duplicate settable: { settable .name } ' )
0 commit comments