@@ -277,14 +277,15 @@ def __init__(self,
277
277
expr = r'\A\s*(\S*?)({})' .format (second_group )
278
278
self ._command_pattern = re .compile (expr )
279
279
280
- def is_valid_command (self , word : str ) -> Tuple [bool , str ]:
280
+ def is_valid_command (self , word : str , * , is_subcommand : bool = False ) -> Tuple [bool , str ]:
281
281
"""Determine whether a word is a valid name for a command.
282
282
283
283
Commands can not include redirection characters, whitespace,
284
284
or termination characters. They also cannot start with a
285
285
shortcut.
286
286
287
287
:param word: the word to check as a command
288
+ :param is_subcommand: Flag whether this command name is a subcommand name
288
289
:return: a tuple of a boolean and an error string
289
290
290
291
If word is not a valid command, return ``False`` and an error string
@@ -297,18 +298,22 @@ def is_valid_command(self, word: str) -> Tuple[bool, str]:
297
298
"""
298
299
valid = False
299
300
301
+ if not isinstance (word , str ):
302
+ return False , 'must be a string. Received {} instead' .format (str (type (word )))
303
+
300
304
if not word :
301
305
return False , 'cannot be an empty string'
302
306
303
307
if word .startswith (constants .COMMENT_CHAR ):
304
308
return False , 'cannot start with the comment character'
305
309
306
- for (shortcut , _ ) in self .shortcuts :
307
- if word .startswith (shortcut ):
308
- # Build an error string with all shortcuts listed
309
- errmsg = 'cannot start with a shortcut: '
310
- errmsg += ', ' .join (shortcut for (shortcut , _ ) in self .shortcuts )
311
- return False , errmsg
310
+ if not is_subcommand :
311
+ for (shortcut , _ ) in self .shortcuts :
312
+ if word .startswith (shortcut ):
313
+ # Build an error string with all shortcuts listed
314
+ errmsg = 'cannot start with a shortcut: '
315
+ errmsg += ', ' .join (shortcut for (shortcut , _ ) in self .shortcuts )
316
+ return False , errmsg
312
317
313
318
errmsg = 'cannot contain: whitespace, quotes, '
314
319
errchars = []
0 commit comments