diff options
-rw-r--r-- | cmd2/cmd2.py | 21 | ||||
-rw-r--r-- | cmd2/parsing.py | 18 | ||||
-rw-r--r-- | tests/test_parsing.py | 8 |
3 files changed, 29 insertions, 18 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 75accb7f..f343cff5 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -2075,11 +2075,11 @@ class Cmd(cmd.Cmd): for arg in reverse_arg_list: if arg.is_escaped: - to_replace = '{{' + str(arg.number) + '}}' - replacement = '{' + str(arg.number) + '}' + to_replace = '{{' + arg.number_str + '}}' + replacement = '{' + arg.number_str + '}' else: - to_replace = '{' + str(arg.number) + '}' - replacement = statement.argv[arg.number] + to_replace = '{' + arg.number_str + '}' + replacement = statement.argv[int(arg.number_str)] parts = resolved.rsplit(to_replace, maxsplit=1) resolved = parts[0] + replacement + parts[1] @@ -2416,8 +2416,9 @@ class Cmd(cmd.Cmd): try: cur_match = normal_matches.__next__() - # Get the number between the braces - cur_num = int(re.findall(MacroArg.digit_pattern, cur_match.group())[0]) + # Get the number string between the braces + cur_num_str = (re.findall(MacroArg.digit_pattern, cur_match.group())[0]) + cur_num = int(cur_num_str) if cur_num < 1: self.perror("Argument numbers must be greater than 0", traceback_war=False) return @@ -2426,7 +2427,7 @@ class Cmd(cmd.Cmd): if cur_num > max_arg_num: max_arg_num = cur_num - arg_list.append(MacroArg(start_index=cur_match.start(), number=cur_num, is_escaped=False)) + arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=False)) except StopIteration: break @@ -2444,10 +2445,10 @@ class Cmd(cmd.Cmd): try: cur_match = escaped_matches.__next__() - # Get the number between the braces - cur_num = int(re.findall(MacroArg.digit_pattern, cur_match.group())[0]) + # Get the number string between the braces + cur_num_str = re.findall(MacroArg.digit_pattern, cur_match.group())[0] - arg_list.append(MacroArg(start_index=cur_match.start(), number=cur_num, is_escaped=True)) + arg_list.append(MacroArg(start_index=cur_match.start(), number_str=cur_num_str, is_escaped=True)) except StopIteration: break diff --git a/cmd2/parsing.py b/cmd2/parsing.py index e1d7b76b..949be42e 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -21,13 +21,15 @@ class MacroArg: Escaped argument syntax: {{5}} """ # The starting index of this argument in the macro value - start_index = attr.ib(validator=attr.validators.instance_of(int), type=int) + start_index = attr.ib(validator=attr.validators.instance_of(int)) - # The number that appears between the braces - number = attr.ib(validator=attr.validators.instance_of(int), type=int) + # The number string that appears between the braces + # This is a string instead of an int because we support unicode digits and must be able + # to reproduce this string later + number_str = attr.ib(validator=attr.validators.instance_of(str)) # Tells if this argument is escaped and therefore needs to be unescaped - is_escaped = attr.ib(validator=attr.validators.instance_of(bool), type=bool) + is_escaped = attr.ib(validator=attr.validators.instance_of(bool)) # Pattern used to find normal argument # Digits surrounded by exactly 1 brace on a side and 1 or more braces on the opposite side @@ -48,16 +50,16 @@ class Macro: """Defines a cmd2 macro""" # Name of the macro - name = attr.ib(validator=attr.validators.instance_of(str), type=str) + name = attr.ib(validator=attr.validators.instance_of(str)) # The string the macro resolves to - value = attr.ib(validator=attr.validators.instance_of(str), type=str) + value = attr.ib(validator=attr.validators.instance_of(str)) # The required number of args the user has to pass to this macro - required_arg_count = attr.ib(validator=attr.validators.instance_of(int), type=int) + required_arg_count = attr.ib(validator=attr.validators.instance_of(int)) # Used to fill in argument placeholders in the macro - arg_list = attr.ib(factory=list, validator=attr.validators.instance_of(list), type=List[MacroArg]) + arg_list = attr.ib(factory=list, validator=attr.validators.instance_of(list)) @attr.s(frozen=True) diff --git a/tests/test_parsing.py b/tests/test_parsing.py index 15da9b7a..1fa460a5 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -786,6 +786,10 @@ def test_macro_normal_arg_pattern(): matches = pattern.findall('{3} text {4} stuff {5}}}}') assert matches == ['{3}', '{4}', '{5}'] + # Unicode digit + matches = pattern.findall('{\N{ARABIC-INDIC DIGIT ONE}}') + assert matches == ['{\N{ARABIC-INDIC DIGIT ONE}}'] + # Invalid strings matches = pattern.findall('5') assert not matches @@ -832,6 +836,10 @@ def test_macro_escaped_arg_pattern(): matches = pattern.findall('{{3}} text {{4}} stuff {{5}}}}') assert matches == ['{{3}}', '{{4}}', '{{5}}'] + # Unicode digit + matches = pattern.findall('{{\N{ARABIC-INDIC DIGIT ONE}}}') + assert matches == ['{{\N{ARABIC-INDIC DIGIT ONE}}}'] + # Invalid strings matches = pattern.findall('5') assert not matches |