From dcdf93defeda34f5529cb806aed6ecf9532e6638 Mon Sep 17 00:00:00 2001 From: CodeWriter21 Date: Sat, 7 Dec 2024 17:58:08 +0330 Subject: [PATCH] fix: Updated the Argparse module to be usable with python 3.12.3. #2 Version 3.10.1 --- pyproject.toml | 2 +- src/log21/Argparse.py | 59 ++++++++++++++++++++++++++++++++++--------- src/log21/__init__.py | 2 +- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 572ee32..c1fa5a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dependencies = [ "webcolors", "docstring-parser" ] -version = "2.10.0" +version = "2.10.1" [tool.setuptools.packages.find] where = ["src"] diff --git a/src/log21/Argparse.py b/src/log21/Argparse.py index 657a9ef..1c6fa31 100644 --- a/src/log21/Argparse.py +++ b/src/log21/Argparse.py @@ -280,15 +280,28 @@ def _format_actions_usage(self, actions: list, groups): group_actions = set() inserts = {} for group in groups: + if not group._group_actions: + raise ValueError(f'empty group {group}') + try: start = actions.index(group._group_actions[0]) except ValueError: continue else: - end = start + len(group._group_actions) + group_action_count = len(group._group_actions) + end = start + group_action_count if actions[start:end] == group._group_actions: + + suppressed_actions_count = 0 for action in group._group_actions: group_actions.add(action) + if action.help is _argparse.SUPPRESS: + suppressed_actions_count += 1 + + exposed_actions_count = group_action_count - suppressed_actions_count + if not exposed_actions_count: + continue + if not group.required: if start in inserts: inserts[start] += ' [' @@ -298,7 +311,7 @@ def _format_actions_usage(self, actions: list, groups): inserts[end] += ']' else: inserts[end] = ']' - else: + elif exposed_actions_count > 1: if start in inserts: inserts[start] += ' (' else: @@ -941,7 +954,22 @@ def consume_optional(start_index): # get the optional identified at this index option_tuple = option_string_indices[start_index] - action, option_string, explicit_arg = option_tuple + if len(option_tuple) == 3: + action, option_string, explicit_arg = option_tuple + sep = None + elif len(option_tuple) == 4: + action, option_string, sep, explicit_arg = option_tuple + else: + # Tell the user that there seem to have been a change in argparse module + # and if they see this error they should immediately report it in an + # issue at GitHub.com/MPCodeWriter21/log21 with their Python version + raise ValueError( + 'Unknown option tuple length, please report this issue at: ' + 'https://GitHub.com/MPCodeWriter21/log21\n' + f'Python version: {_sys.version}' + f'Option tuple: {option_tuple}' + f'log21 version: {_log21.__version__}' + ) # identify additional optionals in the same arg string # (e.g. -xyz is the same as -x -y -z if no args are required) @@ -964,20 +992,27 @@ def consume_optional(start_index): # of the tail of the option string chars = self.prefix_chars if arg_count == 0 and option_string[1] not in chars: + if sep or explicit_arg[0] in chars: + msg = _gettext('ignored explicit argument %r') + raise _argparse.ArgumentError(action, msg % explicit_arg) action_tuples.append((action, [], option_string)) char = option_string[0] option_string = char + explicit_arg[0] - new_explicit_arg = explicit_arg[1:] or None optionals_map = self._option_string_actions if option_string in optionals_map: action = optionals_map[option_string] - explicit_arg = new_explicit_arg + explicit_arg = explicit_arg[1:] + if not explicit_arg: + sep = explicit_arg = None + elif explicit_arg[0] == '=': + sep = '=' + explicit_arg = explicit_arg[1:] + else: + sep = '' else: - msg = _gettext( - f'ignored explicit argument {explicit_arg!r}' - ) - raise _argparse.ArgumentError(action, msg) - + extras.append(char + explicit_arg) + stop = start_index + 1 + break # if the action expect exactly one argument, we've # successfully matched the option; exit the loop elif arg_count == 1: @@ -989,8 +1024,8 @@ def consume_optional(start_index): # error if a double-dash option did not use the # explicit argument else: - msg = _gettext(f'ignored explicit argument {explicit_arg!r}') - raise _argparse.ArgumentError(action, msg) + msg = _gettext('ignored explicit argument %r') + raise _argparse.ArgumentError(action, msg % explicit_arg) # if there is no explicit argument, try to match the # optional's string arguments with the following strings diff --git a/src/log21/__init__.py b/src/log21/__init__.py index 52438fd..e221da6 100644 --- a/src/log21/__init__.py +++ b/src/log21/__init__.py @@ -24,7 +24,7 @@ from .StreamHandler import StreamHandler, ColorizingStreamHandler __author__ = 'CodeWriter21 (Mehrad Pooryoussof)' -__version__ = '2.10.0' +__version__ = '2.10.1' __github__ = 'Https://GitHub.com/MPCodeWriter21/log21' __all__ = [ 'ColorizingStreamHandler', 'DecolorizingFileHandler', 'ColorizingFormatter',