| Conditions | 33 |
| Total Lines | 127 |
| Code Lines | 92 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like sphinxarg.parser.parse_parser() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | import re |
||
| 49 | def parse_parser(parser, data=None, **kwargs): |
||
| 50 | if data is None: |
||
| 51 | data = { |
||
| 52 | 'name': '', |
||
| 53 | 'usage': parser.format_usage().strip(), |
||
| 54 | 'bare_usage': _format_usage_without_prefix(parser), |
||
| 55 | 'prog': parser.prog, |
||
| 56 | } |
||
| 57 | _try_add_parser_attribute(data, parser, 'description') |
||
| 58 | _try_add_parser_attribute(data, parser, 'epilog') |
||
| 59 | for action in parser._get_positional_actions(): |
||
| 60 | if not isinstance(action, _SubParsersAction): |
||
| 61 | continue |
||
| 62 | helps = {} |
||
| 63 | for item in action._choices_actions: |
||
| 64 | helps[item.dest] = item.help |
||
| 65 | |||
| 66 | # commands which share an existing parser are an alias, |
||
| 67 | # don't duplicate docs |
||
| 68 | subsection_alias = {} |
||
| 69 | subsection_alias_names = set() |
||
| 70 | for name, subaction in action._name_parser_map.items(): |
||
| 71 | if subaction not in subsection_alias: |
||
| 72 | subsection_alias[subaction] = [] |
||
| 73 | else: |
||
| 74 | subsection_alias[subaction].append(name) |
||
| 75 | subsection_alias_names.add(name) |
||
| 76 | |||
| 77 | for name, subaction in action._name_parser_map.items(): |
||
| 78 | if name in subsection_alias_names: |
||
| 79 | continue |
||
| 80 | subalias = subsection_alias[subaction] |
||
| 81 | subaction.prog = f'{parser.prog} {name}' |
||
| 82 | subdata = { |
||
| 83 | 'name': name if not subalias else f"{name} ({', '.join(subalias)})", |
||
| 84 | 'help': helps.get(name, ''), |
||
| 85 | 'usage': subaction.format_usage().strip(), |
||
| 86 | 'bare_usage': _format_usage_without_prefix(subaction), |
||
| 87 | } |
||
| 88 | if subalias: |
||
| 89 | subdata['identifier'] = name |
||
| 90 | parse_parser(subaction, subdata, **kwargs) |
||
| 91 | data.setdefault('children', []).append(subdata) |
||
| 92 | |||
| 93 | show_defaults = True |
||
| 94 | if kwargs.get('skip_default_values', False) is True: |
||
| 95 | show_defaults = False |
||
| 96 | show_defaults_const = show_defaults |
||
| 97 | if kwargs.get('skip_default_const_values', False) is True: |
||
| 98 | show_defaults_const = False |
||
| 99 | |||
| 100 | # argparse stores the different groups as a list in parser._action_groups |
||
| 101 | # the first element of the list holds the positional arguments, the |
||
| 102 | # second the option arguments not in groups, and subsequent elements |
||
| 103 | # argument groups with positional and optional parameters |
||
| 104 | action_groups = [] |
||
| 105 | for action_group in parser._action_groups: |
||
| 106 | options_list = [] |
||
| 107 | for action in action_group._group_actions: |
||
| 108 | if isinstance(action, _HelpAction): |
||
| 109 | continue |
||
| 110 | |||
| 111 | # Quote default values for string/None types |
||
| 112 | default = action.default |
||
| 113 | if action.default not in ['', None, True, False] and action.type in [None, str] and isinstance(action.default, str): |
||
| 114 | default = f'"{default}"' |
||
| 115 | |||
| 116 | # fill in any formatters, like %(default)s |
||
| 117 | format_dict = dict(vars(action), prog=data.get('prog', ''), default=default) |
||
| 118 | format_dict['default'] = default |
||
| 119 | help_str = action.help or '' # Ensure we don't print None |
||
| 120 | try: |
||
| 121 | help_str = help_str % format_dict |
||
| 122 | except Exception: |
||
| 123 | pass |
||
| 124 | |||
| 125 | # Options have the option_strings set, positional arguments don't |
||
| 126 | name = action.option_strings |
||
| 127 | if name == []: |
||
| 128 | if action.metavar is None: |
||
| 129 | name = [action.dest] |
||
| 130 | else: |
||
| 131 | name = [action.metavar] |
||
| 132 | # Skip lines for subcommands |
||
| 133 | if name == ['==SUPPRESS==']: |
||
| 134 | continue |
||
| 135 | |||
| 136 | if isinstance(action, _StoreConstAction): |
||
| 137 | option = { |
||
| 138 | 'name': name, |
||
| 139 | 'default': default if show_defaults_const else '==SUPPRESS==', |
||
| 140 | 'help': help_str, |
||
| 141 | } |
||
| 142 | else: |
||
| 143 | option = { |
||
| 144 | 'name': name, |
||
| 145 | 'default': default if show_defaults else '==SUPPRESS==', |
||
| 146 | 'help': help_str, |
||
| 147 | } |
||
| 148 | if action.choices: |
||
| 149 | option['choices'] = action.choices |
||
| 150 | if "==SUPPRESS==" not in option['help']: |
||
| 151 | options_list.append(option) |
||
| 152 | |||
| 153 | if len(options_list) == 0: |
||
| 154 | continue |
||
| 155 | |||
| 156 | # Upper case "Positional Arguments" and "Optional Arguments" titles |
||
| 157 | # Since python-3.10 'optional arguments' changed to 'options' |
||
| 158 | # more info: https://github.com/python/cpython/pull/23858 |
||
| 159 | if action_group.title == 'optional arguments' or action_group.title == 'options': |
||
| 160 | action_group.title = 'Named Arguments' |
||
| 161 | if action_group.title == 'positional arguments': |
||
| 162 | action_group.title = 'Positional Arguments' |
||
| 163 | |||
| 164 | group = { |
||
| 165 | 'title': action_group.title, |
||
| 166 | 'description': action_group.description, |
||
| 167 | 'options': options_list, |
||
| 168 | } |
||
| 169 | |||
| 170 | action_groups.append(group) |
||
| 171 | |||
| 172 | if len(action_groups) > 0: |
||
| 173 | data['action_groups'] = action_groups |
||
| 174 | |||
| 175 | return data |
||
| 176 |