@@ -204,7 +204,10 @@ def __init__(
204
204
name : str ,
205
205
** kwargs : Unpack [CommandOptions ],
206
206
) -> None :
207
+ self ._signature : str | None
208
+
207
209
self ._name : str = name
210
+ self ._parent : Group [Component_T , P ] | None = kwargs .get ("parent" )
208
211
self .callback = callback
209
212
self ._aliases : list [str ] = kwargs .get ("aliases" , [])
210
213
self ._guards : list [Callable [..., bool ] | Callable [..., CoroC ]] = getattr (callback , "__command_guards__" , [])
@@ -215,7 +218,6 @@ def __init__(
215
218
self ._injected : Component_T | None = None
216
219
self ._error : Callable [[Component_T , CommandErrorPayload ], Coro ] | Callable [[CommandErrorPayload ], Coro ] | None = None
217
220
self ._extras : dict [Any , Any ] = kwargs .get ("extras" , {})
218
- self ._parent : Group [Component_T , P ] | None = kwargs .get ("parent" )
219
221
self ._bypass_global_guards : bool = kwargs .get ("bypass_global_guards" , False )
220
222
221
223
self ._before_hook : Callable [[Component_T , Context [Any ]], Coro ] | Callable [[Context [Any ]], Coro ] | None = None
@@ -234,6 +236,73 @@ async def __call__(self, context: Context[BotT]) -> Any:
234
236
callback = self ._callback (self ._injected , context ) if self ._injected else self ._callback (context ) # type: ignore
235
237
return await callback # type: ignore will fix later
236
238
239
+ def _get_signature (self ) -> None :
240
+ params : dict [str , inspect .Parameter ] | None = getattr (self , "_params" , None )
241
+ if not params :
242
+ self ._signature = None
243
+ return
244
+
245
+ help_sig = ""
246
+ for name , param in params .items ():
247
+ s = "<{}>"
248
+
249
+ if param .default is not param .empty :
250
+ s = "[{}]"
251
+
252
+ if param .kind == param .KEYWORD_ONLY :
253
+ s = s .format (f"...{ name } " )
254
+
255
+ elif param .kind == param .VAR_POSITIONAL :
256
+ s = s .format (f"{ name } ..." )
257
+
258
+ elif param .kind == param .POSITIONAL_OR_KEYWORD :
259
+ s = s .format (f"{ name } " )
260
+
261
+ help_sig += f" { s } "
262
+
263
+ self ._signature = help_sig
264
+
265
+ @property
266
+ def signature (self ) -> str | None :
267
+ """Property returning an easily readable POSIX-like argument signature for the command.
268
+
269
+ Useful when generating or displaying help.
270
+
271
+ The format is described below:
272
+
273
+ - ``<arg>`` is a required argument.
274
+ - ``[arg]`` is an optional argument.
275
+ - ``...arg`` is a consume-rest argument.
276
+ - ``arg...`` is an argument list.
277
+
278
+ Example
279
+ -------
280
+
281
+ .. code:: python3
282
+
283
+ @commands.command()
284
+ async def test(ctx: commands.Context, hello: str, world: int) -> None: ...
285
+ ...
286
+
287
+ print(test.signature) # <hello> <world>
288
+
289
+
290
+ @commands.command()
291
+ async def test(ctx: commands.Context, arg: str, *, other: str | None = None) -> None: ...
292
+ ...
293
+
294
+ print(test.signature) # <arg> [...other]
295
+
296
+
297
+ @commands.command()
298
+ async def test(ctx: commands.Context, arg: str, other: str | None = None, *args: str | None = None) -> None: ...
299
+ ...
300
+
301
+ print(test.signature) # <arg> [other] [args...]
302
+
303
+ """
304
+ return self ._signature
305
+
237
306
@property
238
307
def help (self ) -> str :
239
308
"""Property returning a :class:`str` which is the docstring associated with the command callback.
@@ -351,6 +420,7 @@ def callback(
351
420
globalns = {}
352
421
353
422
self ._params : dict [str , inspect .Parameter ] = get_signature_parameters (func , globalns )
423
+ self ._get_signature ()
354
424
355
425
def _convert_literal_type (
356
426
self , context : Context [BotT ], param : inspect .Parameter , args : tuple [Any , ...], * , raw : str | None
0 commit comments